diff options
1516 files changed, 48559 insertions, 25715 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ebbbe345fd..e7e88e95d7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -139,10 +139,10 @@ doc_classes/* @godotengine/documentation # Platform /platform/android/ @godotengine/android -/platform/iphone/ @godotengine/ios +/platform/ios/ @godotengine/ios /platform/javascript/ @godotengine/html5 /platform/linuxbsd/ @godotengine/linux-bsd -/platform/osx/ @godotengine/macos +/platform/macos/ @godotengine/macos /platform/uwp/ @godotengine/uwp /platform/windows/ @godotengine/windows diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml index 40f091e234..03277edc1d 100644 --- a/.github/workflows/ios_builds.yml +++ b/.github/workflows/ios_builds.yml @@ -30,7 +30,7 @@ jobs: uses: ./.github/actions/godot-build with: sconsflags: ${{ env.SCONSFLAGS }} - platform: iphone + platform: ios target: release tools: false tests: false diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index b88c84e34e..aa862168b1 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -19,24 +19,39 @@ jobs: fail-fast: false matrix: include: - - name: Editor w/ Mono (target=release_debug, tools=yes, tests=yes) +# Temporarily disabled until Mono is fixed +# +# - name: Editor w Mono (target=release_debug, tools=yes, tests=yes) +# cache-name: linux-editor-mono +# target: release_debug +# tools: true +# tests: false # Disabled due freeze caused by mix Mono build and CI +# sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no +# doc-test: true +# bin: "./bin/godot.linuxbsd.opt.tools.64.mono" +# build-mono: true +# proj-conv: true +# artifact: true + +# Temporary replacement: + + - name: Editor w/o Mono (target=release_debug, tools=yes, tests=yes) cache-name: linux-editor-mono target: release_debug tools: true tests: false # Disabled due freeze caused by mix Mono build and CI - sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no doc-test: true - bin: "./bin/godot.linuxbsd.opt.tools.64.mono" - build-mono: true + bin: "./bin/godot.linuxbsd.opt.tools.64" + build-mono: false proj-conv: true artifact: true - - name: Editor with doubles and GCC sanitizers (target=debug, tools=yes, float=64, tests=yes, use_asan=yes, use_ubsan=yes) + - name: Editor with doubles and GCC sanitizers (target=debug, tools=yes, float=64, tests=yes, use_asan=yes, use_ubsan=yes, linker=gold) cache-name: linux-editor-double-sanitizers target: debug tools: true tests: true - sconsflags: float=64 use_asan=yes use_ubsan=yes + sconsflags: float=64 use_asan=yes use_ubsan=yes linker=gold proj-test: true # Can be turned off for PRs that intentionally break compat with godot-cpp, # until both the upstream PR and the matching godot-cpp changes are merged. @@ -46,23 +61,35 @@ jobs: # Skip 2GiB artifact speeding up action. artifact: false - - name: Editor with clang sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes) + - name: Editor with clang sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld) cache-name: linux-editor-llvm-sanitizers target: debug tools: true tests: true - sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes + sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes linker=lld bin: "./bin/godot.linuxbsd.tools.64.llvm.san" build-mono: false # Skip 2GiB artifact speeding up action. artifact: false - - name: Template w/ Mono (target=release, tools=no) +# Temporarily disabled: +# +# - name: Template w/ Mono (target=release, tools=no) +# cache-name: linux-template-mono +# target: release +# tools: false +# tests: false +# sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no +# build-mono: false +# artifact: true + +# Temporary replacement: + + - name: Template w/o Mono (target=release, tools=no) cache-name: linux-template-mono target: release tools: false tests: false - sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no build-mono: false artifact: true @@ -88,7 +115,7 @@ jobs: sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \ libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev \ libdbus-1-dev libudev-dev libxi-dev libxrandr-dev yasm xvfb wget unzip \ - llvm libspeechd-dev speech-dispatcher + llvm libspeechd-dev speech-dispatcher fontconfig libfontconfig-dev - name: Setup Godot build cache uses: ./.github/actions/godot-cache diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index 9b8ffc45a7..0cb037bfae 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -24,7 +24,7 @@ jobs: target: release_debug tools: true tests: true - bin: "./bin/godot.osx.opt.tools.64" + bin: "./bin/godot.macos.opt.tools.64" - name: Template (target=release, tools=no) cache-name: macos-template @@ -49,7 +49,7 @@ jobs: uses: ./.github/actions/godot-build with: sconsflags: ${{ env.SCONSFLAGS }} - platform: osx + platform: macos target: ${{ matrix.target }} tools: ${{ matrix.tools }} tests: ${{ matrix.tests }} diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index d7d07b7022..81c7042663 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -37,6 +37,10 @@ jobs: run: | bash ./misc/scripts/clang_format.sh + - name: Header guards formatting checks (header_guards.sh) + run: | + bash ./misc/scripts/header_guards.sh + - name: Python style checks via black (black_format.sh) run: | bash ./misc/scripts/black_format.sh @@ -40,6 +40,7 @@ FireForge <67974470+fire-forge@users.noreply.github.com> <isaacr.7.2005@gmail.co foxydevloper <12120644+foxydevloper@users.noreply.github.com> Fredia Huya-Kouadio <fhuyakou@gmail.com> Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@google.com> +Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@fb.com> Geequlim <geequlim@gmail.com> Gilles Roudiere <gilles.roudiere@gmail.com> Gilles Roudiere <gilles.roudiere@gmail.com> <gilles.roudiere@laas.fr> @@ -128,6 +129,7 @@ RaphaelHunter <raphael10241024@gmail.com> <raphael20141024@gmail.com> Rémi Verschelde <rverschelde@gmail.com> <remi@verschelde.fr> Rhody Lugo <rhodylugo@gmail.com> <rhodylugo@me.com> Ricardo Subtil <ricasubtil@gmail.com> +Rindbee <idleman@yeah.net> Robin Hübner <profan@prfn.se> <robinhubner@gmail.com> romulox_x <romulox_x@yahoo.com> Ruslan Mustakov <r.mustakov@gmail.com> <ruslan.mustakov@xored.com> @@ -139,6 +141,7 @@ Swarnim Arun <swarnimarun11@gmail.com> Theo Hallenius <redsymbzone@hotmail.com> Tomasz Chabora <kobewi4e@gmail.com> Twarit <wtwarit@gmail.com> +Vitika9 <vitika.program@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> diff --git a/AUTHORS.md b/AUTHORS.md index 36be7c4501..a409a1cea5 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -52,7 +52,6 @@ name is available. Bojidar Marinov (bojidar-bg) Brian Semrau (briansemrau) Bruno Lourenço (MadEqua) - bruvzg Cameron Reikes (creikey) Camille Mohr-Daurat (pouleyKetchoupp) Caner Demirer (cdemirer) @@ -64,8 +63,8 @@ name is available. Dana Olson (adolson) Daniel J. Ramirez (djrm) Daniel Rakos (aqnuep) - dankan1890 Danil Alexeev (dalexeev) + dankan1890 David Cambré (Gallilus) David Sichma (DavidSichma) David Snopek (dsnopek) @@ -85,7 +84,7 @@ name is available. Eveline Jarosz (Marqin) Fabian Mathews (supagu) Fabio Alessandrelli (Faless) - fabriceci + Fabrice Cipolla (fabriceci) Ferenc Arn (tagcup) FireForge (fire-forge) follower @@ -122,8 +121,8 @@ name is available. Jérôme Gully (Nutriz) Jia Jun Chai (SkyLucilfer) Joan Fons Sanchez (JFonS) - Johannes Witt (HaSa1002) Johan Manuel (29jm) + Johannes Witt (HaSa1002) Jordan Schidlowsky (winterpixelgames) Joshua Grams (JoshuaGrams) Juan Linietsky (reduz) @@ -187,6 +186,7 @@ name is available. Paul Batty (Paulb23) Paul Joannon (paulloz) Paul Trojahn (ptrojahn) + PÄvels NadtoÄajevs (bruvzg) PaweÅ‚ Fertyk (pfertyk) Pawel Kowal (pkowal1982) Pawel Lampe (Scony) @@ -232,6 +232,7 @@ name is available. Twarit Waikar (IronicallySerious) Umang Kalra (theoway) Vinzenz Feenstra (vinzenz) + Vitika Soni (Vitika9) 박한얼 (volzhs) V. Vamsi Krishna (vkbsb) Wilhem Barbier (nounoursheureux) @@ -246,3 +247,4 @@ name is available. Zak Stam (zaksnet) Zher Huei Lee (leezh) ZuBsPaCe + 风é’å±± (Rindbee) @@ -21,27 +21,33 @@ generous deed immortalized in the next stable release of Godot Engine. ## Silver sponsors + Affray Interactive <https://scp.games/pandemic> ASIFA-Hollywood <https://www.asifa-hollywood.org> - ORE System <https://ore-system.com> + Playful Studios <https://playfulstudios.com> + Robot Gentleman <http://robotgentleman.com> ## Bronze sponsors + Basically Games Brandon Lamb Bri Daniel Kaplan Garry Newman Gordon MacPherson Hunter Dickson + Isaiah smith + Kenney <https://kenney.nl> Kitcat490 Kyle Szklenski Maxim Karsten - Nik Rudenko Moonwards <https://www.moonwards.com> + Nik Rudenko TrampolineTales <https://trampolinetales.com> ## Mini sponsors AD Ford + Albin Lundahl Andres Hernandez Andrew Bowen Andrew Dunai @@ -75,8 +81,10 @@ generous deed immortalized in the next stable release of Godot Engine. Patrick Horn Patrick Schmidt Rami - Relintai + René Habermann Ronnie Cheng + Ryan Heath + Samantha ShikadiGum Slobodan Milnovic Stephan Lanfermann @@ -101,15 +109,14 @@ generous deed immortalized in the next stable release of Godot Engine. David Snopek Ed Morley First Last + Frank Kurka Hunter Jones Jacobus Dens - Jasper Brooks Javier Roman Joan Fons Jonathan Wright Jon Woodward Karl Werf - Kevin Vu Klavdij Voncina Maciej Pendolski Manuele Finocchiaro @@ -141,11 +148,12 @@ generous deed immortalized in the next stable release of Godot Engine. Adam Mill Adam Nakonieczny Adam Nelson + Adam Stankiewicz Adrian Adamiak Alexander Erlemann - Alexander J Maynard Alex Khayrullin alice gambrell + Alo Mis Andrew Cunningham Andrew Farr Andriy @@ -154,21 +162,19 @@ generous deed immortalized in the next stable release of Godot Engine. Arch Henderson III Arthur S. Muszynski BasicIncomePlz - BoomHorseHat + Brandon Hawkinson BrizzleBrip c64cosmin Cameron Connolly Charles Gray Charlie Whitfield - Chase Taranto Chris Petrich Chris Serino - Craig Ostrin + Collin Rapp Craig Scarborough Craig Smith Cristopher CzechBlueBear - D DagobertDick Daniel Hernández Alcojor Daniel Tebbutt @@ -176,12 +182,11 @@ generous deed immortalized in the next stable release of Godot Engine. David Thomason Daylon J Williams Dennis Belfrage - Dev To Be curious Dimitri Nüscheler Donn Eddy Eric Brand + Eric Churches Eugenio Hugo Salgüero Jáñez - EXUREI Felix Winterhalter flesk foxydevloper @@ -200,22 +205,19 @@ generous deed immortalized in the next stable release of Godot Engine. Horváth-Lázár Péter Hu Hund Hunter Barabas - HurrieCrane Jaap Marsman Jamal Bencharki James Couzens - Jan Sælid Jared Jared White Jean-Sébastien Ross Jennifer Wilcox - Jeremi Biernacki Jesús Chicharro Joel Fivat Johnathan Kupferer + John Duplechain John Stinson Josef Stumpfegger - Jose Malheiro Jose Manuel Muñoz Perez Joshie Sparks Joshua Flores @@ -225,6 +227,7 @@ generous deed immortalized in the next stable release of Godot Engine. Julian Todd Juraj Móza JUSTIN CARROLL + Justin Palmer Kelteseth Kevan Khora @@ -247,30 +250,27 @@ generous deed immortalized in the next stable release of Godot Engine. Martin Soucek matt Matt Greene + Matthew Dana Max Kryschi - medecau Michael Dürwald Michael Policastro - Miika Moilanen MikadoSC Mike Barbee nate etan - Nick Abousselam - Nicola Cocchiaro Nicolás Carrasco + Nikita Blizniuk Oliver Dick Oscar Campos Paul Hocker Paul Von Zimmerman - Pavel Kotlyar Pedro Pete Goodwin - Peter Richmond Petr Malac - PhaineOfCatz - RafaÅ‚ Michno + Petrus Prinsloo + Philip Woods + R + RaiRu RAMupgrade - Raymond Harris Reilt Rene Tailleur Rhodochrone @@ -278,39 +278,35 @@ generous deed immortalized in the next stable release of Godot Engine. Rob Robert McDermott Rob McInroy - Rocknight Studios RodZilla Romeo Disca Ronnie Ashlock Ronny Mühle Russ Ryan Breaker - Ryan Heath Ryan Miller Ryan Scott Samuel Hummerstone Samuel Judd - Sean Morgan - Sebastian Hutter + schroedinger's possum Serban Serafimescu Sergey Fonaryov - Sergey Minakov Shishir Tandale Sing Chun Lee + Skides SKison Song Junwoo spacechase0 Stephan Hennion Steven Landow Stoned Xander + Sven Carstensen Teslatech + Thomas Bjarnelöf Thomas Kurz - Tim Suess Tobias Bocanegra Tobias Raggl - Todd Smith Tom Glenn - Tom Wor Torbulous toto bibi Troy Kinsella @@ -326,7 +322,6 @@ generous deed immortalized in the next stable release of Godot Engine. ## Silver donors - 1D_Inc Aaron Oldenburg A. B. Adam Brunnmeier @@ -350,7 +345,6 @@ generous deed immortalized in the next stable release of Godot Engine. Alder Stefano Alejandro Saucedo AleMax - Ales Jelovcan Alessandro Senese Alex Chan Alex Clavelle @@ -359,6 +353,7 @@ generous deed immortalized in the next stable release of Godot Engine. Allen Schade Amar Å ahinović Andre Altmueller + Andrei Pufu Andre Stackhouse Andrew Groot andrew james morris @@ -367,7 +362,6 @@ generous deed immortalized in the next stable release of Godot Engine. Ano Nim Anthony Avina Anton Bouwer - Antti Vesanen Arch Toasty Arda Erol Arthur Brainville @@ -380,7 +374,6 @@ generous deed immortalized in the next stable release of Godot Engine. Austin Miller Azar Gurbanov AzulCrescent - b110110 Balázs Batári Beau Seymour Behzad Ghaffari @@ -394,8 +387,9 @@ generous deed immortalized in the next stable release of Godot Engine. Bjarne Voigtländer Black Block Blunderjack - Brad Harms + BoiLudens Bram + Brian Brian Ford Bronson Zgeb Burney Waring @@ -406,19 +400,19 @@ generous deed immortalized in the next stable release of Godot Engine. Carlos Rios Carl van der Geest Casey - Cassidy James Chad Steadman Checkpoint Charlie Chris Jagusch Chris Langford Chris Ridenour + Christian Kaltenecker Christian Mauduit + Christian Scholz Christian Winter Christoffer Dahlblom Christophe Gagnier - Christopher Chin Christoph Woinke - ClicheChloe + Codex404 Cody Parker Conall O Conner Lane @@ -427,8 +421,11 @@ generous deed immortalized in the next stable release of Godot Engine. Craig Post CT Cullen Canejo + cynwav Dakota Watkins + Daniel H. Bahr Danielle Cheney + Dare Looks Daren Scot Wilson Dave Walker David Baker @@ -437,6 +434,7 @@ generous deed immortalized in the next stable release of Godot Engine. David Maziarka David Rapisarda Devin Carraway + Devin R Dimitri Roche Dmytro Korchynskyi Dominik Wetzel @@ -447,15 +445,14 @@ generous deed immortalized in the next stable release of Godot Engine. Ducky Duobix Duodecimal - Eduardo Teixeira Edward Herbert Edward Swartz Egon Elbre - eiki kanou Elgenzay Elias Nykrem Elijah Anderson Emerson MX + Ends Ephemeral Eric Stokes Eric Walkingshaw @@ -480,35 +477,29 @@ generous deed immortalized in the next stable release of Godot Engine. George Marques Gon Shibayama Green Fox - Greg Lincoln - Greg Olson Greyson Richey Grid Grominet Guillaume Pham Ngoc Guldoman Guo Hongci - gurehamu Haplo Hayden Foley Heribert Hirth + Hylian Ensemble Ian Richard Kunert Ian Williams IndustrialRobot Inki Crow iveks - izzy kestrel - Jackson Harmer Jacob D Jaguar Jake D - Jake Huxell Jako Danar James James A F Manley + James Allen James Gary - James Guardino - James Quincy James Thomas Jamie Massey Janis Skuja @@ -521,12 +512,14 @@ generous deed immortalized in the next stable release of Godot Engine. Jeff Hungerford Jeffrey Berube Jennifer Graves + Jeramie Jesse Dubay - Jim Engstrand + João Pedro Braz Joe Hurdle Joe Klemmer John Anders Stav John Bruce + Johnny Deepman Jonas Jonas Arndt Jonas Bernemann @@ -537,12 +530,13 @@ generous deed immortalized in the next stable release of Godot Engine. Jonathan Ellis Jonathan G Jonathan Turner + Jon Oakes Jon Sully Jordan West Jordy Goodridge Jorge Antunes - Jorge Araya Navarro Jose Francisco 'Yiro' Vera Girona + José Gabriel González Joseph Catrambone Josh P Josh Taylor @@ -557,6 +551,7 @@ generous deed immortalized in the next stable release of Godot Engine. Justin Hamilton Justin Spedding KaDokta + Kalydi Balázs Karol Wojtasiuk (Drakonter) Katsuomi Kobayashi Keedong Park @@ -577,17 +572,17 @@ generous deed immortalized in the next stable release of Godot Engine. kycho Kyle Burnett Kyle Jacobs - La diagonale du poulpe Lasse le Dous Laurent CHEA Laurent Dethoor Laxman Pradhan + Lech Rozanski Leland Vakarian Lemin LEMMiNO Leonardo Baumle - Leonardo Dimano Levi Lindsey + LF Linus Lind Lundgren Logan Apple Ludovic DELVAL @@ -601,7 +596,7 @@ generous deed immortalized in the next stable release of Godot Engine. Marcos Heitor Carvalho Markie Music Mark Jad - Mark Malone + Mark Tyler Markus Martin Markus Michael Egger Markus Strompen @@ -617,9 +612,9 @@ generous deed immortalized in the next stable release of Godot Engine. Maxime Santerre Maxwell McStuffings - meinkush Melissa Mears Merlyn Morgan-Graham + Mert Kasar Metal Demon 2000 mhilbrunner Michael @@ -643,7 +638,6 @@ generous deed immortalized in the next stable release of Godot Engine. moulefrite MrAZIE Mrjemandem - Nathan Fish Nathaniel neighty Neil Blakey-Milner @@ -654,7 +648,7 @@ generous deed immortalized in the next stable release of Godot Engine. Nicholas Orlowski Nick Eldrenkamp Nick Macholl - Niclas Eriksen + Nico Greve Nicolas Goll-Perrier Nicolas Rosset Nicolò Brigadoi Calamari @@ -662,6 +656,7 @@ generous deed immortalized in the next stable release of Godot Engine. Nima Farid Noel Billig Noesis + obscuresteel Okatima Oleg Reva Oliver Ambrose @@ -678,7 +673,6 @@ generous deed immortalized in the next stable release of Godot Engine. PaweÅ‚ Åyczkowski Peter Höglund Philip Ludington (MrPhil) - Philip Woods Pierre Caye Pixel Archipel pj @@ -689,20 +683,17 @@ generous deed immortalized in the next stable release of Godot Engine. pwab RackBar Dingum Rafa Laguna - Raffaele Aramo Ragnar Pettersson Rainer Amler Rammeow - Recep Karademir red1939 + Relintai Remi Rampin Remtaine Reneator - René Habermann Riccardo Marini Richard Hayes Richard Ivánek - Richard Néveri Riley Robin Ward RobotCritter @@ -710,26 +701,25 @@ generous deed immortalized in the next stable release of Godot Engine. Rodrigo Loli Roger Smith Roglozor + Roka Roland RzÄ…sa Roman Papush Ronald Ho Hip (CrimsonZA) - Ronan Roy Scayged + Russ Ryan Groom + Ryan Mueller Rykk - Sam Edson Sammy Fischer Sangeeth Pavithran - schroedinger's possum - Scott Longley Sean Dee Sebastian Michailidis SeongWan Kim Sessamekesh + Seth Drebitko SeungJong k Shaidak Shane - Shane Sicienski Shane Spoor Silver1063 simdee @@ -746,11 +736,12 @@ generous deed immortalized in the next stable release of Godot Engine. Soheib El-Harrache Solene Waked Sophie Winter + Space Hedgehog + Sparky Squidgy Squirrel Stéphane Roussel Stephen Rice - Steve Cloete Steven Drovie summerblind Sung soo Choi @@ -758,10 +749,12 @@ generous deed immortalized in the next stable release of Godot Engine. SxP tadashi endo Tarch + Techwizz Terry The Domis4 Theodore Lindsey TheVoiceInMyHead + TheWint Thibaut DECROMBECQUE thomas Thomas Bechtold @@ -774,8 +767,7 @@ generous deed immortalized in the next stable release of Godot Engine. Tim Gleason Tim Klein Timothy B. MacDonald - Title Plinsut - TMoney + Tim Riley Toadile Tobias Bradtke Tom Coxon @@ -802,18 +794,20 @@ generous deed immortalized in the next stable release of Godot Engine. Vitaliy Sapronenko Vi Watch Vladimir Savin + Vuli Nux Wapiti . - Watchinofoye Wiley Thompson William Bodin William Edwards William F Siqueira + Windvis Woonki Moon Wyatt Goodin - yakcyll + Xananax Yan Shi - Yegor Smirnov + yust Zach H. + Zekim Zher Huei Lee è•æƒŸå… è²´å® å°æ¾ diff --git a/SConstruct b/SConstruct index 0eba93e4ff..0fd9326e1c 100644 --- a/SConstruct +++ b/SConstruct @@ -195,7 +195,7 @@ opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False)) opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False)) opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False)) -opts.Add("disable_classes", "Disable given classes (comma separated)", "") +opts.Add("build_feature_profile", "Path to a file containing a feature build profile", "") opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True)) opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True)) opts.Add("system_certs_path", "Use this path as SSL certificates default for editor (for package maintainers)", "") @@ -260,7 +260,7 @@ else: ): selected_platform = "linuxbsd" elif sys.platform == "darwin": - selected_platform = "osx" + selected_platform = "macos" elif sys.platform == "win32": selected_platform = "windows" else: @@ -272,6 +272,20 @@ else: if selected_platform != "": print("Automatically detected platform: " + selected_platform) +if selected_platform in ["macos", "osx"]: + if selected_platform == "osx": + # Deprecated alias kept for compatibility. + print('Platform "osx" has been renamed to "macos" in Godot 4.0. Building for platform "macos".') + # Alias for convenience. + selected_platform = "macos" + +if selected_platform in ["ios", "iphone"]: + if selected_platform == "iphone": + # Deprecated alias kept for compatibility. + print('Platform "iphone" has been renamed to "ios" in Godot 4.0. Building for platform "ios".') + # Alias for convenience. + selected_platform = "ios" + if selected_platform in ["linux", "bsd", "x11"]: if selected_platform == "x11": # Deprecated alias kept for compatibility. @@ -554,7 +568,7 @@ if selected_platform in platform_list: ) # Apple LLVM versions differ from upstream LLVM version \o/, compare # in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions - elif env["platform"] == "osx" or env["platform"] == "iphone": + elif env["platform"] == "macos" or env["platform"] == "ios": vanilla = methods.is_vanilla_clang(env) if vanilla and cc_version_major < 6: print( @@ -738,7 +752,27 @@ if selected_platform in platform_list: if env["tools"]: env.Append(CPPDEFINES=["TOOLS_ENABLED"]) - methods.write_disabled_classes(env["disable_classes"].split(",")) + + disabled_classes = [] + + if env["build_feature_profile"] != "": + print("Using build feature profile: " + env["build_feature_profile"]) + import json + + try: + ft = json.load(open(env["build_feature_profile"])) + if "disabled_classes" in ft: + disabled_classes = ft["disabled_classes"] + if "disabled_build_options" in ft: + dbo = ft["disabled_build_options"] + for c in dbo: + env[c] = dbo[c] + except: + print("Error opening feature build profile: " + env["build_feature_profile"]) + Exit(255) + + methods.write_disabled_classes(disabled_classes) + if env["disable_3d"]: if env["tools"]: print( @@ -820,6 +854,9 @@ if selected_platform in platform_list: # Microsoft Visual Studio Project Generation if env["vsproj"]: + if os.name != "nt": + print("Error: The `vsproj` option is only usable on Windows with Visual Studio.") + Exit(255) env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]] methods.generate_vs_project(env, GetOption("num_jobs")) methods.generate_cpp_hint_file("cpp.hint") diff --git a/core/SCsub b/core/SCsub index df3e7a547a..d4462fa546 100644 --- a/core/SCsub +++ b/core/SCsub @@ -129,7 +129,7 @@ if env["builtin_zstd"]: "decompress/zstd_decompress_block.c", "decompress/zstd_decompress.c", ] - if env["platform"] in ["android", "iphone", "linuxbsd", "osx"]: + if env["platform"] in ["android", "ios", "linuxbsd", "macos"]: # Match platforms with ZSTD_ASM_SUPPORTED in common/portability_macros.h thirdparty_zstd_sources.append("decompress/huf_decompress_amd64.S") thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources] @@ -188,7 +188,6 @@ SConscript("os/SCsub") SConscript("math/SCsub") SConscript("crypto/SCsub") SConscript("io/SCsub") -SConscript("multiplayer/SCsub") SConscript("debugger/SCsub") SConscript("input/SCsub") SConscript("variant/SCsub") diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 782d369ae6..44ad4961d9 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -246,6 +246,14 @@ void Engine::get_singletons(List<Singleton> *p_singletons) { } } +String Engine::get_write_movie_path() const { + return write_movie_path; +} + +void Engine::set_write_movie_path(const String &p_path) { + write_movie_path = p_path; +} + void Engine::set_shader_cache_path(const String &p_path) { shader_cache_path = p_path; } diff --git a/core/config/engine.h b/core/config/engine.h index 82e3ee5487..68562643e7 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -76,6 +76,7 @@ private: static Engine *singleton; + String write_movie_path; String shader_cache_path; public: @@ -138,6 +139,9 @@ public: Dictionary get_license_info() const; String get_license_text() const; + void set_write_movie_path(const String &p_path); + String get_write_movie_path() const; + void set_shader_cache_path(const String &p_path); String get_shader_cache_path() const; diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 7145e628c1..38db7f9190 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -488,7 +488,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b // We need to test both possibilities as extensions for Linux binaries are optional // (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck'). -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED if (!found) { // Attempt to load PCK from macOS .app bundle resources. found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_basename + ".pck")) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_filename + ".pck")); @@ -511,8 +511,9 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b if (found) { Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); if (err == OK && !p_ignore_override) { - // Load override from location of the executable. - // Optional, we don't mind if it fails. + // Load overrides from the PCK and the executable location. + // Optional, we don't mind if either fails. + _load_settings_text("res://override.cfg"); _load_settings_text(exec_path.get_base_dir().plus_file("override.cfg")); } return err; diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 26ecd41353..e5d5464643 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -231,6 +231,14 @@ void OS::crash(const String &p_message) { CRASH_NOW_MSG(p_message); } +Vector<String> OS::get_system_fonts() const { + return ::OS::get_singleton()->get_system_fonts(); +} + +String OS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { + return ::OS::get_singleton()->get_system_font_path(p_font_name, p_bold, p_italic); +} + String OS::get_executable_path() const { return ::OS::get_singleton()->get_executable_path(); } @@ -589,6 +597,8 @@ void OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_processor_count"), &OS::get_processor_count); ClassDB::bind_method(D_METHOD("get_processor_name"), &OS::get_processor_name); + ClassDB::bind_method(D_METHOD("get_system_fonts"), &OS::get_system_fonts); + ClassDB::bind_method(D_METHOD("get_system_font_path", "font_name", "bold", "italic"), &OS::get_system_font_path, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path); ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr", "open_console"), &OS::execute, DEFVAL(Array()), DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("create_process", "path", "arguments", "open_console"), &OS::create_process, DEFVAL(false)); @@ -1220,16 +1230,10 @@ Vector<uint8_t> File::get_buffer(int64_t p_length) const { String File::get_as_text() const { ERR_FAIL_COND_V_MSG(f.is_null(), String(), "File must be opened before use, or is lacking read-write permission."); - String text; uint64_t original_pos = f->get_position(); const_cast<FileAccess *>(*f)->seek(0); - String l = get_line(); - while (!eof_reached()) { - text += l + "\n"; - l = get_line(); - } - text += l; + String text = f->get_as_utf8_string(); const_cast<FileAccess *>(*f)->seek(original_pos); @@ -2286,6 +2290,10 @@ bool Engine::is_editor_hint() const { return ::Engine::get_singleton()->is_editor_hint(); } +String Engine::get_write_movie_path() const { + return ::Engine::get_singleton()->get_write_movie_path(); +} + void Engine::set_print_error_messages(bool p_enabled) { ::Engine::get_singleton()->set_print_error_messages(p_enabled); } @@ -2335,6 +2343,8 @@ void Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("is_editor_hint"), &Engine::is_editor_hint); + ClassDB::bind_method(D_METHOD("get_write_movie_path"), &Engine::get_write_movie_path); + ClassDB::bind_method(D_METHOD("set_print_error_messages", "enabled"), &Engine::set_print_error_messages); ClassDB::bind_method(D_METHOD("is_printing_error_messages"), &Engine::is_printing_error_messages); diff --git a/core/core_bind.h b/core/core_bind.h index c116ac4986..f98de81354 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -170,6 +170,8 @@ public: void alert(const String &p_alert, const String &p_title = "ALERT!"); void crash(const String &p_message); + Vector<String> get_system_fonts() const; + String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const; String get_executable_path() const; int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false, bool p_open_console = false); int create_process(const String &p_path, const Vector<String> &p_arguments, bool p_open_console = false); @@ -674,6 +676,9 @@ public: void set_editor_hint(bool p_enabled); bool is_editor_hint() const; + // `set_write_movie_path()` is not exposed to the scripting API as changing it at run-time has no effect. + String get_write_movie_path() const; + void set_print_error_messages(bool p_enabled); bool is_printing_error_messages() const; diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 1753efad60..dc0ab72a86 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -31,7 +31,6 @@ #include "core_constants.h" #include "core/input/input_event.h" -#include "core/multiplayer/multiplayer.h" #include "core/object/class_db.h" #include "core/os/keyboard.h" #include "core/variant/variant.h" @@ -660,15 +659,6 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_OBJECT_CORE); BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT); - // rpc - BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_DISABLED", Multiplayer::RPC_MODE_DISABLED); - BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_ANY_PEER", Multiplayer::RPC_MODE_ANY_PEER); - BIND_CORE_ENUM_CONSTANT_CUSTOM("RPC_MODE_AUTHORITY", Multiplayer::RPC_MODE_AUTHORITY); - - BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE", Multiplayer::TRANSFER_MODE_UNRELIABLE); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_UNRELIABLE_ORDERED", Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TRANSFER_MODE_RELIABLE", Multiplayer::TRANSFER_MODE_RELIABLE); - BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT", Variant::INT); @@ -681,11 +671,14 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3", Variant::VECTOR3); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3I", Variant::VECTOR3I); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR4", Variant::VECTOR4); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR4I", Variant::VECTOR4I); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_QUATERNION", Variant::QUATERNION); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM3D", Variant::TRANSFORM3D); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PROJECTION", Variant::PROJECTION); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING_NAME", Variant::STRING_NAME); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH); diff --git a/core/core_constants.h b/core/core_constants.h index d5b3b156b2..5e05b7a931 100644 --- a/core/core_constants.h +++ b/core/core_constants.h @@ -42,4 +42,4 @@ public: static int64_t get_global_constant_value(int p_idx); }; -#endif // GLOBAL_CONSTANTS_H +#endif // CORE_CONSTANTS_H diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h index eacef268cc..008e9e92b5 100644 --- a/core/crypto/crypto_core.h +++ b/core/crypto/crypto_core.h @@ -115,4 +115,5 @@ public: static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]); static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]); }; + #endif // CRYPTO_CORE_H diff --git a/core/debugger/debugger_marshalls.h b/core/debugger/debugger_marshalls.h index 378c3af8aa..751e8a6371 100644 --- a/core/debugger/debugger_marshalls.h +++ b/core/debugger/debugger_marshalls.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef DEBUGGER_MARSHARLLS_H -#define DEBUGGER_MARSHARLLS_H +#ifndef DEBUGGER_MARSHALLS_H +#define DEBUGGER_MARSHALLS_H #include "core/object/script_language.h" @@ -69,4 +69,4 @@ struct DebuggerMarshalls { }; }; -#endif // DEBUGGER_MARSHARLLS_H +#endif // DEBUGGER_MARSHALLS_H diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp index 263c75760b..d495a8ee20 100644 --- a/core/debugger/engine_debugger.cpp +++ b/core/debugger/engine_debugger.cpp @@ -43,6 +43,8 @@ HashMap<StringName, EngineDebugger::Profiler> EngineDebugger::profilers; HashMap<StringName, EngineDebugger::Capture> EngineDebugger::captures; HashMap<String, EngineDebugger::CreatePeerFunc> EngineDebugger::protocols; +void (*EngineDebugger::allow_focus_steal_fn)(); + void EngineDebugger::register_profiler(const StringName &p_name, const Profiler &p_func) { ERR_FAIL_COND_MSG(profilers.has(p_name), "Profiler already registered: " + p_name); profilers.insert(p_name, p_func); @@ -133,7 +135,7 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks, singleton->poll_events(true); } -void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints) { +void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints, void (*p_allow_focus_steal_fn)()) { register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more. if (p_uri.is_empty()) { return; @@ -174,6 +176,8 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp)); } + + allow_focus_steal_fn = p_allow_focus_steal_fn; } void EngineDebugger::deinitialize() { diff --git a/core/debugger/engine_debugger.h b/core/debugger/engine_debugger.h index a8a791f9b0..236d5e5f63 100644 --- a/core/debugger/engine_debugger.h +++ b/core/debugger/engine_debugger.h @@ -100,13 +100,15 @@ protected: static HashMap<StringName, Capture> captures; static HashMap<String, CreatePeerFunc> protocols; + static void (*allow_focus_steal_fn)(); + public: _FORCE_INLINE_ static EngineDebugger *get_singleton() { return singleton; } _FORCE_INLINE_ static bool is_active() { return singleton != nullptr && script_debugger != nullptr; } _FORCE_INLINE_ static ScriptDebugger *get_script_debugger() { return script_debugger; }; - static void initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints); + static void initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints, void (*p_allow_focus_steal_fn)()); static void deinitialize(); static void register_profiler(const StringName &p_name, const Profiler &p_profiler); static void unregister_profiler(const StringName &p_name); diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index c73e2eb3fb..23ee977df4 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -452,6 +452,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { msg.push_back(error_str); ERR_FAIL_COND(!script_lang); msg.push_back(script_lang->debug_get_stack_level_count() > 0); + if (allow_focus_steal_fn) { + allow_focus_steal_fn(); + } send_message("debug_enter", msg); Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode(); diff --git a/core/doc_data.cpp b/core/doc_data.cpp index 89e7a8dc71..df86cd1dc2 100644 --- a/core/doc_data.cpp +++ b/core/doc_data.cpp @@ -115,6 +115,31 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met p_method.name = p_methodinfo.name; p_method.description = p_desc; + if (p_methodinfo.flags & METHOD_FLAG_VIRTUAL) { + p_method.qualifiers = "virtual"; + } + + if (p_methodinfo.flags & METHOD_FLAG_CONST) { + if (!p_method.qualifiers.is_empty()) { + p_method.qualifiers += " "; + } + p_method.qualifiers += "const"; + } + + if (p_methodinfo.flags & METHOD_FLAG_VARARG) { + if (!p_method.qualifiers.is_empty()) { + p_method.qualifiers += " "; + } + p_method.qualifiers += "vararg"; + } + + if (p_methodinfo.flags & METHOD_FLAG_STATIC) { + if (!p_method.qualifiers.is_empty()) { + p_method.qualifiers += " "; + } + p_method.qualifiers += "static"; + } + return_doc_from_retinfo(p_method, p_methodinfo.return_val); for (int i = 0; i < p_methodinfo.arguments.size(); i++) { @@ -123,7 +148,7 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met int default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); if (default_arg_index >= 0) { Variant default_arg = p_methodinfo.default_arguments[default_arg_index]; - argument.default_value = default_arg.get_construct_string(); + argument.default_value = default_arg.get_construct_string().replace("\n", ""); } p_method.arguments.push_back(argument); } diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index ecdb1e26dc..867b1fc637 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -131,11 +131,14 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Variant::VECTOR3, vec3_elems * sizeof(float), vec3_elems * sizeof(float), vec3_elems * sizeof(double), vec3_elems * sizeof(double) }, { Variant::VECTOR3I, 3 * sizeof(int32_t), 3 * sizeof(int32_t), 3 * sizeof(int32_t), 3 * sizeof(int32_t) }, { Variant::TRANSFORM2D, 6 * sizeof(float), 6 * sizeof(float), 6 * sizeof(double), 6 * sizeof(double) }, + { Variant::VECTOR4, 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(double), 4 * sizeof(double) }, + { Variant::VECTOR4I, 4 * sizeof(int32_t), 4 * sizeof(int32_t), 4 * sizeof(int32_t), 4 * sizeof(int32_t) }, { Variant::PLANE, (vec3_elems + 1) * sizeof(float), (vec3_elems + 1) * sizeof(float), (vec3_elems + 1) * sizeof(double), (vec3_elems + 1) * sizeof(double) }, { Variant::QUATERNION, 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(double), 4 * sizeof(double) }, { Variant::AABB, (vec3_elems * 2) * sizeof(float), (vec3_elems * 2) * sizeof(float), (vec3_elems * 2) * sizeof(double), (vec3_elems * 2) * sizeof(double) }, { Variant::BASIS, (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(double), (vec3_elems * 3) * sizeof(double) }, { Variant::TRANSFORM3D, (vec3_elems * 4) * sizeof(float), (vec3_elems * 4) * sizeof(float), (vec3_elems * 4) * sizeof(double), (vec3_elems * 4) * sizeof(double) }, + { Variant::PROJECTION, 4 * 4 * sizeof(float), 4 * 4 * sizeof(float), 4 * 4 * sizeof(double), 4 * 4 * sizeof(double) }, { Variant::COLOR, 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(float) }, { Variant::STRING_NAME, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, { Variant::NODE_PATH, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, @@ -169,11 +172,14 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { static_assert(type_size_array[Variant::VECTOR3][sizeof(void *)] == sizeof(Vector3), "Size of Vector3 mismatch"); static_assert(type_size_array[Variant::VECTOR3I][sizeof(void *)] == sizeof(Vector3i), "Size of Vector3i mismatch"); static_assert(type_size_array[Variant::TRANSFORM2D][sizeof(void *)] == sizeof(Transform2D), "Size of Transform2D mismatch"); + static_assert(type_size_array[Variant::VECTOR4][sizeof(void *)] == sizeof(Vector4), "Size of Vector4 mismatch"); + static_assert(type_size_array[Variant::VECTOR4I][sizeof(void *)] == sizeof(Vector4i), "Size of Vector4i mismatch"); static_assert(type_size_array[Variant::PLANE][sizeof(void *)] == sizeof(Plane), "Size of Plane mismatch"); static_assert(type_size_array[Variant::QUATERNION][sizeof(void *)] == sizeof(Quaternion), "Size of Quaternion mismatch"); static_assert(type_size_array[Variant::AABB][sizeof(void *)] == sizeof(AABB), "Size of AABB mismatch"); static_assert(type_size_array[Variant::BASIS][sizeof(void *)] == sizeof(Basis), "Size of Basis mismatch"); static_assert(type_size_array[Variant::TRANSFORM3D][sizeof(void *)] == sizeof(Transform3D), "Size of Transform3D mismatch"); + static_assert(type_size_array[Variant::PROJECTION][sizeof(void *)] == sizeof(Projection), "Size of Projection mismatch"); static_assert(type_size_array[Variant::COLOR][sizeof(void *)] == sizeof(Color), "Size of Color mismatch"); static_assert(type_size_array[Variant::STRING_NAME][sizeof(void *)] == sizeof(StringName), "Size of StringName mismatch"); static_assert(type_size_array[Variant::NODE_PATH][sizeof(void *)] == sizeof(NodePath), "Size of NodePath mismatch"); @@ -256,6 +262,14 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Variant::TRANSFORM2D, "x", 0, 0, 0, 0 }, { Variant::TRANSFORM2D, "y", 2 * sizeof(float), 2 * sizeof(float), 2 * sizeof(double), 2 * sizeof(double) }, { Variant::TRANSFORM2D, "origin", 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(double), 4 * sizeof(double) }, + { Variant::VECTOR4, "x", 0, 0, 0, 0 }, + { Variant::VECTOR4, "y", sizeof(float), sizeof(float), sizeof(double), sizeof(double) }, + { Variant::VECTOR4, "z", 2 * sizeof(float), 2 * sizeof(float), 2 * sizeof(double), 2 * sizeof(double) }, + { Variant::VECTOR4, "w", 3 * sizeof(float), 3 * sizeof(float), 3 * sizeof(double), 3 * sizeof(double) }, + { Variant::VECTOR4I, "x", 0, 0, 0, 0 }, + { Variant::VECTOR4I, "y", sizeof(int32_t), sizeof(int32_t), sizeof(int32_t), sizeof(int32_t) }, + { Variant::VECTOR4I, "z", 2 * sizeof(int32_t), 2 * sizeof(int32_t), 2 * sizeof(int32_t), 2 * sizeof(int32_t) }, + { Variant::VECTOR4I, "w", 3 * sizeof(int32_t), 3 * sizeof(int32_t), 3 * sizeof(int32_t), 3 * sizeof(int32_t) }, { Variant::PLANE, "normal", 0, 0, 0, 0 }, { Variant::PLANE, "d", vec3_elems * sizeof(float), vec3_elems * sizeof(float), vec3_elems * sizeof(double), vec3_elems * sizeof(double) }, { Variant::QUATERNION, "x", 0, 0, 0, 0 }, diff --git a/core/extension/extension_api_dump.h b/core/extension/extension_api_dump.h index 7346e182f1..1bc455ea67 100644 --- a/core/extension/extension_api_dump.h +++ b/core/extension/extension_api_dump.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef API_DUMP_H -#define API_DUMP_H +#ifndef EXTENSION_API_DUMP_H +#define EXTENSION_API_DUMP_H #include "core/extension/native_extension.h" @@ -42,4 +42,4 @@ public: }; #endif -#endif // API_DUMP_H +#endif // EXTENSION_API_DUMP_H diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index 58103e3af3..ef0b590030 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -344,6 +344,10 @@ static GDNativeVariantFromTypeConstructorFunc gdnative_get_variant_from_type_con return VariantTypeConstructor<Vector3i>::variant_from_type; case GDNATIVE_VARIANT_TYPE_TRANSFORM2D: return VariantTypeConstructor<Transform2D>::variant_from_type; + case GDNATIVE_VARIANT_TYPE_VECTOR4: + return VariantTypeConstructor<Vector4>::variant_from_type; + case GDNATIVE_VARIANT_TYPE_VECTOR4I: + return VariantTypeConstructor<Vector4i>::variant_from_type; case GDNATIVE_VARIANT_TYPE_PLANE: return VariantTypeConstructor<Plane>::variant_from_type; case GDNATIVE_VARIANT_TYPE_QUATERNION: @@ -354,6 +358,8 @@ static GDNativeVariantFromTypeConstructorFunc gdnative_get_variant_from_type_con return VariantTypeConstructor<Basis>::variant_from_type; case GDNATIVE_VARIANT_TYPE_TRANSFORM3D: return VariantTypeConstructor<Transform3D>::variant_from_type; + case GDNATIVE_VARIANT_TYPE_PROJECTION: + return VariantTypeConstructor<Projection>::variant_from_type; case GDNATIVE_VARIANT_TYPE_COLOR: return VariantTypeConstructor<Color>::variant_from_type; case GDNATIVE_VARIANT_TYPE_STRING_NAME: @@ -421,6 +427,10 @@ static GDNativeTypeFromVariantConstructorFunc gdnative_get_type_from_variant_con return VariantTypeConstructor<Vector3i>::type_from_variant; case GDNATIVE_VARIANT_TYPE_TRANSFORM2D: return VariantTypeConstructor<Transform2D>::type_from_variant; + case GDNATIVE_VARIANT_TYPE_VECTOR4: + return VariantTypeConstructor<Vector4>::type_from_variant; + case GDNATIVE_VARIANT_TYPE_VECTOR4I: + return VariantTypeConstructor<Vector4i>::type_from_variant; case GDNATIVE_VARIANT_TYPE_PLANE: return VariantTypeConstructor<Plane>::type_from_variant; case GDNATIVE_VARIANT_TYPE_QUATERNION: @@ -431,6 +441,8 @@ static GDNativeTypeFromVariantConstructorFunc gdnative_get_type_from_variant_con return VariantTypeConstructor<Basis>::type_from_variant; case GDNATIVE_VARIANT_TYPE_TRANSFORM3D: return VariantTypeConstructor<Transform3D>::type_from_variant; + case GDNATIVE_VARIANT_TYPE_PROJECTION: + return VariantTypeConstructor<Projection>::type_from_variant; case GDNATIVE_VARIANT_TYPE_COLOR: return VariantTypeConstructor<Color>::type_from_variant; case GDNATIVE_VARIANT_TYPE_STRING_NAME: diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index f106b805e7..041a6e5112 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -67,11 +67,14 @@ typedef enum { GDNATIVE_VARIANT_TYPE_VECTOR3, GDNATIVE_VARIANT_TYPE_VECTOR3I, GDNATIVE_VARIANT_TYPE_TRANSFORM2D, + GDNATIVE_VARIANT_TYPE_VECTOR4, + GDNATIVE_VARIANT_TYPE_VECTOR4I, GDNATIVE_VARIANT_TYPE_PLANE, GDNATIVE_VARIANT_TYPE_QUATERNION, GDNATIVE_VARIANT_TYPE_AABB, GDNATIVE_VARIANT_TYPE_BASIS, GDNATIVE_VARIANT_TYPE_TRANSFORM3D, + GDNATIVE_VARIANT_TYPE_PROJECTION, /* misc types */ GDNATIVE_VARIANT_TYPE_COLOR, @@ -579,4 +582,4 @@ typedef GDNativeBool (*GDNativeInitializationFunction)(const GDNativeInterface * } #endif -#endif +#endif // GDNATIVE_INTERFACE_H diff --git a/core/extension/native_extension.h b/core/extension/native_extension.h index ca50f78621..b7238d2899 100644 --- a/core/extension/native_extension.h +++ b/core/extension/native_extension.h @@ -97,4 +97,4 @@ public: virtual String get_resource_type(const String &p_path) const; }; -#endif // NATIVEEXTENSION_H +#endif // NATIVE_EXTENSION_H diff --git a/core/extension/native_extension_manager.h b/core/extension/native_extension_manager.h index 5594f6c0de..ed80cd6b7a 100644 --- a/core/extension/native_extension_manager.h +++ b/core/extension/native_extension_manager.h @@ -71,4 +71,4 @@ public: VARIANT_ENUM_CAST(NativeExtensionManager::LoadStatus) -#endif // NATIVEEXTENSIONMANAGER_H +#endif // NATIVE_EXTENSION_MANAGER_H diff --git a/core/input/input_builders.py b/core/input/input_builders.py index 748ec06133..c0dac26f02 100644 --- a/core/input/input_builders.py +++ b/core/input/input_builders.py @@ -47,9 +47,9 @@ def make_default_controller_mappings(target, source, env): platform_variables = { "Linux": "#if X11_ENABLED", "Windows": "#ifdef WINDOWS_ENABLED", - "Mac OS X": "#ifdef OSX_ENABLED", + "Mac OS X": "#ifdef MACOS_ENABLED", "Android": "#if defined(__ANDROID__)", - "iOS": "#ifdef IPHONE_ENABLED", + "iOS": "#ifdef IOS_ENABLED", "Javascript": "#ifdef JAVASCRIPT_ENABLED", "UWP": "#ifdef UWP_ENABLED", } diff --git a/core/input/shortcut.h b/core/input/shortcut.h index 0c9689cdcb..daec410039 100644 --- a/core/input/shortcut.h +++ b/core/input/shortcut.h @@ -55,4 +55,5 @@ public: static bool is_event_array_equal(const Array &p_event_array1, const Array &p_event_array2); }; + #endif // SHORTCUT_H diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp index 0a900078b7..f82d6f077f 100644 --- a/core/io/dir_access.cpp +++ b/core/io/dir_access.cpp @@ -34,6 +34,7 @@ #include "core/io/file_access.h" #include "core/os/memory.h" #include "core/os/os.h" +#include "core/templates/local_vector.h" String DirAccess::_get_root_path() const { switch (_access_type) { @@ -286,11 +287,16 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { Ref<FileAccess> fdst = FileAccess::open(p_to, FileAccess::WRITE, &err); ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to open " + p_to); + const size_t copy_buffer_limit = 65536; // 64 KB + fsrc->seek_end(0); int size = fsrc->get_position(); fsrc->seek(0); err = OK; - while (size--) { + size_t buffer_size = MIN(size * sizeof(uint8_t), copy_buffer_limit); + LocalVector<uint8_t> buffer; + buffer.resize(buffer_size); + while (size > 0) { if (fsrc->get_error() != OK) { err = fsrc->get_error(); break; @@ -300,7 +306,14 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) { break; } - fdst->store_8(fsrc->get_8()); + int bytes_read = fsrc->get_buffer(buffer.ptr(), buffer_size); + if (bytes_read <= 0) { + err = FAILED; + break; + } + fdst->store_buffer(buffer.ptr(), bytes_read); + + size -= bytes_read; } } diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 8ee19f274e..2f69c10218 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -285,6 +285,46 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; + case Variant::VECTOR4: { + Vector4 val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); + val.x = decode_double(&buf[0]); + val.y = decode_double(&buf[sizeof(double)]); + val.z = decode_double(&buf[sizeof(double) * 2]); + val.w = decode_double(&buf[sizeof(double) * 3]); + + if (r_len) { + (*r_len) += sizeof(double) * 4; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 4, ERR_INVALID_DATA); + val.x = decode_float(&buf[0]); + val.y = decode_float(&buf[sizeof(float)]); + val.z = decode_float(&buf[sizeof(float) * 2]); + val.w = decode_float(&buf[sizeof(float) * 3]); + + if (r_len) { + (*r_len) += sizeof(float) * 4; + } + } + r_variant = val; + + } break; + case Variant::VECTOR4I: { + ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); + Vector4i val; + val.x = decode_uint32(&buf[0]); + val.y = decode_uint32(&buf[4]); + val.z = decode_uint32(&buf[8]); + val.w = decode_uint32(&buf[12]); + r_variant = val; + + if (r_len) { + (*r_len) += 4 * 4; + } + + } break; case Variant::TRANSFORM2D: { Transform2D val; if (type & ENCODE_FLAG_64) { @@ -457,6 +497,33 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = val; } break; + case Variant::PROJECTION: { + Projection val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 16, ERR_INVALID_DATA); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + val.matrix[i][j] = decode_double(&buf[(i * 4 + j) * sizeof(double)]); + } + } + if (r_len) { + (*r_len) += sizeof(double) * 16; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 62, ERR_INVALID_DATA); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + val.matrix[i][j] = decode_float(&buf[(i * 4 + j) * sizeof(float)]); + } + } + + if (r_len) { + (*r_len) += sizeof(float) * 16; + } + } + r_variant = val; + + } break; // misc types case Variant::COLOR: { ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); @@ -1286,6 +1353,30 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 6 * sizeof(real_t); } break; + case Variant::VECTOR4: { + if (buf) { + Vector4 v4 = p_variant; + encode_real(v4.x, &buf[0]); + encode_real(v4.y, &buf[sizeof(real_t)]); + encode_real(v4.z, &buf[sizeof(real_t) * 2]); + encode_real(v4.w, &buf[sizeof(real_t) * 3]); + } + + r_len += 4 * sizeof(real_t); + + } break; + case Variant::VECTOR4I: { + if (buf) { + Vector4i v4 = p_variant; + encode_uint32(v4.x, &buf[0]); + encode_uint32(v4.y, &buf[4]); + encode_uint32(v4.z, &buf[8]); + encode_uint32(v4.w, &buf[12]); + } + + r_len += 4 * 4; + + } break; case Variant::PLANE: { if (buf) { Plane p = p_variant; @@ -1354,6 +1445,19 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 12 * sizeof(real_t); } break; + case Variant::PROJECTION: { + if (buf) { + Projection val = p_variant; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + memcpy(&buf[(i * 4 + j) * sizeof(real_t)], &val.matrix[i][j], sizeof(real_t)); + } + } + } + + r_len += 16 * sizeof(real_t); + + } break; // misc types case Variant::COLOR: { diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index 0b12640627..ec9d33aa5a 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -127,4 +127,4 @@ public: PacketPeerStream(); }; -#endif // PACKET_STREAM_H +#endif // PACKET_PEER_H diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index b1c50e829c..016302c653 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -81,6 +81,9 @@ enum { VARIANT_VECTOR3I = 47, VARIANT_PACKED_INT64_ARRAY = 48, VARIANT_PACKED_FLOAT64_ARRAY = 49, + VARIANT_VECTOR4 = 50, + VARIANT_VECTOR4I = 51, + VARIANT_PROJECTION = 52, OBJECT_EMPTY = 0, OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, @@ -237,6 +240,22 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { v.z = f->get_32(); r_v = v; } break; + case VARIANT_VECTOR4: { + Vector4 v; + v.x = f->get_real(); + v.y = f->get_real(); + v.z = f->get_real(); + v.w = f->get_real(); + r_v = v; + } break; + case VARIANT_VECTOR4I: { + Vector4i v; + v.x = f->get_32(); + v.y = f->get_32(); + v.z = f->get_32(); + v.w = f->get_32(); + r_v = v; + } break; case VARIANT_PLANE: { Plane v; v.normal.x = f->get_real(); @@ -306,6 +325,26 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { v.origin.z = f->get_real(); r_v = v; } break; + case VARIANT_PROJECTION: { + Projection v; + v.matrix[0].x = f->get_real(); + v.matrix[0].y = f->get_real(); + v.matrix[0].z = f->get_real(); + v.matrix[0].w = f->get_real(); + v.matrix[1].x = f->get_real(); + v.matrix[1].y = f->get_real(); + v.matrix[1].z = f->get_real(); + v.matrix[1].w = f->get_real(); + v.matrix[2].x = f->get_real(); + v.matrix[2].y = f->get_real(); + v.matrix[2].z = f->get_real(); + v.matrix[2].w = f->get_real(); + v.matrix[3].x = f->get_real(); + v.matrix[3].y = f->get_real(); + v.matrix[3].z = f->get_real(); + v.matrix[3].w = f->get_real(); + r_v = v; + } break; case VARIANT_COLOR: { Color v; // Colors should always be in single-precision. v.r = f->get_float(); @@ -865,6 +904,22 @@ String ResourceLoaderBinary::get_unicode_string() { return s; } +void ResourceLoaderBinary::get_classes_used(Ref<FileAccess> p_f, HashSet<StringName> *p_classes) { + open(p_f, false, true); + if (error) { + return; + } + + for (int i = 0; i < internal_resources.size(); i++) { + p_f->seek(internal_resources[i].offset); + String t = get_unicode_string(); + ERR_FAIL_COND(p_f->get_error() != OK); + if (t != String()) { + p_classes->insert(t); + } + } +} + void ResourceLoaderBinary::get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types) { open(p_f, false, true); if (error) { @@ -1337,6 +1392,16 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons return OK; } +void ResourceFormatLoaderBinary::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) { + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_MSG(f.is_null(), "Cannot open file '" + p_path + "'."); + + ResourceLoaderBinary loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + loader.get_classes_used(f, r_classes); +} + String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); if (f.is_null()) { @@ -1473,6 +1538,24 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V f->store_32(val.z); } break; + case Variant::VECTOR4: { + f->store_32(VARIANT_VECTOR4); + Vector4 val = p_property; + f->store_real(val.x); + f->store_real(val.y); + f->store_real(val.z); + f->store_real(val.w); + + } break; + case Variant::VECTOR4I: { + f->store_32(VARIANT_VECTOR4I); + Vector4i val = p_property; + f->store_32(val.x); + f->store_32(val.y); + f->store_32(val.z); + f->store_32(val.w); + + } break; case Variant::PLANE: { f->store_32(VARIANT_PLANE); Plane val = p_property; @@ -1544,6 +1627,27 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V f->store_real(val.origin.z); } break; + case Variant::PROJECTION: { + f->store_32(VARIANT_PROJECTION); + Projection val = p_property; + f->store_real(val.matrix[0].x); + f->store_real(val.matrix[0].y); + f->store_real(val.matrix[0].z); + f->store_real(val.matrix[0].w); + f->store_real(val.matrix[1].x); + f->store_real(val.matrix[1].y); + f->store_real(val.matrix[1].z); + f->store_real(val.matrix[1].w); + f->store_real(val.matrix[2].x); + f->store_real(val.matrix[2].y); + f->store_real(val.matrix[2].z); + f->store_real(val.matrix[2].w); + f->store_real(val.matrix[3].x); + f->store_real(val.matrix[3].y); + f->store_real(val.matrix[3].z); + f->store_real(val.matrix[3].w); + + } break; case Variant::COLOR: { f->store_32(VARIANT_COLOR); Color val = p_property; diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 5da880ddb8..2b043302fd 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -101,6 +101,7 @@ public: void open(Ref<FileAccess> p_f, bool p_no_resources = false, bool p_keep_uuid_paths = false); String recognize(Ref<FileAccess> p_f); void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types); + void get_classes_used(Ref<FileAccess> p_f, HashSet<StringName> *p_classes); ResourceLoaderBinary() {} }; @@ -112,6 +113,7 @@ public: 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; + virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map); diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 934cb780e6..e059fc842b 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -352,6 +352,16 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons return pat.metadata; } +void ResourceFormatImporter::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) { + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + return; + } + + ResourceLoader::get_classes_used(pat.path, r_classes); +} void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { PathAndType pat; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 0c7909df06..d0ea98b598 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -65,12 +65,12 @@ public: virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; virtual ResourceUID::ID get_resource_uid(const String &p_path) const; - virtual Variant get_resource_metadata(const String &p_path) const; virtual bool is_import_valid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual bool is_imported(const String &p_path) const { return recognize_path(p_path); } virtual String get_import_group_file(const String &p_path) const; + virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); virtual bool exists(const String &p_path) const; virtual int get_import_order(const String &p_path) const; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 2cd455475c..fc4177004b 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -76,6 +76,21 @@ bool ResourceFormatLoader::handles_type(const String &p_type) const { return false; } +void ResourceFormatLoader::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) { + Vector<String> ret; + if (GDVIRTUAL_CALL(_get_classes_used, p_path, ret)) { + for (int i = 0; i < ret.size(); i++) { + r_classes->insert(ret[i]); + } + return; + } + + String res = get_resource_type(p_path); + if (!res.is_empty()) { + r_classes->insert(res); + } +} + String ResourceFormatLoader::get_resource_type(const String &p_path) const { String ret; @@ -180,6 +195,7 @@ void ResourceFormatLoader::_bind_methods() { GDVIRTUAL_BIND(_get_dependencies, "path", "add_types"); GDVIRTUAL_BIND(_rename_dependencies, "path", "renames"); GDVIRTUAL_BIND(_exists, "path"); + GDVIRTUAL_BIND(_get_classes_used, "path"); GDVIRTUAL_BIND(_load, "path", "original_path", "use_sub_threads", "cache_mode"); } @@ -730,6 +746,18 @@ Error ResourceLoader::rename_dependencies(const String &p_path, const HashMap<St return OK; // ?? } +void ResourceLoader::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) { + String local_path = _validate_local_path(p_path); + + for (int i = 0; i < loader_count; i++) { + if (!loader[i]->recognize_path(local_path)) { + continue; + } + + return loader[i]->get_classes_used(p_path, r_classes); + } +} + String ResourceLoader::get_resource_type(const String &p_path) { String local_path = _validate_local_path(p_path); diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 815dd1dd72..91ba930176 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -55,6 +55,7 @@ protected: GDVIRTUAL1RC(String, _get_resource_type, String) GDVIRTUAL1RC(ResourceUID::ID, _get_resource_uid, String) GDVIRTUAL2RC(Vector<String>, _get_dependencies, String, bool) + GDVIRTUAL1RC(Vector<String>, _get_classes_used, String) GDVIRTUAL2RC(int64_t, _rename_dependencies, String, Dictionary) GDVIRTUAL1RC(bool, _exists, String) @@ -67,6 +68,7 @@ public: 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; virtual bool handles_type(const String &p_type) const; + virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); virtual String get_resource_type(const String &p_path) const; virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); @@ -170,6 +172,7 @@ public: static void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions); static void add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front = false); static void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader); + static void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); static String get_resource_type(const String &p_path); static ResourceUID::ID get_resource_uid(const String &p_path); static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); diff --git a/core/io/resource_uid.h b/core/io/resource_uid.h index da42553cf5..0da37e2716 100644 --- a/core/io/resource_uid.h +++ b/core/io/resource_uid.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RESOURCE_UUID_H -#define RESOURCE_UUID_H +#ifndef RESOURCE_UID_H +#define RESOURCE_UID_H #include "core/object/ref_counted.h" #include "core/string/string_name.h" @@ -85,4 +85,4 @@ public: ~ResourceUID(); }; -#endif // RESOURCEUUID_H +#endif // RESOURCE_UID_H diff --git a/core/math/bvh.h b/core/math/bvh.h index 9f6ab9f736..b5f5eda3e6 100644 --- a/core/math/bvh.h +++ b/core/math/bvh.h @@ -302,7 +302,7 @@ public: tree.update(); _check_for_collisions(); #ifdef BVH_INTEGRITY_CHECKS - tree.integrity_check_all(); + tree._integrity_check_all(); #endif } diff --git a/core/math/bvh_public.inc b/core/math/bvh_public.inc index 36b0bfeb13..fc1c67a21b 100644 --- a/core/math/bvh_public.inc +++ b/core/math/bvh_public.inc @@ -2,7 +2,7 @@ public: BVHHandle item_add(T *p_userdata, bool p_active, const BOUNDS &p_aabb, int32_t p_subindex, uint32_t p_tree_id, uint32_t p_tree_collision_mask, bool p_invisible = false) { #ifdef BVH_VERBOSE_TREE VERBOSE_PRINT("\nitem_add BEFORE"); - _debug_recursive_print_tree(0); + _debug_recursive_print_tree(p_tree_id); VERBOSE_PRINT("\n"); #endif @@ -78,8 +78,8 @@ BVHHandle item_add(T *p_userdata, bool p_active, const BOUNDS &p_aabb, int32_t p mem += _nodes.estimate_memory_use(); String sz = _debug_aabb_to_string(abb); - VERBOSE_PRINT("\titem_add [" + itos(ref_id) + "] " + itos(_refs.size()) + " refs,\t" + itos(_nodes.size()) + " nodes " + sz); - VERBOSE_PRINT("mem use : " + itos(mem) + ", num nodes : " + itos(_nodes.size())); + VERBOSE_PRINT("\titem_add [" + itos(ref_id) + "] " + itos(_refs.used_size()) + " refs,\t" + itos(_nodes.used_size()) + " nodes " + sz); + VERBOSE_PRINT("mem use : " + itos(mem) + ", num nodes reserved : " + itos(_nodes.reserved_size())); #endif diff --git a/core/math/color.h b/core/math/color.h index 0afa6006a8..65036f74cc 100644 --- a/core/math/color.h +++ b/core/math/color.h @@ -215,12 +215,12 @@ struct _NO_DISCARD_ Color { _FORCE_INLINE_ void set_a8(int32_t a8) { a = (CLAMP(a8, 0, 255) / 255.0f); } _FORCE_INLINE_ int32_t get_a8() const { return int32_t(CLAMP(Math::round(a * 255.0f), 0.0f, 255.0f)); } - _FORCE_INLINE_ void set_h(float p_h) { set_hsv(p_h, get_s(), get_v()); } - _FORCE_INLINE_ void set_s(float p_s) { set_hsv(get_h(), p_s, get_v()); } - _FORCE_INLINE_ void set_v(float p_v) { set_hsv(get_h(), get_s(), p_v); } - _FORCE_INLINE_ void set_ok_hsl_h(float p_h) { set_ok_hsl(p_h, get_ok_hsl_s(), get_ok_hsl_l()); } - _FORCE_INLINE_ void set_ok_hsl_s(float p_s) { set_ok_hsl(get_ok_hsl_h(), p_s, get_ok_hsl_l()); } - _FORCE_INLINE_ void set_ok_hsl_l(float p_l) { set_ok_hsl(get_ok_hsl_h(), get_ok_hsl_s(), p_l); } + _FORCE_INLINE_ void set_h(float p_h) { set_hsv(p_h, get_s(), get_v(), a); } + _FORCE_INLINE_ void set_s(float p_s) { set_hsv(get_h(), p_s, get_v(), a); } + _FORCE_INLINE_ void set_v(float p_v) { set_hsv(get_h(), get_s(), p_v, a); } + _FORCE_INLINE_ void set_ok_hsl_h(float p_h) { set_ok_hsl(p_h, get_ok_hsl_s(), get_ok_hsl_l(), a); } + _FORCE_INLINE_ void set_ok_hsl_s(float p_s) { set_ok_hsl(get_ok_hsl_h(), p_s, get_ok_hsl_l(), a); } + _FORCE_INLINE_ void set_ok_hsl_l(float p_l) { set_ok_hsl(get_ok_hsl_h(), get_ok_hsl_s(), p_l, a); } _FORCE_INLINE_ Color() {} diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 4ab00e1f34..898c3c2d91 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -33,7 +33,7 @@ #include "core/io/file_access.h" #include "core/math/aabb.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/math/vector3.h" #include "core/string/print_string.h" #include "core/templates/local_vector.h" @@ -184,7 +184,7 @@ class Delaunay3D { return true; } - CameraMatrix cm; + Projection cm; cm.matrix[0][0] = p_points[p_simplex.points[0]].x; cm.matrix[0][1] = p_points[p_simplex.points[1]].x; diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp index 4be4809e3f..208f89f449 100644 --- a/core/math/math_fieldwise.cpp +++ b/core/math/math_fieldwise.cpp @@ -76,6 +76,36 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } + case Variant::VECTOR3I: { + SETUP_TYPE(Vector3i) + + /**/ TRY_TRANSFER_FIELD("x", x) + else TRY_TRANSFER_FIELD("y", y) + else TRY_TRANSFER_FIELD("z", z) + + return target; + } + case Variant::VECTOR4: { + SETUP_TYPE(Vector4) + + /**/ TRY_TRANSFER_FIELD("x", x) + else TRY_TRANSFER_FIELD("y", y) + else TRY_TRANSFER_FIELD("z", z) + else TRY_TRANSFER_FIELD("w", w) + + return target; + } + case Variant::VECTOR4I: { + SETUP_TYPE(Vector4i) + + /**/ TRY_TRANSFER_FIELD("x", x) + else TRY_TRANSFER_FIELD("y", y) + else TRY_TRANSFER_FIELD("z", z) + else TRY_TRANSFER_FIELD("w", w) + + return target; + } + case Variant::PLANE: { SETUP_TYPE(Plane) diff --git a/core/math/plane.h b/core/math/plane.h index 66c1741662..73babfa496 100644 --- a/core/math/plane.h +++ b/core/math/plane.h @@ -52,7 +52,7 @@ struct _NO_DISCARD_ Plane { _FORCE_INLINE_ bool is_point_over(const Vector3 &p_point) const; ///< Point is over plane _FORCE_INLINE_ real_t distance_to(const Vector3 &p_point) const; - _FORCE_INLINE_ bool has_point(const Vector3 &p_point, real_t _epsilon = CMP_EPSILON) const; + _FORCE_INLINE_ bool has_point(const Vector3 &p_point, real_t p_tolerance = CMP_EPSILON) const; /* intersections */ @@ -97,10 +97,10 @@ real_t Plane::distance_to(const Vector3 &p_point) const { return (normal.dot(p_point) - d); } -bool Plane::has_point(const Vector3 &p_point, real_t _epsilon) const { +bool Plane::has_point(const Vector3 &p_point, real_t p_tolerance) const { real_t dist = normal.dot(p_point) - d; dist = ABS(dist); - return (dist <= _epsilon); + return (dist <= p_tolerance); } Plane::Plane(const Vector3 &p_normal, real_t p_d) : diff --git a/core/math/camera_matrix.cpp b/core/math/projection.cpp index 57c53b0adb..edf8bf36cd 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/projection.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* camera_matrix.cpp */ +/* projection.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "camera_matrix.h" +#include "projection.h" #include "core/math/aabb.h" #include "core/math/math_funcs.h" @@ -37,7 +37,7 @@ #include "core/math/transform_3d.h" #include "core/string/print_string.h" -float CameraMatrix::determinant() const { +float Projection::determinant() const { return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] - matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] - matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] + matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] + matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] - matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] - @@ -52,7 +52,7 @@ float CameraMatrix::determinant() const { matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] + matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3]; } -void CameraMatrix::set_identity() { +void Projection::set_identity() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { matrix[i][j] = (i == j) ? 1 : 0; @@ -60,7 +60,7 @@ void CameraMatrix::set_identity() { } } -void CameraMatrix::set_zero() { +void Projection::set_zero() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { matrix[i][j] = 0; @@ -68,7 +68,7 @@ void CameraMatrix::set_zero() { } } -Plane CameraMatrix::xform4(const Plane &p_vec4) const { +Plane Projection::xform4(const Plane &p_vec4) const { Plane ret; ret.normal.x = matrix[0][0] * p_vec4.normal.x + matrix[1][0] * p_vec4.normal.y + matrix[2][0] * p_vec4.normal.z + matrix[3][0] * p_vec4.d; @@ -78,7 +78,22 @@ Plane CameraMatrix::xform4(const Plane &p_vec4) const { return ret; } -void CameraMatrix::adjust_perspective_znear(real_t p_new_znear) { +Vector4 Projection::xform(const Vector4 &p_vec4) const { + return Vector4( + matrix[0][0] * p_vec4.x + matrix[1][0] * p_vec4.y + matrix[2][0] * p_vec4.z + matrix[3][0] * p_vec4.w, + matrix[0][1] * p_vec4.x + matrix[1][1] * p_vec4.y + matrix[2][1] * p_vec4.z + matrix[3][1] * p_vec4.w, + matrix[0][2] * p_vec4.x + matrix[1][2] * p_vec4.y + matrix[2][2] * p_vec4.z + matrix[3][2] * p_vec4.w, + matrix[0][3] * p_vec4.x + matrix[1][3] * p_vec4.y + matrix[2][3] * p_vec4.z + matrix[3][3] * p_vec4.w); +} +Vector4 Projection::xform_inv(const Vector4 &p_vec4) const { + return Vector4( + matrix[0][0] * p_vec4.x + matrix[0][1] * p_vec4.y + matrix[0][2] * p_vec4.z + matrix[0][3] * p_vec4.w, + matrix[1][0] * p_vec4.x + matrix[1][1] * p_vec4.y + matrix[1][2] * p_vec4.z + matrix[1][3] * p_vec4.w, + matrix[2][0] * p_vec4.x + matrix[2][1] * p_vec4.y + matrix[2][2] * p_vec4.z + matrix[2][3] * p_vec4.w, + matrix[3][0] * p_vec4.x + matrix[3][1] * p_vec4.y + matrix[3][2] * p_vec4.z + matrix[3][3] * p_vec4.w); +} + +void Projection::adjust_perspective_znear(real_t p_new_znear) { real_t zfar = get_z_far(); real_t znear = p_new_znear; @@ -87,7 +102,154 @@ void CameraMatrix::adjust_perspective_znear(real_t p_new_znear) { matrix[3][2] = -2 * znear * zfar / deltaZ; } -void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) { +Projection Projection::create_depth_correction(bool p_flip_y) { + Projection proj; + proj.set_depth_correction(p_flip_y); + return proj; +} + +Projection Projection::create_light_atlas_rect(const Rect2 &p_rect) { + Projection proj; + proj.set_light_atlas_rect(p_rect); + return proj; +} + +Projection Projection::create_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) { + Projection proj; + proj.set_perspective(p_fovy_degrees, p_aspect, p_z_near, p_z_far, p_flip_fov); + return proj; +} + +Projection Projection::create_perspective_hmd(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) { + Projection proj; + proj.set_perspective(p_fovy_degrees, p_aspect, p_z_near, p_z_far, p_flip_fov, p_eye, p_intraocular_dist, p_convergence_dist); + return proj; +} + +Projection Projection::create_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { + Projection proj; + proj.set_for_hmd(p_eye, p_aspect, p_intraocular_dist, p_display_width, p_display_to_lens, p_oversample, p_z_near, p_z_far); + return proj; +} + +Projection Projection::create_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) { + Projection proj; + proj.set_orthogonal(p_left, p_right, p_bottom, p_top, p_zfar, p_zfar); + return proj; +} + +Projection Projection::create_orthogonal_aspect(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) { + Projection proj; + proj.set_orthogonal(p_size, p_aspect, p_znear, p_zfar, p_flip_fov); + return proj; +} + +Projection Projection::create_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far) { + Projection proj; + proj.set_frustum(p_left, p_right, p_bottom, p_top, p_near, p_far); + return proj; +} + +Projection Projection::create_frustum_aspect(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov) { + Projection proj; + proj.set_frustum(p_size, p_aspect, p_offset, p_near, p_far, p_flip_fov); + return proj; +} + +Projection Projection::create_fit_aabb(const AABB &p_aabb) { + Projection proj; + proj.scale_translate_to_fit(p_aabb); + return proj; +} + +Projection Projection::perspective_znear_adjusted(real_t p_new_znear) const { + Projection proj = *this; + proj.adjust_perspective_znear(p_new_znear); + return proj; +} + +Plane Projection::get_projection_plane(Planes p_plane) const { + const real_t *matrix = (const real_t *)this->matrix; + + switch (p_plane) { + case PLANE_NEAR: { + Plane new_plane = Plane(matrix[3] + matrix[2], + matrix[7] + matrix[6], + matrix[11] + matrix[10], + matrix[15] + matrix[14]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_FAR: { + Plane new_plane = Plane(matrix[3] - matrix[2], + matrix[7] - matrix[6], + matrix[11] - matrix[10], + matrix[15] - matrix[14]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_LEFT: { + Plane new_plane = Plane(matrix[3] + matrix[0], + matrix[7] + matrix[4], + matrix[11] + matrix[8], + matrix[15] + matrix[12]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_TOP: { + Plane new_plane = Plane(matrix[3] - matrix[1], + matrix[7] - matrix[5], + matrix[11] - matrix[9], + matrix[15] - matrix[13]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_RIGHT: { + Plane new_plane = Plane(matrix[3] - matrix[0], + matrix[7] - matrix[4], + matrix[11] - matrix[8], + matrix[15] - matrix[12]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_BOTTOM: { + Plane new_plane = Plane(matrix[3] + matrix[1], + matrix[7] + matrix[5], + matrix[11] + matrix[9], + matrix[15] + matrix[13]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + } + + return Plane(); +} + +Projection Projection::flipped_y() const { + Projection proj = *this; + proj.flip_y(); + return proj; +} + +Projection Projection ::jitter_offseted(const Vector2 &p_offset) const { + Projection proj = *this; + proj.add_jitter_offset(p_offset); + return proj; +} + +void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) { if (p_flip_fov) { p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect); } @@ -113,7 +275,7 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ matrix[3][3] = 0; } -void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) { +void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) { if (p_flip_fov) { p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect); } @@ -145,13 +307,13 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ set_frustum(left, right, -ymax, ymax, p_z_near, p_z_far); // translate matrix by (modeltranslation, 0.0, 0.0) - CameraMatrix cm; + Projection cm; cm.set_identity(); cm.matrix[3][0] = modeltranslation; *this = *this * cm; } -void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { +void Projection::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { // we first calculate our base frustum on our values without taking our lens magnification into account. real_t f1 = (p_intraocular_dist * 0.5) / p_display_to_lens; real_t f2 = ((p_display_width - p_intraocular_dist) * 0.5) / p_display_to_lens; @@ -179,7 +341,7 @@ void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_ } } -void CameraMatrix::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) { +void Projection::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) { set_identity(); matrix[0][0] = 2.0 / (p_right - p_left); @@ -191,7 +353,7 @@ void CameraMatrix::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom matrix[3][3] = 1.0; } -void CameraMatrix::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) { +void Projection::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) { if (!p_flip_fov) { p_size *= p_aspect; } @@ -199,7 +361,7 @@ void CameraMatrix::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear set_orthogonal(-p_size / 2, +p_size / 2, -p_size / p_aspect / 2, +p_size / p_aspect / 2, p_znear, p_zfar); } -void CameraMatrix::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far) { +void Projection::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far) { ERR_FAIL_COND(p_right <= p_left); ERR_FAIL_COND(p_top <= p_bottom); ERR_FAIL_COND(p_far <= p_near); @@ -231,7 +393,7 @@ void CameraMatrix::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, r te[15] = 0; } -void CameraMatrix::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov) { +void Projection::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov) { if (!p_flip_fov) { p_size *= p_aspect; } @@ -239,7 +401,7 @@ void CameraMatrix::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, set_frustum(-p_size / 2 + p_offset.x, +p_size / 2 + p_offset.x, -p_size / p_aspect / 2 + p_offset.y, +p_size / p_aspect / 2 + p_offset.y, p_near, p_far); } -real_t CameraMatrix::get_z_far() const { +real_t Projection::get_z_far() const { const real_t *matrix = (const real_t *)this->matrix; Plane new_plane = Plane(matrix[3] - matrix[2], matrix[7] - matrix[6], @@ -252,7 +414,7 @@ real_t CameraMatrix::get_z_far() const { return new_plane.d; } -real_t CameraMatrix::get_z_near() const { +real_t Projection::get_z_near() const { const real_t *matrix = (const real_t *)this->matrix; Plane new_plane = Plane(matrix[3] + matrix[2], matrix[7] + matrix[6], @@ -263,7 +425,7 @@ real_t CameraMatrix::get_z_near() const { return new_plane.d; } -Vector2 CameraMatrix::get_viewport_half_extents() const { +Vector2 Projection::get_viewport_half_extents() const { const real_t *matrix = (const real_t *)this->matrix; ///////--- Near Plane ---/////// Plane near_plane = Plane(matrix[3] + matrix[2], @@ -291,7 +453,7 @@ Vector2 CameraMatrix::get_viewport_half_extents() const { return Vector2(res.x, res.y); } -Vector2 CameraMatrix::get_far_plane_half_extents() const { +Vector2 Projection::get_far_plane_half_extents() const { const real_t *matrix = (const real_t *)this->matrix; ///////--- Far Plane ---/////// Plane far_plane = Plane(matrix[3] - matrix[2], @@ -319,7 +481,7 @@ Vector2 CameraMatrix::get_far_plane_half_extents() const { return Vector2(res.x, res.y); } -bool CameraMatrix::get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const { +bool Projection::get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const { Vector<Plane> planes = get_projection_planes(Transform3D()); const Planes intersections[8][3] = { { PLANE_FAR, PLANE_LEFT, PLANE_TOP }, @@ -342,7 +504,7 @@ bool CameraMatrix::get_endpoints(const Transform3D &p_transform, Vector3 *p_8poi return true; } -Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform) const { +Vector<Plane> Projection::get_projection_planes(const Transform3D &p_transform) const { /** Fast Plane Extraction from combined modelview/projection matrices. * References: * https://web.archive.org/web/20011221205252/https://www.markmorley.com/opengl/frustumculling.html @@ -425,13 +587,13 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform return planes; } -CameraMatrix CameraMatrix::inverse() const { - CameraMatrix cm = *this; +Projection Projection::inverse() const { + Projection cm = *this; cm.invert(); return cm; } -void CameraMatrix::invert() { +void Projection::invert() { int i, j, k; int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */ real_t pvt_val; /* Value of current pivot element */ @@ -529,18 +691,18 @@ void CameraMatrix::invert() { } } -void CameraMatrix::flip_y() { +void Projection::flip_y() { for (int i = 0; i < 4; i++) { matrix[1][i] = -matrix[1][i]; } } -CameraMatrix::CameraMatrix() { +Projection::Projection() { set_identity(); } -CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const { - CameraMatrix new_matrix; +Projection Projection::operator*(const Projection &p_matrix) const { + Projection new_matrix; for (int j = 0; j < 4; j++) { for (int i = 0; i < 4; i++) { @@ -555,7 +717,7 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const { return new_matrix; } -void CameraMatrix::set_depth_correction(bool p_flip_y) { +void Projection::set_depth_correction(bool p_flip_y) { real_t *m = &matrix[0][0]; m[0] = 1; @@ -576,7 +738,7 @@ void CameraMatrix::set_depth_correction(bool p_flip_y) { m[15] = 1.0; } -void CameraMatrix::set_light_bias() { +void Projection::set_light_bias() { real_t *m = &matrix[0][0]; m[0] = 0.5; @@ -597,7 +759,7 @@ void CameraMatrix::set_light_bias() { m[15] = 1.0; } -void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) { +void Projection::set_light_atlas_rect(const Rect2 &p_rect) { real_t *m = &matrix[0][0]; m[0] = p_rect.size.width; @@ -618,7 +780,7 @@ void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) { m[15] = 1.0; } -CameraMatrix::operator String() const { +Projection::operator String() const { String str; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { @@ -629,22 +791,22 @@ CameraMatrix::operator String() const { return str; } -real_t CameraMatrix::get_aspect() const { +real_t Projection::get_aspect() const { Vector2 vp_he = get_viewport_half_extents(); return vp_he.x / vp_he.y; } -int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const { +int Projection::get_pixels_per_meter(int p_for_pixel_width) const { Vector3 result = xform(Vector3(1, 0, -1)); return int((result.x * 0.5 + 0.5) * p_for_pixel_width); } -bool CameraMatrix::is_orthogonal() const { +bool Projection::is_orthogonal() const { return matrix[3][3] == 1.0; } -real_t CameraMatrix::get_fov() const { +real_t Projection::get_fov() const { const real_t *matrix = (const real_t *)this->matrix; Plane right_plane = Plane(matrix[3] - matrix[0], @@ -667,7 +829,7 @@ real_t CameraMatrix::get_fov() const { } } -float CameraMatrix::get_lod_multiplier() const { +float Projection::get_lod_multiplier() const { if (is_orthogonal()) { return get_viewport_half_extents().x; } else { @@ -678,14 +840,14 @@ float CameraMatrix::get_lod_multiplier() const { //usage is lod_size / (lod_distance * multiplier) < threshold } -void CameraMatrix::make_scale(const Vector3 &p_scale) { +void Projection::make_scale(const Vector3 &p_scale) { set_identity(); matrix[0][0] = p_scale.x; matrix[1][1] = p_scale.y; matrix[2][2] = p_scale.z; } -void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) { +void Projection::scale_translate_to_fit(const AABB &p_aabb) { Vector3 min = p_aabb.position; Vector3 max = p_aabb.position + p_aabb.size; @@ -710,12 +872,12 @@ void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) { matrix[3][3] = 1; } -void CameraMatrix::add_jitter_offset(const Vector2 &p_offset) { +void Projection::add_jitter_offset(const Vector2 &p_offset) { matrix[3][0] += p_offset.x; matrix[3][1] += p_offset.y; } -CameraMatrix::operator Transform3D() const { +Projection::operator Transform3D() const { Transform3D tr; const real_t *m = &matrix[0][0]; @@ -737,8 +899,13 @@ CameraMatrix::operator Transform3D() const { return tr; } - -CameraMatrix::CameraMatrix(const Transform3D &p_transform) { +Projection::Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) { + matrix[0] = p_x; + matrix[1] = p_y; + matrix[2] = p_z; + matrix[3] = p_w; +} +Projection::Projection(const Transform3D &p_transform) { const Transform3D &tr = p_transform; real_t *m = &matrix[0][0]; @@ -760,5 +927,5 @@ CameraMatrix::CameraMatrix(const Transform3D &p_transform) { m[15] = 1.0; } -CameraMatrix::~CameraMatrix() { +Projection::~Projection() { } diff --git a/core/math/camera_matrix.h b/core/math/projection.h index a4051cee3b..a3d2d7720b 100644 --- a/core/math/camera_matrix.h +++ b/core/math/projection.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* camera_matrix.h */ +/* projection.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERA_MATRIX_H -#define CAMERA_MATRIX_H +#ifndef PROJECTION_H +#define PROJECTION_H #include "core/math/math_defs.h" #include "core/math/vector3.h" +#include "core/math/vector4.h" #include "core/templates/vector.h" struct AABB; @@ -41,7 +42,7 @@ struct Rect2; struct Transform3D; struct Vector2; -struct CameraMatrix { +struct Projection { enum Planes { PLANE_NEAR, PLANE_FAR, @@ -51,13 +52,24 @@ struct CameraMatrix { PLANE_BOTTOM }; - real_t matrix[4][4]; + Vector4 matrix[4]; + + _FORCE_INLINE_ const Vector4 &operator[](const int p_axis) const { + DEV_ASSERT((unsigned int)p_axis < 4); + return matrix[p_axis]; + } + + _FORCE_INLINE_ Vector4 &operator[](const int p_axis) { + DEV_ASSERT((unsigned int)p_axis < 4); + return matrix[p_axis]; + } float determinant() const; void set_identity(); void set_zero(); void set_light_bias(); void set_depth_correction(bool p_flip_y = true); + void set_light_atlas_rect(const Rect2 &p_rect); void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov = false); void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist); @@ -68,6 +80,21 @@ struct CameraMatrix { void set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov = false); void adjust_perspective_znear(real_t p_new_znear); + static Projection create_depth_correction(bool p_flip_y); + static Projection create_light_atlas_rect(const Rect2 &p_rect); + static Projection create_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov = false); + static Projection create_perspective_hmd(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist); + static Projection create_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far); + static Projection create_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar); + static Projection create_orthogonal_aspect(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov = false); + static Projection create_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far); + static Projection create_frustum_aspect(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov = false); + static Projection create_fit_aabb(const AABB &p_aabb); + Projection perspective_znear_adjusted(real_t p_new_znear) const; + Plane get_projection_plane(Planes p_plane) const; + Projection flipped_y() const; + Projection jitter_offseted(const Vector2 &p_offset) const; + static real_t get_fovy(real_t p_fovx, real_t p_aspect) { return Math::rad2deg(Math::atan(p_aspect * Math::tan(Math::deg2rad(p_fovx) * 0.5)) * 2.0); } @@ -85,13 +112,16 @@ struct CameraMatrix { Vector2 get_far_plane_half_extents() const; void invert(); - CameraMatrix inverse() const; + Projection inverse() const; - CameraMatrix operator*(const CameraMatrix &p_matrix) const; + Projection operator*(const Projection &p_matrix) const; Plane xform4(const Plane &p_vec4) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec3) const; + Vector4 xform(const Vector4 &p_vec4) const; + Vector4 xform_inv(const Vector4 &p_vec4) const; + operator String() const; void scale_translate_to_fit(const AABB &p_aabb); @@ -102,7 +132,7 @@ struct CameraMatrix { void flip_y(); - bool operator==(const CameraMatrix &p_cam) const { + bool operator==(const Projection &p_cam) const { for (uint32_t i = 0; i < 4; i++) { for (uint32_t j = 0; j < 4; j++) { if (matrix[i][j] != p_cam.matrix[i][j]) { @@ -113,18 +143,19 @@ struct CameraMatrix { return true; } - bool operator!=(const CameraMatrix &p_cam) const { + bool operator!=(const Projection &p_cam) const { return !(*this == p_cam); } float get_lod_multiplier() const; - CameraMatrix(); - CameraMatrix(const Transform3D &p_transform); - ~CameraMatrix(); + Projection(); + Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w); + Projection(const Transform3D &p_transform); + ~Projection(); }; -Vector3 CameraMatrix::xform(const Vector3 &p_vec3) const { +Vector3 Projection::xform(const Vector3 &p_vec3) const { Vector3 ret; ret.x = matrix[0][0] * p_vec3.x + matrix[1][0] * p_vec3.y + matrix[2][0] * p_vec3.z + matrix[3][0]; ret.y = matrix[0][1] * p_vec3.x + matrix[1][1] * p_vec3.y + matrix[2][1] * p_vec3.z + matrix[3][1]; @@ -133,4 +164,4 @@ Vector3 CameraMatrix::xform(const Vector3 &p_vec3) const { return ret / w; } -#endif // CAMERA_MATRIX_H +#endif // PROJECTION_H diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 11bfcc1a6f..252c108166 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -111,7 +111,7 @@ Quaternion Quaternion::log() const { Quaternion Quaternion::exp() const { Quaternion src = *this; Vector3 src_v = Vector3(src.x, src.y, src.z); - float theta = src_v.length(); + real_t theta = src_v.length(); if (theta < CMP_EPSILON) { return Quaternion(0, 0, 0, 1); } @@ -132,15 +132,9 @@ Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) con // adjust signs (if necessary) if (cosom < 0.0f) { cosom = -cosom; - to1.x = -p_to.x; - to1.y = -p_to.y; - to1.z = -p_to.z; - to1.w = -p_to.w; + to1 = -p_to; } else { - to1.x = p_to.x; - to1.y = p_to.y; - to1.z = p_to.z; - to1.w = p_to.w; + to1 = p_to; } // calculate coefficients @@ -189,16 +183,50 @@ Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) c invFactor * from.w + newFactor * p_to.w); } -Quaternion Quaternion::cubic_slerp(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const { +Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized."); ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion must be normalized."); #endif - //the only way to do slerp :| - real_t t2 = (1.0f - p_weight) * p_weight * 2; - Quaternion sp = this->slerp(p_b, p_weight); - Quaternion sq = p_pre_a.slerpni(p_post_b, p_weight); - return sp.slerpni(sq, t2); + Quaternion ret_q = *this; + Quaternion pre_q = p_pre_a; + Quaternion to_q = p_b; + Quaternion post_q = p_post_b; + + // Align flip phases. + ret_q = Basis(ret_q).get_rotation_quaternion(); + pre_q = Basis(pre_q).get_rotation_quaternion(); + to_q = Basis(to_q).get_rotation_quaternion(); + post_q = Basis(post_q).get_rotation_quaternion(); + + // Flip quaternions to shortest path if necessary. + bool flip1 = signbit(ret_q.dot(pre_q)); + pre_q = flip1 ? -pre_q : pre_q; + bool flip2 = signbit(ret_q.dot(to_q)); + to_q = flip2 ? -to_q : to_q; + bool flip3 = flip2 ? to_q.dot(post_q) <= 0 : signbit(to_q.dot(post_q)); + post_q = flip3 ? -post_q : post_q; + + if (flip1 || flip2 || flip3) { + // Angle is too large, calc by Approximate. + ret_q.x = Math::cubic_interpolate(ret_q.x, to_q.x, pre_q.x, post_q.x, p_weight); + ret_q.y = Math::cubic_interpolate(ret_q.y, to_q.y, pre_q.y, post_q.y, p_weight); + ret_q.z = Math::cubic_interpolate(ret_q.z, to_q.z, pre_q.z, post_q.z, p_weight); + ret_q.w = Math::cubic_interpolate(ret_q.w, to_q.w, pre_q.w, post_q.w, p_weight); + ret_q.normalize(); + } else { + // Calc by Expmap. + Quaternion ln_ret = ret_q.log(); + Quaternion ln_to = to_q.log(); + Quaternion ln_pre = pre_q.log(); + Quaternion ln_post = post_q.log(); + Quaternion ln = Quaternion(0, 0, 0, 0); + ln.x = Math::cubic_interpolate(ln_ret.x, ln_to.x, ln_pre.x, ln_post.x, p_weight); + ln.y = Math::cubic_interpolate(ln_ret.y, ln_to.y, ln_pre.y, ln_post.y, p_weight); + ln.z = Math::cubic_interpolate(ln_ret.z, ln_to.z, ln_pre.z, ln_post.z, p_weight); + ret_q = ln.exp(); + } + return ret_q; } Quaternion::operator String() const { @@ -213,7 +241,7 @@ Vector3 Quaternion::get_axis() const { return Vector3(x * r, y * r, z * r); } -float Quaternion::get_angle() const { +real_t Quaternion::get_angle() const { return 2 * Math::acos(w); } diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 9801746659..cb54a6f540 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -71,10 +71,10 @@ struct _NO_DISCARD_ Quaternion { Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const; Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const; - Quaternion cubic_slerp(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const; + Quaternion spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const; Vector3 get_axis() const; - float get_angle() const; + real_t get_angle() const; _FORCE_INLINE_ void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const { r_angle = 2 * Math::acos(w); diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index cbd2fd3fa1..bb8bf9f569 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -136,11 +136,11 @@ void Transform2D::scale_basis(const Size2 &p_scale) { columns[1][1] *= p_scale.y; } -void Transform2D::translate(const real_t p_tx, const real_t p_ty) { - translate(Vector2(p_tx, p_ty)); +void Transform2D::translate_local(const real_t p_tx, const real_t p_ty) { + translate_local(Vector2(p_tx, p_ty)); } -void Transform2D::translate(const Vector2 &p_translation) { +void Transform2D::translate_local(const Vector2 &p_translation) { columns[2] += basis_xform(p_translation); } @@ -235,9 +235,9 @@ Transform2D Transform2D::untranslated() const { return copy; } -Transform2D Transform2D::translated(const Vector2 &p_offset) const { +Transform2D Transform2D::translated_local(const Vector2 &p_offset) const { Transform2D copy = *this; - copy.translate(p_offset); + copy.translate_local(p_offset); return copy; } diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 72d34a5d4c..e64d050f0c 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -74,8 +74,8 @@ struct _NO_DISCARD_ Transform2D { void scale(const Size2 &p_scale); void scale_basis(const Size2 &p_scale); - void translate(const real_t p_tx, const real_t p_ty); - void translate(const Vector2 &p_translation); + void translate_local(const real_t p_tx, const real_t p_ty); + void translate_local(const Vector2 &p_translation); real_t basis_determinant() const; @@ -87,7 +87,7 @@ struct _NO_DISCARD_ Transform2D { Transform2D scaled(const Size2 &p_scale) const; Transform2D basis_scaled(const Size2 &p_scale) const; - Transform2D translated(const Vector2 &p_offset) const; + Transform2D translated_local(const Vector2 &p_offset) const; Transform2D rotated(const real_t p_angle) const; Transform2D untranslated() const; diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index 76b31daa76..c497a276f3 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -70,17 +70,23 @@ void Transform3D::rotate_basis(const Vector3 &p_axis, real_t p_angle) { } Transform3D Transform3D::looking_at(const Vector3 &p_target, const Vector3 &p_up) const { +#ifdef MATH_CHECKS + ERR_FAIL_COND_V_MSG(origin.is_equal_approx(p_target), Transform3D(), "The transform's origin and target can't be equal."); +#endif Transform3D t = *this; t.basis = Basis::looking_at(p_target - origin, p_up); return t; } void Transform3D::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { +#ifdef MATH_CHECKS + ERR_FAIL_COND_MSG(p_eye.is_equal_approx(p_target), "The eye and target vectors can't be equal."); +#endif basis = Basis::looking_at(p_target - p_eye, p_up); origin = p_eye; } -Transform3D Transform3D::sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const { +Transform3D Transform3D::spherical_interpolate_with(const Transform3D &p_transform, real_t p_c) const { /* not sure if very "efficient" but good enough? */ Transform3D interp; @@ -123,19 +129,19 @@ void Transform3D::scale_basis(const Vector3 &p_scale) { basis.scale(p_scale); } -void Transform3D::translate(real_t p_tx, real_t p_ty, real_t p_tz) { - translate(Vector3(p_tx, p_ty, p_tz)); +void Transform3D::translate_local(real_t p_tx, real_t p_ty, real_t p_tz) { + translate_local(Vector3(p_tx, p_ty, p_tz)); } -void Transform3D::translate(const Vector3 &p_translation) { +void Transform3D::translate_local(const Vector3 &p_translation) { for (int i = 0; i < 3; i++) { origin[i] += basis[i].dot(p_translation); } } -Transform3D Transform3D::translated(const Vector3 &p_translation) const { +Transform3D Transform3D::translated_local(const Vector3 &p_translation) const { Transform3D t = *this; - t.translate(p_translation); + t.translate_local(p_translation); return t; } diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index 25832434cd..1f8026043f 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -56,9 +56,9 @@ struct _NO_DISCARD_ Transform3D { void scale(const Vector3 &p_scale); Transform3D scaled(const Vector3 &p_scale) const; void scale_basis(const Vector3 &p_scale); - void translate(real_t p_tx, real_t p_ty, real_t p_tz); - void translate(const Vector3 &p_translation); - Transform3D translated(const Vector3 &p_translation) const; + void translate_local(real_t p_tx, real_t p_ty, real_t p_tz); + void translate_local(const Vector3 &p_translation); + Transform3D translated_local(const Vector3 &p_translation) const; const Basis &get_basis() const { return basis; } void set_basis(const Basis &p_basis) { basis = p_basis; } @@ -100,7 +100,7 @@ struct _NO_DISCARD_ Transform3D { void operator*=(const real_t p_val); Transform3D operator*(const real_t p_val) const; - Transform3D sphere_interpolate_with(const Transform3D &p_transform, real_t p_c) const; + Transform3D spherical_interpolate_with(const Transform3D &p_transform, real_t p_c) const; Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; _FORCE_INLINE_ Transform3D inverse_xform(const Transform3D &t) const { diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp new file mode 100644 index 0000000000..ed42d8bfb9 --- /dev/null +++ b/core/math/vector4.cpp @@ -0,0 +1,122 @@ +/*************************************************************************/ +/* vector4.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "vector4.h" + +#include "core/math/basis.h" +#include "core/string/print_string.h" + +bool Vector4::is_equal_approx(const Vector4 &p_vec4) const { + return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w); +} + +real_t Vector4::length() const { + return Math::sqrt(length_squared()); +} + +void Vector4::normalize() { + *this /= length(); +} + +Vector4 Vector4::normalized() const { + return *this / length(); +} + +bool Vector4::is_normalized() const { + return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); // Use less epsilon. +} + +Vector4 Vector4::abs() const { + return Vector4(Math::abs(x), Math::abs(y), Math::abs(z), Math::abs(w)); +} + +Vector4 Vector4::sign() const { + return Vector4(SIGN(x), SIGN(y), SIGN(z), SIGN(w)); +} + +Vector4 Vector4::floor() const { + return Vector4(Math::floor(x), Math::floor(y), Math::floor(z), Math::floor(w)); +} + +Vector4 Vector4::ceil() const { + return Vector4(Math::ceil(x), Math::ceil(y), Math::ceil(z), Math::ceil(w)); +} + +Vector4 Vector4::round() const { + return Vector4(Math::round(x), Math::round(y), Math::round(z), Math::round(w)); +} + +Vector4 Vector4::lerp(const Vector4 &p_to, const real_t p_weight) const { + return Vector4( + x + (p_weight * (p_to.x - x)), + y + (p_weight * (p_to.y - y)), + z + (p_weight * (p_to.z - z)), + w + (p_weight * (p_to.w - w))); +} + +Vector4 Vector4::inverse() const { + return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w); +} + +Vector4::Axis Vector4::min_axis_index() const { + uint32_t min_index = 0; + real_t min_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) < min_value) { + min_index = i; + min_value = operator[](i); + } + } + return Vector4::Axis(min_index); +} + +Vector4::Axis Vector4::max_axis_index() const { + uint32_t max_index = 0; + real_t max_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) > max_value) { + max_index = i; + max_value = operator[](i); + } + } + return Vector4::Axis(max_index); +} + +Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const { + return Vector4( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y), + CLAMP(z, p_min.z, p_max.z), + CLAMP(w, p_min.w, p_max.w)); +} + +Vector4::operator String() const { + return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")"; +} diff --git a/core/math/vector4.h b/core/math/vector4.h new file mode 100644 index 0000000000..37ddb509d6 --- /dev/null +++ b/core/math/vector4.h @@ -0,0 +1,283 @@ +/*************************************************************************/ +/* vector4.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 VECTOR4_H +#define VECTOR4_H + +#include "core/math/math_defs.h" +#include "core/math/math_funcs.h" +#include "core/math/vector3.h" +#include "core/string/ustring.h" + +struct _NO_DISCARD_ Vector4 { + enum Axis { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_W, + }; + + union { + struct { + real_t x; + real_t y; + real_t z; + real_t w; + }; + real_t components[4] = { 0, 0, 0, 0 }; + }; + + _FORCE_INLINE_ real_t &operator[](const int p_axis) { + DEV_ASSERT((unsigned int)p_axis < 4); + return components[p_axis]; + } + _FORCE_INLINE_ const real_t &operator[](const int p_axis) const { + DEV_ASSERT((unsigned int)p_axis < 4); + return components[p_axis]; + } + _FORCE_INLINE_ real_t length_squared() const; + bool is_equal_approx(const Vector4 &p_vec4) const; + real_t length() const; + void normalize(); + Vector4 normalized() const; + bool is_normalized() const; + + Vector4 abs() const; + Vector4 sign() const; + Vector4 floor() const; + Vector4 ceil() const; + Vector4 round() const; + Vector4 lerp(const Vector4 &p_to, const real_t p_weight) const; + + Vector4::Axis min_axis_index() const; + Vector4::Axis max_axis_index() const; + Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const; + + Vector4 inverse() const; + _FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const; + + _FORCE_INLINE_ void operator+=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator-=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator*=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator/=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator*=(const real_t &s); + _FORCE_INLINE_ void operator/=(const real_t &s); + _FORCE_INLINE_ Vector4 operator+(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator-(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator*(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator/(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator-() const; + _FORCE_INLINE_ Vector4 operator*(const real_t &s) const; + _FORCE_INLINE_ Vector4 operator/(const real_t &s) const; + + _FORCE_INLINE_ bool operator==(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator!=(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator>(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator<(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator>=(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator<=(const Vector4 &p_vec4) const; + + operator String() const; + + _FORCE_INLINE_ Vector4() {} + + _FORCE_INLINE_ Vector4(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : + x(p_x), + y(p_y), + z(p_z), + w(p_w) { + } + + Vector4(const Vector4 &p_vec4) : + x(p_vec4.x), + y(p_vec4.y), + z(p_vec4.z), + w(p_vec4.w) { + } + + void operator=(const Vector4 &p_vec4) { + x = p_vec4.x; + y = p_vec4.y; + z = p_vec4.z; + w = p_vec4.w; + } +}; + +real_t Vector4::dot(const Vector4 &p_vec4) const { + return x * p_vec4.x + y * p_vec4.y + z * p_vec4.z + w * p_vec4.w; +} + +real_t Vector4::length_squared() const { + return dot(*this); +} + +void Vector4::operator+=(const Vector4 &p_vec4) { + x += p_vec4.x; + y += p_vec4.y; + z += p_vec4.z; + w += p_vec4.w; +} + +void Vector4::operator-=(const Vector4 &p_vec4) { + x -= p_vec4.x; + y -= p_vec4.y; + z -= p_vec4.z; + w -= p_vec4.w; +} + +void Vector4::operator*=(const Vector4 &p_vec4) { + x *= p_vec4.x; + y *= p_vec4.y; + z *= p_vec4.z; + w *= p_vec4.w; +} + +void Vector4::operator/=(const Vector4 &p_vec4) { + x /= p_vec4.x; + y /= p_vec4.y; + z /= p_vec4.z; + w /= p_vec4.w; +} +void Vector4::operator*=(const real_t &s) { + x *= s; + y *= s; + z *= s; + w *= s; +} + +void Vector4::operator/=(const real_t &s) { + *this *= 1.0f / s; +} + +Vector4 Vector4::operator+(const Vector4 &p_vec4) const { + return Vector4(x + p_vec4.x, y + p_vec4.y, z + p_vec4.z, w + p_vec4.w); +} + +Vector4 Vector4::operator-(const Vector4 &p_vec4) const { + return Vector4(x - p_vec4.x, y - p_vec4.y, z - p_vec4.z, w - p_vec4.w); +} + +Vector4 Vector4::operator*(const Vector4 &p_vec4) const { + return Vector4(x * p_vec4.x, y * p_vec4.y, z * p_vec4.z, w * p_vec4.w); +} + +Vector4 Vector4::operator/(const Vector4 &p_vec4) const { + return Vector4(x / p_vec4.x, y / p_vec4.y, z / p_vec4.z, w / p_vec4.w); +} + +Vector4 Vector4::operator-() const { + return Vector4(x, y, z, w); +} + +Vector4 Vector4::operator*(const real_t &s) const { + return Vector4(x * s, y * s, z * s, w * s); +} + +Vector4 Vector4::operator/(const real_t &s) const { + return *this * (1.0f / s); +} + +bool Vector4::operator==(const Vector4 &p_vec4) const { + return x == p_vec4.x && y == p_vec4.y && z == p_vec4.z && w == p_vec4.w; +} + +bool Vector4::operator!=(const Vector4 &p_vec4) const { + return x != p_vec4.x || y != p_vec4.y || z != p_vec4.z || w != p_vec4.w; +} + +bool Vector4::operator<(const Vector4 &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w < p_v.w; + } + return z < p_v.z; + } + return y < p_v.y; + } + return x < p_v.x; +} + +bool Vector4::operator>(const Vector4 &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w > p_v.w; + } + return z > p_v.z; + } + return y > p_v.y; + } + return x > p_v.x; +} + +bool Vector4::operator<=(const Vector4 &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w <= p_v.w; + } + return z < p_v.z; + } + return y < p_v.y; + } + return x < p_v.x; +} + +bool Vector4::operator>=(const Vector4 &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w >= p_v.w; + } + return z > p_v.z; + } + return y > p_v.y; + } + return x > p_v.x; +} + +_FORCE_INLINE_ Vector4 operator*(const float p_scalar, const Vector4 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector4 operator*(const double p_scalar, const Vector4 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector4 operator*(const int32_t p_scalar, const Vector4 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector4 operator*(const int64_t p_scalar, const Vector4 &p_vec) { + return p_vec * p_scalar; +} + +#endif // VECTOR4_H diff --git a/core/templates/thread_work_pool.cpp b/core/math/vector4i.cpp index a75fd06b9b..8c571b02e3 100644 --- a/core/templates/thread_work_pool.cpp +++ b/core/math/vector4i.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* thread_work_pool.cpp */ +/* vector4i.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,54 +28,64 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "thread_work_pool.h" +#include "vector4i.h" -#include "core/os/os.h" +#include "core/math/vector4.h" +#include "core/string/ustring.h" -void ThreadWorkPool::_thread_function(void *p_user) { - ThreadData *thread = static_cast<ThreadData *>(p_user); - while (true) { - thread->start.wait(); - if (thread->exit.load()) { - break; - } - thread->work->work(); - thread->completed.post(); - } +void Vector4i::set_axis(const int p_axis, const int32_t p_value) { + ERR_FAIL_INDEX(p_axis, 4); + coord[p_axis] = p_value; } -void ThreadWorkPool::init(int p_thread_count) { - ERR_FAIL_COND(threads != nullptr); - if (p_thread_count < 0) { - p_thread_count = OS::get_singleton()->get_default_thread_pool_size(); - } - - thread_count = p_thread_count; - threads = memnew_arr(ThreadData, thread_count); +int32_t Vector4i::get_axis(const int p_axis) const { + ERR_FAIL_INDEX_V(p_axis, 4, 0); + return operator[](p_axis); +} - for (uint32_t i = 0; i < thread_count; i++) { - threads[i].exit.store(false); - threads[i].thread.start(&ThreadWorkPool::_thread_function, &threads[i]); +Vector4i::Axis Vector4i::min_axis_index() const { + uint32_t min_index = 0; + int32_t min_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) < min_value) { + min_index = i; + min_value = operator[](i); + } } + return Vector4i::Axis(min_index); } -void ThreadWorkPool::finish() { - if (threads == nullptr) { - return; +Vector4i::Axis Vector4i::max_axis_index() const { + uint32_t max_index = 0; + int32_t max_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) > max_value) { + max_index = i; + max_value = operator[](i); + } } + return Vector4i::Axis(max_index); +} - for (uint32_t i = 0; i < thread_count; i++) { - threads[i].exit.store(true); - threads[i].start.post(); - } - for (uint32_t i = 0; i < thread_count; i++) { - threads[i].thread.wait_to_finish(); - } +Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const { + return Vector4i( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y), + CLAMP(z, p_min.z, p_max.z), + CLAMP(w, p_min.w, p_max.w)); +} + +Vector4i::operator String() const { + return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")"; +} - memdelete_arr(threads); - threads = nullptr; +Vector4i::operator Vector4() const { + return Vector4(x, y, z, w); } -ThreadWorkPool::~ThreadWorkPool() { - finish(); +Vector4i::Vector4i(const Vector4 &p_vec4) { + x = p_vec4.x; + y = p_vec4.y; + z = p_vec4.z; + w = p_vec4.w; } diff --git a/core/math/vector4i.h b/core/math/vector4i.h new file mode 100644 index 0000000000..37d905878f --- /dev/null +++ b/core/math/vector4i.h @@ -0,0 +1,338 @@ +/*************************************************************************/ +/* vector4i.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 VECTOR4I_H +#define VECTOR4I_H + +#include "core/error/error_macros.h" +#include "core/math/math_funcs.h" + +class String; +struct Vector4; + +struct _NO_DISCARD_ Vector4i { + enum Axis { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_W, + }; + + union { + struct { + int32_t x; + int32_t y; + int32_t z; + int32_t w; + }; + + int32_t coord[4] = { 0 }; + }; + + _FORCE_INLINE_ const int32_t &operator[](const int p_axis) const { + DEV_ASSERT((unsigned int)p_axis < 4); + return coord[p_axis]; + } + + _FORCE_INLINE_ int32_t &operator[](const int p_axis) { + DEV_ASSERT((unsigned int)p_axis < 4); + return coord[p_axis]; + } + + void set_axis(const int p_axis, const int32_t p_value); + int32_t get_axis(const int p_axis) const; + + Vector4i::Axis min_axis_index() const; + Vector4i::Axis max_axis_index() const; + + _FORCE_INLINE_ int64_t length_squared() const; + _FORCE_INLINE_ double length() const; + + _FORCE_INLINE_ void zero(); + + _FORCE_INLINE_ Vector4i abs() const; + _FORCE_INLINE_ Vector4i sign() const; + Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const; + + /* Operators */ + + _FORCE_INLINE_ Vector4i &operator+=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator+(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator-=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator-(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator*=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator*(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator/=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator/(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator%=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator%(const Vector4i &p_v) const; + + _FORCE_INLINE_ Vector4i &operator*=(const int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator*(const int32_t p_scalar) const; + _FORCE_INLINE_ Vector4i &operator/=(const int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator/(const int32_t p_scalar) const; + _FORCE_INLINE_ Vector4i &operator%=(const int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator%(const int32_t p_scalar) const; + + _FORCE_INLINE_ Vector4i operator-() const; + + _FORCE_INLINE_ bool operator==(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator!=(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator<(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator<=(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator>(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator>=(const Vector4i &p_v) const; + + operator String() const; + operator Vector4() const; + + _FORCE_INLINE_ Vector4i() {} + Vector4i(const Vector4 &p_vec4); + _FORCE_INLINE_ Vector4i(const int32_t p_x, const int32_t p_y, const int32_t p_z, const int32_t p_w) { + x = p_x; + y = p_y; + z = p_z; + w = p_w; + } +}; + +int64_t Vector4i::length_squared() const { + return x * (int64_t)x + y * (int64_t)y + z * (int64_t)z + w * (int64_t)w; +} + +double Vector4i::length() const { + return Math::sqrt((double)length_squared()); +} + +Vector4i Vector4i::abs() const { + return Vector4i(ABS(x), ABS(y), ABS(z), ABS(w)); +} + +Vector4i Vector4i::sign() const { + return Vector4i(SIGN(x), SIGN(y), SIGN(z), SIGN(w)); +} + +/* Operators */ + +Vector4i &Vector4i::operator+=(const Vector4i &p_v) { + x += p_v.x; + y += p_v.y; + z += p_v.z; + w += p_v.w; + return *this; +} + +Vector4i Vector4i::operator+(const Vector4i &p_v) const { + return Vector4i(x + p_v.x, y + p_v.y, z + p_v.z, w + p_v.w); +} + +Vector4i &Vector4i::operator-=(const Vector4i &p_v) { + x -= p_v.x; + y -= p_v.y; + z -= p_v.z; + w -= p_v.w; + return *this; +} + +Vector4i Vector4i::operator-(const Vector4i &p_v) const { + return Vector4i(x - p_v.x, y - p_v.y, z - p_v.z, w - p_v.w); +} + +Vector4i &Vector4i::operator*=(const Vector4i &p_v) { + x *= p_v.x; + y *= p_v.y; + z *= p_v.z; + w *= p_v.w; + return *this; +} + +Vector4i Vector4i::operator*(const Vector4i &p_v) const { + return Vector4i(x * p_v.x, y * p_v.y, z * p_v.z, w * p_v.w); +} + +Vector4i &Vector4i::operator/=(const Vector4i &p_v) { + x /= p_v.x; + y /= p_v.y; + z /= p_v.z; + w /= p_v.w; + return *this; +} + +Vector4i Vector4i::operator/(const Vector4i &p_v) const { + return Vector4i(x / p_v.x, y / p_v.y, z / p_v.z, w / p_v.w); +} + +Vector4i &Vector4i::operator%=(const Vector4i &p_v) { + x %= p_v.x; + y %= p_v.y; + z %= p_v.z; + w %= p_v.w; + return *this; +} + +Vector4i Vector4i::operator%(const Vector4i &p_v) const { + return Vector4i(x % p_v.x, y % p_v.y, z % p_v.z, w % p_v.w); +} + +Vector4i &Vector4i::operator*=(const int32_t p_scalar) { + x *= p_scalar; + y *= p_scalar; + z *= p_scalar; + w *= p_scalar; + return *this; +} + +Vector4i Vector4i::operator*(const int32_t p_scalar) const { + return Vector4i(x * p_scalar, y * p_scalar, z * p_scalar, w * p_scalar); +} + +// Multiplication operators required to workaround issues with LLVM using implicit conversion. + +_FORCE_INLINE_ Vector4i operator*(const int32_t p_scalar, const Vector4i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector4i operator*(const int64_t p_scalar, const Vector4i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector4i operator*(const float p_scalar, const Vector4i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector4i operator*(const double p_scalar, const Vector4i &p_vector) { + return p_vector * p_scalar; +} + +Vector4i &Vector4i::operator/=(const int32_t p_scalar) { + x /= p_scalar; + y /= p_scalar; + z /= p_scalar; + w /= p_scalar; + return *this; +} + +Vector4i Vector4i::operator/(const int32_t p_scalar) const { + return Vector4i(x / p_scalar, y / p_scalar, z / p_scalar, w / p_scalar); +} + +Vector4i &Vector4i::operator%=(const int32_t p_scalar) { + x %= p_scalar; + y %= p_scalar; + z %= p_scalar; + w %= p_scalar; + return *this; +} + +Vector4i Vector4i::operator%(const int32_t p_scalar) const { + return Vector4i(x % p_scalar, y % p_scalar, z % p_scalar, w % p_scalar); +} + +Vector4i Vector4i::operator-() const { + return Vector4i(-x, -y, -z, -w); +} + +bool Vector4i::operator==(const Vector4i &p_v) const { + return (x == p_v.x && y == p_v.y && z == p_v.z && w == p_v.w); +} + +bool Vector4i::operator!=(const Vector4i &p_v) const { + return (x != p_v.x || y != p_v.y || z != p_v.z || w != p_v.w); +} + +bool Vector4i::operator<(const Vector4i &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w < p_v.w; + } else { + return z < p_v.z; + } + } else { + return y < p_v.y; + } + } else { + return x < p_v.x; + } +} + +bool Vector4i::operator>(const Vector4i &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w > p_v.w; + } else { + return z > p_v.z; + } + } else { + return y > p_v.y; + } + } else { + return x > p_v.x; + } +} + +bool Vector4i::operator<=(const Vector4i &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w <= p_v.w; + } else { + return z < p_v.z; + } + } else { + return y < p_v.y; + } + } else { + return x < p_v.x; + } +} + +bool Vector4i::operator>=(const Vector4i &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w >= p_v.w; + } else { + return z > p_v.z; + } + } else { + return y > p_v.y; + } + } else { + return x > p_v.x; + } +} + +void Vector4i::zero() { + x = y = z = w = 0; +} + +#endif // VECTOR4I_H diff --git a/core/multiplayer/SCsub b/core/multiplayer/SCsub deleted file mode 100644 index 19a6549225..0000000000 --- a/core/multiplayer/SCsub +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -env.add_source_files(env.core_sources, "*.cpp") diff --git a/core/multiplayer/multiplayer.h b/core/multiplayer/multiplayer.h deleted file mode 100644 index f4c965b0f8..0000000000 --- a/core/multiplayer/multiplayer.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************/ -/* multiplayer.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 MULTIPLAYER_H -#define MULTIPLAYER_H - -#include "core/variant/binder_common.h" - -#include "core/string/string_name.h" - -namespace Multiplayer { - -enum TransferMode { - TRANSFER_MODE_UNRELIABLE, - TRANSFER_MODE_UNRELIABLE_ORDERED, - TRANSFER_MODE_RELIABLE -}; - -enum RPCMode { - RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) - RPC_MODE_ANY_PEER, // Any peer can call this RPC - RPC_MODE_AUTHORITY, // Only the node's multiplayer authority (server by default) can call this RPC -}; - -struct RPCConfig { - StringName name; - RPCMode rpc_mode = RPC_MODE_DISABLED; - bool call_local = false; - TransferMode transfer_mode = TRANSFER_MODE_RELIABLE; - int channel = 0; - - bool operator==(RPCConfig const &p_other) const { - return name == p_other.name; - } -}; - -struct SortRPCConfig { - StringName::AlphCompare compare; - bool operator()(const RPCConfig &p_a, const RPCConfig &p_b) const { - return compare(p_a.name, p_b.name); - } -}; - -}; // namespace Multiplayer - -// This is needed for proper docs generation (i.e. not "Multiplayer."-prefixed). -typedef Multiplayer::RPCMode RPCMode; -typedef Multiplayer::TransferMode TransferMode; - -VARIANT_ENUM_CAST(RPCMode); -VARIANT_ENUM_CAST(TransferMode); - -#endif // MULTIPLAYER_H diff --git a/core/multiplayer/multiplayer_api.cpp b/core/multiplayer/multiplayer_api.cpp deleted file mode 100644 index 9605647b3f..0000000000 --- a/core/multiplayer/multiplayer_api.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/*************************************************************************/ -/* multiplayer_api.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 "multiplayer_api.h" - -#include "core/debugger/engine_debugger.h" -#include "core/io/marshalls.h" - -#include <stdint.h> - -#ifdef DEBUG_ENABLED -#include "core/os/os.h" -#endif - -MultiplayerReplicationInterface *(*MultiplayerAPI::create_default_replication_interface)(MultiplayerAPI *p_multiplayer) = nullptr; -MultiplayerRPCInterface *(*MultiplayerAPI::create_default_rpc_interface)(MultiplayerAPI *p_multiplayer) = nullptr; -MultiplayerCacheInterface *(*MultiplayerAPI::create_default_cache_interface)(MultiplayerAPI *p_multiplayer) = nullptr; - -#ifdef DEBUG_ENABLED -void MultiplayerAPI::profile_bandwidth(const String &p_inout, int p_size) { - if (EngineDebugger::is_profiling("multiplayer")) { - Array values; - values.push_back(p_inout); - values.push_back(OS::get_singleton()->get_ticks_msec()); - values.push_back(p_size); - EngineDebugger::profiler_add_frame_data("multiplayer", values); - } -} -#endif - -void MultiplayerAPI::poll() { - if (!multiplayer_peer.is_valid() || multiplayer_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED) { - return; - } - - multiplayer_peer->poll(); - - if (!multiplayer_peer.is_valid()) { // It's possible that polling might have resulted in a disconnection, so check here. - return; - } - - while (multiplayer_peer->get_available_packet_count()) { - int sender = multiplayer_peer->get_packet_peer(); - const uint8_t *packet; - int len; - - Error err = multiplayer_peer->get_packet(&packet, len); - if (err != OK) { - ERR_PRINT("Error getting packet!"); - return; // Something is wrong! - } - - remote_sender_id = sender; - _process_packet(sender, packet, len); - remote_sender_id = 0; - - if (!multiplayer_peer.is_valid()) { - return; // It's also possible that a packet or RPC caused a disconnection, so also check here. - } - } - replicator->on_network_process(); -} - -void MultiplayerAPI::clear() { - connected_peers.clear(); - packet_cache.clear(); - cache->clear(); -} - -void MultiplayerAPI::set_root_path(const NodePath &p_path) { - ERR_FAIL_COND_MSG(!p_path.is_absolute() && !p_path.is_empty(), "MultiplayerAPI root path must be absolute."); - root_path = p_path; -} - -NodePath MultiplayerAPI::get_root_path() const { - return root_path; -} - -void MultiplayerAPI::set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) { - if (p_peer == multiplayer_peer) { - return; // Nothing to do - } - - ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED, - "Supplied MultiplayerPeer must be connecting or connected."); - - if (multiplayer_peer.is_valid()) { - multiplayer_peer->disconnect("peer_connected", callable_mp(this, &MultiplayerAPI::_add_peer)); - multiplayer_peer->disconnect("peer_disconnected", callable_mp(this, &MultiplayerAPI::_del_peer)); - multiplayer_peer->disconnect("connection_succeeded", callable_mp(this, &MultiplayerAPI::_connected_to_server)); - multiplayer_peer->disconnect("connection_failed", callable_mp(this, &MultiplayerAPI::_connection_failed)); - multiplayer_peer->disconnect("server_disconnected", callable_mp(this, &MultiplayerAPI::_server_disconnected)); - clear(); - } - - multiplayer_peer = p_peer; - - if (multiplayer_peer.is_valid()) { - multiplayer_peer->connect("peer_connected", callable_mp(this, &MultiplayerAPI::_add_peer)); - multiplayer_peer->connect("peer_disconnected", callable_mp(this, &MultiplayerAPI::_del_peer)); - multiplayer_peer->connect("connection_succeeded", callable_mp(this, &MultiplayerAPI::_connected_to_server)); - multiplayer_peer->connect("connection_failed", callable_mp(this, &MultiplayerAPI::_connection_failed)); - multiplayer_peer->connect("server_disconnected", callable_mp(this, &MultiplayerAPI::_server_disconnected)); - } - replicator->on_reset(); -} - -Ref<MultiplayerPeer> MultiplayerAPI::get_multiplayer_peer() const { - return multiplayer_peer; -} - -void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) { - ERR_FAIL_COND_MSG(root_path.is_empty(), "Multiplayer root was not initialized. If you are using custom multiplayer, remember to set the root path via MultiplayerAPI.set_root_path before using it."); - ERR_FAIL_COND_MSG(p_packet_len < 1, "Invalid packet received. Size too small."); - -#ifdef DEBUG_ENABLED - profile_bandwidth("in", p_packet_len); -#endif - - // Extract the `packet_type` from the LSB three bits: - uint8_t packet_type = p_packet[0] & CMD_MASK; - - switch (packet_type) { - case NETWORK_COMMAND_SIMPLIFY_PATH: { - cache->process_simplify_path(p_from, p_packet, p_packet_len); - } break; - - case NETWORK_COMMAND_CONFIRM_PATH: { - cache->process_confirm_path(p_from, p_packet, p_packet_len); - } break; - - case NETWORK_COMMAND_REMOTE_CALL: { - rpc->process_rpc(p_from, p_packet, p_packet_len); - } break; - - case NETWORK_COMMAND_RAW: { - _process_raw(p_from, p_packet, p_packet_len); - } break; - case NETWORK_COMMAND_SPAWN: { - replicator->on_spawn_receive(p_from, p_packet, p_packet_len); - } break; - case NETWORK_COMMAND_DESPAWN: { - replicator->on_despawn_receive(p_from, p_packet, p_packet_len); - } break; - case NETWORK_COMMAND_SYNC: { - replicator->on_sync_receive(p_from, p_packet, p_packet_len); - } break; - } -} - -// The variant is compressed and encoded; The first byte contains all the meta -// information and the format is: -// - The first LSB 5 bits are used for the variant type. -// - The next two bits are used to store the encoding mode. -// - The most significant is used to store the boolean value. -#define VARIANT_META_TYPE_MASK 0x1F -#define VARIANT_META_EMODE_MASK 0x60 -#define VARIANT_META_BOOL_MASK 0x80 -#define ENCODE_8 0 << 5 -#define ENCODE_16 1 << 5 -#define ENCODE_32 2 << 5 -#define ENCODE_64 3 << 5 -Error MultiplayerAPI::encode_and_compress_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_allow_object_decoding) { - // Unreachable because `VARIANT_MAX` == 27 and `ENCODE_VARIANT_MASK` == 31 - CRASH_COND(p_variant.get_type() > VARIANT_META_TYPE_MASK); - - uint8_t *buf = r_buffer; - r_len = 0; - uint8_t encode_mode = 0; - - switch (p_variant.get_type()) { - case Variant::BOOL: { - if (buf) { - // We still have 1 free bit in the meta, so let's use it. - buf[0] = (p_variant.operator bool()) ? (1 << 7) : 0; - buf[0] |= encode_mode | p_variant.get_type(); - } - r_len += 1; - } break; - case Variant::INT: { - if (buf) { - // Reserve the first byte for the meta. - buf += 1; - } - r_len += 1; - int64_t val = p_variant; - if (val <= (int64_t)INT8_MAX && val >= (int64_t)INT8_MIN) { - // Use 8 bit - encode_mode = ENCODE_8; - if (buf) { - buf[0] = val; - } - r_len += 1; - } else if (val <= (int64_t)INT16_MAX && val >= (int64_t)INT16_MIN) { - // Use 16 bit - encode_mode = ENCODE_16; - if (buf) { - encode_uint16(val, buf); - } - r_len += 2; - } else if (val <= (int64_t)INT32_MAX && val >= (int64_t)INT32_MIN) { - // Use 32 bit - encode_mode = ENCODE_32; - if (buf) { - encode_uint32(val, buf); - } - r_len += 4; - } else { - // Use 64 bit - encode_mode = ENCODE_64; - if (buf) { - encode_uint64(val, buf); - } - r_len += 8; - } - // Store the meta - if (buf) { - buf -= 1; - buf[0] = encode_mode | p_variant.get_type(); - } - } break; - default: - // Any other case is not yet compressed. - Error err = encode_variant(p_variant, r_buffer, r_len, p_allow_object_decoding); - if (err != OK) { - return err; - } - if (r_buffer) { - // The first byte is not used by the marshalling, so store the type - // so we know how to decompress and decode this variant. - r_buffer[0] = p_variant.get_type(); - } - } - - return OK; -} - -Error MultiplayerAPI::decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding) { - const uint8_t *buf = p_buffer; - int len = p_len; - - ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); - uint8_t type = buf[0] & VARIANT_META_TYPE_MASK; - uint8_t encode_mode = buf[0] & VARIANT_META_EMODE_MASK; - - ERR_FAIL_COND_V(type >= Variant::VARIANT_MAX, ERR_INVALID_DATA); - - switch (type) { - case Variant::BOOL: { - bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0; - r_variant = val; - if (r_len) { - *r_len = 1; - } - } break; - case Variant::INT: { - buf += 1; - len -= 1; - if (r_len) { - *r_len = 1; - } - if (encode_mode == ENCODE_8) { - // 8 bits. - ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); - int8_t val = buf[0]; - r_variant = val; - if (r_len) { - (*r_len) += 1; - } - } else if (encode_mode == ENCODE_16) { - // 16 bits. - ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA); - int16_t val = decode_uint16(buf); - r_variant = val; - if (r_len) { - (*r_len) += 2; - } - } else if (encode_mode == ENCODE_32) { - // 32 bits. - ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); - int32_t val = decode_uint32(buf); - r_variant = val; - if (r_len) { - (*r_len) += 4; - } - } else { - // 64 bits. - ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); - int64_t val = decode_uint64(buf); - r_variant = val; - if (r_len) { - (*r_len) += 8; - } - } - } break; - default: - Error err = decode_variant(r_variant, p_buffer, p_len, r_len, p_allow_object_decoding); - if (err != OK) { - return err; - } - } - - return OK; -} - -Error MultiplayerAPI::encode_and_compress_variants(const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw, bool p_allow_object_decoding) { - r_len = 0; - int size = 0; - - if (p_count == 0) { - if (r_raw) { - *r_raw = true; - } - return OK; - } - - // Try raw encoding optimization. - if (r_raw && p_count == 1) { - *r_raw = false; - const Variant &v = *(p_variants[0]); - if (v.get_type() == Variant::PACKED_BYTE_ARRAY) { - *r_raw = true; - const PackedByteArray pba = v; - if (p_buffer) { - memcpy(p_buffer, pba.ptr(), pba.size()); - } - r_len += pba.size(); - } else { - encode_and_compress_variant(v, p_buffer, size, p_allow_object_decoding); - r_len += size; - } - return OK; - } - - // Regular encoding. - for (int i = 0; i < p_count; i++) { - const Variant &v = *(p_variants[i]); - encode_and_compress_variant(v, p_buffer ? p_buffer + r_len : nullptr, size, p_allow_object_decoding); - r_len += size; - } - return OK; -} - -Error MultiplayerAPI::decode_and_decompress_variants(Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw, bool p_allow_object_decoding) { - r_len = 0; - int argc = r_variants.size(); - if (argc == 0 && p_raw) { - return OK; - } - ERR_FAIL_COND_V(p_raw && argc != 1, ERR_INVALID_DATA); - if (p_raw) { - r_len = p_len; - PackedByteArray pba; - pba.resize(p_len); - memcpy(pba.ptrw(), p_buffer, p_len); - r_variants.write[0] = pba; - return OK; - } - - Vector<Variant> args; - Vector<const Variant *> argp; - args.resize(argc); - - for (int i = 0; i < argc; i++) { - ERR_FAIL_COND_V_MSG(r_len >= p_len, ERR_INVALID_DATA, "Invalid packet received. Size too small."); - - int vlen; - Error err = MultiplayerAPI::decode_and_decompress_variant(r_variants.write[i], &p_buffer[r_len], p_len - r_len, &vlen, p_allow_object_decoding); - ERR_FAIL_COND_V_MSG(err != OK, err, "Invalid packet received. Unable to decode state variable."); - r_len += vlen; - } - return OK; -} - -void MultiplayerAPI::_add_peer(int p_id) { - connected_peers.insert(p_id); - cache->on_peer_change(p_id, true); - replicator->on_peer_change(p_id, true); - emit_signal(SNAME("peer_connected"), p_id); -} - -void MultiplayerAPI::_del_peer(int p_id) { - replicator->on_peer_change(p_id, false); - cache->on_peer_change(p_id, false); - connected_peers.erase(p_id); - emit_signal(SNAME("peer_disconnected"), p_id); -} - -void MultiplayerAPI::_connected_to_server() { - emit_signal(SNAME("connected_to_server")); -} - -void MultiplayerAPI::_connection_failed() { - emit_signal(SNAME("connection_failed")); -} - -void MultiplayerAPI::_server_disconnected() { - replicator->on_reset(); - emit_signal(SNAME("server_disconnected")); -} - -Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, Multiplayer::TransferMode p_mode, int p_channel) { - ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet."); - ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no multiplayer peer is active."); - ERR_FAIL_COND_V_MSG(multiplayer_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a multiplayer peer which is not connected."); - - if (packet_cache.size() < p_data.size() + 1) { - packet_cache.resize(p_data.size() + 1); - } - - const uint8_t *r = p_data.ptr(); - packet_cache.write[0] = NETWORK_COMMAND_RAW; - memcpy(&packet_cache.write[1], &r[0], p_data.size()); - - multiplayer_peer->set_target_peer(p_to); - multiplayer_peer->set_transfer_channel(p_channel); - multiplayer_peer->set_transfer_mode(p_mode); - - return multiplayer_peer->put_packet(packet_cache.ptr(), p_data.size() + 1); -} - -void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) { - ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small."); - - Vector<uint8_t> out; - int len = p_packet_len - 1; - out.resize(len); - { - uint8_t *w = out.ptrw(); - memcpy(&w[0], &p_packet[1], len); - } - emit_signal(SNAME("peer_packet"), p_from, out); -} - -bool MultiplayerAPI::is_cache_confirmed(NodePath p_path, int p_peer) { - return cache->is_cache_confirmed(p_path, p_peer); -} - -bool MultiplayerAPI::send_object_cache(Object *p_obj, NodePath p_path, int p_peer_id, int &r_id) { - return cache->send_object_cache(p_obj, p_path, p_peer_id, r_id); -} - -Object *MultiplayerAPI::get_cached_object(int p_from, uint32_t p_cache_id) { - return cache->get_cached_object(p_from, p_cache_id); -} - -int MultiplayerAPI::get_unique_id() const { - ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), 0, "No multiplayer peer is assigned. Unable to get unique ID."); - return multiplayer_peer->get_unique_id(); -} - -bool MultiplayerAPI::is_server() const { - return multiplayer_peer.is_valid() && multiplayer_peer->is_server(); -} - -void MultiplayerAPI::set_refuse_new_connections(bool p_refuse) { - ERR_FAIL_COND_MSG(!multiplayer_peer.is_valid(), "No multiplayer peer is assigned. Unable to set 'refuse_new_connections'."); - multiplayer_peer->set_refuse_new_connections(p_refuse); -} - -bool MultiplayerAPI::is_refusing_new_connections() const { - ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), false, "No multiplayer peer is assigned. Unable to get 'refuse_new_connections'."); - return multiplayer_peer->is_refusing_new_connections(); -} - -Vector<int> MultiplayerAPI::get_peer_ids() const { - ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), Vector<int>(), "No multiplayer peer is assigned. Assume no peers are connected."); - - Vector<int> ret; - for (const int &E : connected_peers) { - ret.push_back(E); - } - - return ret; -} - -void MultiplayerAPI::set_allow_object_decoding(bool p_enable) { - allow_object_decoding = p_enable; -} - -bool MultiplayerAPI::is_object_decoding_allowed() const { - return allow_object_decoding; -} - -String MultiplayerAPI::get_rpc_md5(const Object *p_obj) const { - return rpc->get_rpc_md5(p_obj); -} - -void MultiplayerAPI::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { - rpc->rpcp(p_obj, p_peer_id, p_method, p_arg, p_argcount); -} - -Error MultiplayerAPI::spawn(Object *p_object, Variant p_config) { - return replicator->on_spawn(p_object, p_config); -} - -Error MultiplayerAPI::despawn(Object *p_object, Variant p_config) { - return replicator->on_despawn(p_object, p_config); -} - -Error MultiplayerAPI::replication_start(Object *p_object, Variant p_config) { - return replicator->on_replication_start(p_object, p_config); -} - -Error MultiplayerAPI::replication_stop(Object *p_object, Variant p_config) { - return replicator->on_replication_stop(p_object, p_config); -} - -void MultiplayerAPI::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_root_path", "path"), &MultiplayerAPI::set_root_path); - ClassDB::bind_method(D_METHOD("get_root_path"), &MultiplayerAPI::get_root_path); - ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode", "channel"), &MultiplayerAPI::send_bytes, DEFVAL(MultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(Multiplayer::TRANSFER_MODE_RELIABLE), DEFVAL(0)); - ClassDB::bind_method(D_METHOD("has_multiplayer_peer"), &MultiplayerAPI::has_multiplayer_peer); - ClassDB::bind_method(D_METHOD("get_multiplayer_peer"), &MultiplayerAPI::get_multiplayer_peer); - ClassDB::bind_method(D_METHOD("set_multiplayer_peer", "peer"), &MultiplayerAPI::set_multiplayer_peer); - ClassDB::bind_method(D_METHOD("get_unique_id"), &MultiplayerAPI::get_unique_id); - ClassDB::bind_method(D_METHOD("is_server"), &MultiplayerAPI::is_server); - ClassDB::bind_method(D_METHOD("get_remote_sender_id"), &MultiplayerAPI::get_remote_sender_id); - ClassDB::bind_method(D_METHOD("poll"), &MultiplayerAPI::poll); - ClassDB::bind_method(D_METHOD("clear"), &MultiplayerAPI::clear); - - ClassDB::bind_method(D_METHOD("get_peers"), &MultiplayerAPI::get_peer_ids); - ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "refuse"), &MultiplayerAPI::set_refuse_new_connections); - ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &MultiplayerAPI::is_refusing_new_connections); - ClassDB::bind_method(D_METHOD("set_allow_object_decoding", "enable"), &MultiplayerAPI::set_allow_object_decoding); - ClassDB::bind_method(D_METHOD("is_object_decoding_allowed"), &MultiplayerAPI::is_object_decoding_allowed); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_connections"), "set_refuse_new_connections", "is_refusing_new_connections"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer_peer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerPeer", PROPERTY_USAGE_NONE), "set_multiplayer_peer", "get_multiplayer_peer"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_path"), "set_root_path", "get_root_path"); - ADD_PROPERTY_DEFAULT("refuse_new_connections", false); - - ADD_SIGNAL(MethodInfo("peer_connected", PropertyInfo(Variant::INT, "id"))); - ADD_SIGNAL(MethodInfo("peer_disconnected", PropertyInfo(Variant::INT, "id"))); - ADD_SIGNAL(MethodInfo("peer_packet", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::PACKED_BYTE_ARRAY, "packet"))); - ADD_SIGNAL(MethodInfo("connected_to_server")); - ADD_SIGNAL(MethodInfo("connection_failed")); - ADD_SIGNAL(MethodInfo("server_disconnected")); -} - -MultiplayerAPI::MultiplayerAPI() { - if (create_default_replication_interface) { - replicator = Ref<MultiplayerReplicationInterface>(create_default_replication_interface(this)); - } else { - replicator.instantiate(); - } - if (create_default_rpc_interface) { - rpc = Ref<MultiplayerRPCInterface>(create_default_rpc_interface(this)); - } else { - rpc.instantiate(); - } - if (create_default_cache_interface) { - cache = Ref<MultiplayerCacheInterface>(create_default_cache_interface(this)); - } else { - cache.instantiate(); - } -} - -MultiplayerAPI::~MultiplayerAPI() { - clear(); -} diff --git a/core/multiplayer/multiplayer_api.h b/core/multiplayer/multiplayer_api.h deleted file mode 100644 index cc7743ccf8..0000000000 --- a/core/multiplayer/multiplayer_api.h +++ /dev/null @@ -1,194 +0,0 @@ -/*************************************************************************/ -/* multiplayer_api.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 MULTIPLAYER_API_H -#define MULTIPLAYER_API_H - -#include "core/multiplayer/multiplayer.h" -#include "core/multiplayer/multiplayer_peer.h" -#include "core/object/ref_counted.h" - -class MultiplayerAPI; - -class MultiplayerReplicationInterface : public RefCounted { - GDCLASS(MultiplayerReplicationInterface, RefCounted); - -public: - virtual void on_peer_change(int p_id, bool p_connected) {} - virtual void on_reset() {} - virtual Error on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) { return ERR_UNAVAILABLE; } - virtual Error on_despawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) { return ERR_UNAVAILABLE; } - virtual Error on_sync_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) { return ERR_UNAVAILABLE; } - virtual Error on_spawn(Object *p_obj, Variant p_config) { return ERR_UNAVAILABLE; } - virtual Error on_despawn(Object *p_obj, Variant p_config) { return ERR_UNAVAILABLE; } - virtual Error on_replication_start(Object *p_obj, Variant p_config) { return ERR_UNAVAILABLE; } - virtual Error on_replication_stop(Object *p_obj, Variant p_config) { return ERR_UNAVAILABLE; } - virtual void on_network_process() {} - - MultiplayerReplicationInterface() {} -}; - -class MultiplayerRPCInterface : public RefCounted { - GDCLASS(MultiplayerRPCInterface, RefCounted); - -public: - // Called by Node.rpc - virtual void rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) {} - virtual void process_rpc(int p_from, const uint8_t *p_packet, int p_packet_len) {} - virtual String get_rpc_md5(const Object *p_obj) const { return String(); } - - MultiplayerRPCInterface() {} -}; - -class MultiplayerCacheInterface : public RefCounted { - GDCLASS(MultiplayerCacheInterface, RefCounted); - -public: - virtual void clear() {} - virtual void on_peer_change(int p_id, bool p_connected) {} - virtual void process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {} - virtual void process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {} - - // Returns true if all peers have cached path. - virtual bool send_object_cache(Object *p_obj, NodePath p_path, int p_target, int &p_id) { return false; } - virtual Object *get_cached_object(int p_from, uint32_t p_cache_id) { return nullptr; } - virtual bool is_cache_confirmed(NodePath p_path, int p_peer) { return false; } - - MultiplayerCacheInterface() {} -}; - -class MultiplayerAPI : public RefCounted { - GDCLASS(MultiplayerAPI, RefCounted); - -public: - enum NetworkCommands { - NETWORK_COMMAND_REMOTE_CALL = 0, - NETWORK_COMMAND_SIMPLIFY_PATH, - NETWORK_COMMAND_CONFIRM_PATH, - NETWORK_COMMAND_RAW, - NETWORK_COMMAND_SPAWN, - NETWORK_COMMAND_DESPAWN, - NETWORK_COMMAND_SYNC, - }; - - // For each command, the 4 MSB can contain custom flags, as defined by subsystems. - enum { - CMD_FLAG_0_SHIFT = 4, - CMD_FLAG_1_SHIFT = 5, - CMD_FLAG_2_SHIFT = 6, - CMD_FLAG_3_SHIFT = 7, - }; - - // This is the mask that will be used to extract the command. - enum { - CMD_MASK = 7, // 0x7 -> 0b00001111 - }; - -private: - Ref<MultiplayerPeer> multiplayer_peer; - HashSet<int> connected_peers; - int remote_sender_id = 0; - int remote_sender_override = 0; - - Vector<uint8_t> packet_cache; - - NodePath root_path; - bool allow_object_decoding = false; - - Ref<MultiplayerCacheInterface> cache; - Ref<MultiplayerReplicationInterface> replicator; - Ref<MultiplayerRPCInterface> rpc; - -protected: - static void _bind_methods(); - - void _process_packet(int p_from, const uint8_t *p_packet, int p_packet_len); - void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len); - -public: - static MultiplayerReplicationInterface *(*create_default_replication_interface)(MultiplayerAPI *p_multiplayer); - static MultiplayerRPCInterface *(*create_default_rpc_interface)(MultiplayerAPI *p_multiplayer); - static MultiplayerCacheInterface *(*create_default_cache_interface)(MultiplayerAPI *p_multiplayer); - - static Error encode_and_compress_variant(const Variant &p_variant, uint8_t *p_buffer, int &r_len, bool p_allow_object_decoding); - static Error decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding); - static Error encode_and_compress_variants(const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw = nullptr, bool p_allow_object_decoding = false); - static Error decode_and_decompress_variants(Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw = false, bool p_allow_object_decoding = false); - - void poll(); - void clear(); - void set_root_path(const NodePath &p_path); - NodePath get_root_path() const; - void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer); - Ref<MultiplayerPeer> get_multiplayer_peer() const; - - Error send_bytes(Vector<uint8_t> p_data, int p_to = MultiplayerPeer::TARGET_PEER_BROADCAST, Multiplayer::TransferMode p_mode = Multiplayer::TRANSFER_MODE_RELIABLE, int p_channel = 0); - - // RPC API - void rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); - String get_rpc_md5(const Object *p_obj) const; - // Replication API - Error spawn(Object *p_object, Variant p_config); - Error despawn(Object *p_object, Variant p_config); - Error replication_start(Object *p_object, Variant p_config); - Error replication_stop(Object *p_object, Variant p_config); - // Cache API - bool send_object_cache(Object *p_obj, NodePath p_path, int p_target, int &p_id); - Object *get_cached_object(int p_from, uint32_t p_cache_id); - bool is_cache_confirmed(NodePath p_path, int p_peer); - - void _add_peer(int p_id); - void _del_peer(int p_id); - void _connected_to_server(); - void _connection_failed(); - void _server_disconnected(); - - bool has_multiplayer_peer() const { return multiplayer_peer.is_valid(); } - Vector<int> get_peer_ids() const; - const HashSet<int> get_connected_peers() const { return connected_peers; } - int get_remote_sender_id() const { return remote_sender_override ? remote_sender_override : remote_sender_id; } - void set_remote_sender_override(int p_id) { remote_sender_override = p_id; } - int get_unique_id() const; - bool is_server() const; - void set_refuse_new_connections(bool p_refuse); - bool is_refusing_new_connections() const; - - void set_allow_object_decoding(bool p_enable); - bool is_object_decoding_allowed() const; - -#ifdef DEBUG_ENABLED - void profile_bandwidth(const String &p_inout, int p_size); -#endif - - MultiplayerAPI(); - ~MultiplayerAPI(); -}; - -#endif // MULTIPLAYER_API_H diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index ac008dad88..d67315f20d 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -305,6 +305,13 @@ void ClassDB::add_compatibility_class(const StringName &p_class, const StringNam compat_classes[p_class] = p_fallback; } +StringName ClassDB::get_compatibility_class(const StringName &p_class) { + if (compat_classes.has(p_class)) { + return compat_classes[p_class]; + } + return StringName(); +} + Object *ClassDB::instantiate(const StringName &p_class) { ClassInfo *ti; { diff --git a/core/object/class_db.h b/core/object/class_db.h index 1d26eb18f1..8b6a260d86 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -357,6 +357,7 @@ public: static bool is_resource_extension(const StringName &p_extension); static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback); + static StringName get_compatibility_class(const StringName &p_class); static void set_current_api(APIType p_api); static APIType get_current_api(); @@ -418,16 +419,16 @@ _FORCE_INLINE_ Vector<Error> errarray(P... p_args) { #endif -#define GDREGISTER_CLASS(m_class) \ - if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \ - ::ClassDB::register_class<m_class>(); \ +#define GDREGISTER_CLASS(m_class) \ + if (m_class::_class_is_enabled) { \ + ::ClassDB::register_class<m_class>(); \ } -#define GDREGISTER_VIRTUAL_CLASS(m_class) \ - if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \ - ::ClassDB::register_class<m_class>(true); \ +#define GDREGISTER_VIRTUAL_CLASS(m_class) \ + if (m_class::_class_is_enabled) { \ + ::ClassDB::register_class<m_class>(true); \ } #define GDREGISTER_ABSTRACT_CLASS(m_class) \ - if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \ + if (m_class::_class_is_enabled) { \ ::ClassDB::register_abstract_class<m_class>(); \ } diff --git a/core/object/object.h b/core/object/object.h index 705d6451dc..17f75a4e1d 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -358,6 +358,7 @@ private: friend class ::ClassDB; \ \ public: \ + static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \ virtual String get_class() const override { \ if (_get_extension()) { \ return _get_extension()->class_name.operator String(); \ @@ -667,6 +668,8 @@ public: // Should be protected, but bug in clang++. _FORCE_INLINE_ static void register_custom_data_to_otdb() {} public: + static constexpr bool _class_is_enabled = true; + void notify_property_list_changed(); static void *get_class_ptr_static() { diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 4623d0e525..226fd8b791 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -344,11 +344,14 @@ void ScriptLanguage::get_core_type_words(List<String> *p_core_type_words) const p_core_type_words->push_back("Vector3"); p_core_type_words->push_back("Vector3i"); p_core_type_words->push_back("Transform2D"); + p_core_type_words->push_back("Vector4"); + p_core_type_words->push_back("Vector4i"); p_core_type_words->push_back("Plane"); p_core_type_words->push_back("Quaternion"); p_core_type_words->push_back("AABB"); p_core_type_words->push_back("Basis"); p_core_type_words->push_back("Transform3D"); + p_core_type_words->push_back("Projection"); p_core_type_words->push_back("Color"); p_core_type_words->push_back("StringName"); p_core_type_words->push_back("NodePath"); diff --git a/core/object/script_language.h b/core/object/script_language.h index 686ab5b8d3..c9f8a4f828 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -33,7 +33,6 @@ #include "core/doc_data.h" #include "core/io/resource.h" -#include "core/multiplayer/multiplayer.h" #include "core/templates/pair.h" #include "core/templates/rb_map.h" @@ -159,7 +158,7 @@ public: virtual bool is_placeholder_fallback_enabled() const { return false; } - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const = 0; + virtual const Variant get_rpc_config() const = 0; Script() {} }; @@ -213,7 +212,7 @@ public: virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid); virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid); - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const { return get_script()->get_rpc_methods(); } + virtual const Variant get_rpc_config() const { return get_script()->get_rpc_config(); } virtual ScriptLanguage *get_language() = 0; virtual ~ScriptInstance(); @@ -469,7 +468,7 @@ public: virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid = nullptr) override; virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid = nullptr) override; - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override { return Vector<Multiplayer::RPCConfig>(); } + virtual const Variant get_rpc_config() const override { return Variant(); } PlaceHolderScriptInstance(ScriptLanguage *p_language, Ref<Script> p_script, Object *p_owner); ~PlaceHolderScriptInstance(); diff --git a/core/object/script_language_extension.cpp b/core/object/script_language_extension.cpp index ab8dd6d1ee..9de784ea7f 100644 --- a/core/object/script_language_extension.cpp +++ b/core/object/script_language_extension.cpp @@ -74,7 +74,7 @@ void ScriptExtension::_bind_methods() { GDVIRTUAL_BIND(_get_members); GDVIRTUAL_BIND(_is_placeholder_fallback_enabled); - GDVIRTUAL_BIND(_get_rpc_methods); + GDVIRTUAL_BIND(_get_rpc_config); } void ScriptLanguageExtension::_bind_methods() { diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 2c53139ec2..10eacfd9f7 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -173,28 +173,12 @@ public: EXBIND0RC(bool, is_placeholder_fallback_enabled) - GDVIRTUAL0RC(TypedArray<Dictionary>, _get_rpc_methods) + GDVIRTUAL0RC(Variant, _get_rpc_config) - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override { - TypedArray<Dictionary> ret; - GDVIRTUAL_REQUIRED_CALL(_get_rpc_methods, ret); - Vector<Multiplayer::RPCConfig> rpcret; - for (int i = 0; i < ret.size(); i++) { - Dictionary d = ret[i]; - Multiplayer::RPCConfig rpc; - ERR_CONTINUE(!d.has("name")); - rpc.name = d["name"]; - ERR_CONTINUE(!d.has("rpc_mode")); - rpc.rpc_mode = Multiplayer::RPCMode(int(d["rpc_mode"])); - ERR_CONTINUE(!d.has("call_local")); - rpc.call_local = d["call_local"]; - ERR_CONTINUE(!d.has("transfer_mode")); - rpc.transfer_mode = Multiplayer::TransferMode(int(d["transfer_mode"])); - ERR_CONTINUE(!d.has("channel")); - rpc.channel = d["channel"]; - rpcret.push_back(rpc); - } - return rpcret; + virtual const Variant get_rpc_config() const override { + Variant ret; + GDVIRTUAL_REQUIRED_CALL(_get_rpc_config, ret); + return ret; } ScriptExtension() {} diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp new file mode 100644 index 0000000000..54738a673e --- /dev/null +++ b/core/object/worker_thread_pool.cpp @@ -0,0 +1,474 @@ +/*************************************************************************/ +/* worker_thread_pool.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "worker_thread_pool.h" + +#include "core/os/os.h" + +void WorkerThreadPool::Task::free_template_userdata() { + ERR_FAIL_COND(!template_userdata); + ERR_FAIL_COND(native_func_userdata == nullptr); + BaseTemplateUserdata *btu = (BaseTemplateUserdata *)native_func_userdata; + memdelete(btu); +} + +WorkerThreadPool *WorkerThreadPool::singleton = nullptr; + +void WorkerThreadPool::_process_task_queue() { + task_mutex.lock(); + Task *task = task_queue.first()->self(); + task_queue.remove(task_queue.first()); + task_mutex.unlock(); + _process_task(task); +} + +void WorkerThreadPool::_process_task(Task *p_task) { + bool low_priority = p_task->low_priority; + + if (p_task->group) { + // Handling a group + bool do_post = false; + Callable::CallError ce; + Variant ret; + Variant arg; + Variant *argptr = &arg; + + while (true) { + uint32_t work_index = p_task->group->index.postincrement(); + + if (work_index >= p_task->group->max) { + break; + } + if (p_task->native_group_func) { + p_task->native_group_func(p_task->native_func_userdata, work_index); + } else if (p_task->template_userdata) { + p_task->template_userdata->callback_indexed(work_index); + } else { + arg = work_index; + p_task->callable.call((const Variant **)&argptr, 1, ret, ce); + } + + // This is the only way to ensure posting is done when all tasks are really complete. + uint32_t completed_amount = p_task->group->completed_index.increment(); + + if (completed_amount == p_task->group->max) { + do_post = true; + } + } + + if (do_post && p_task->template_userdata) { + memdelete(p_task->template_userdata); // This is no longer needed at this point, so get rid of it. + } + + if (low_priority && use_native_low_priority_threads) { + p_task->completed = true; + p_task->done_semaphore.post(); + if (do_post) { + p_task->group->completed.set_to(true); + } + } else { + if (do_post) { + p_task->group->done_semaphore.post(); + p_task->group->completed.set_to(true); + } + uint32_t max_users = p_task->group->tasks_used + 1; // Add 1 because the thread waiting for it is also user. Read before to avoid another thread freeing task after increment. + uint32_t finished_users = p_task->group->finished.increment(); + + if (finished_users == max_users) { + // Get rid of the group, because nobody else is using it. + task_mutex.lock(); + group_allocator.free(p_task->group); + task_mutex.unlock(); + } + + // For groups, tasks get rid of themselves. + + task_mutex.lock(); + task_allocator.free(p_task); + task_mutex.unlock(); + } + } else { + if (p_task->native_func) { + p_task->native_func(p_task->native_func_userdata); + } else if (p_task->template_userdata) { + p_task->template_userdata->callback(); + memdelete(p_task->template_userdata); + } else { + Callable::CallError ce; + Variant ret; + p_task->callable.call(nullptr, 0, ret, ce); + } + + p_task->completed = true; + p_task->done_semaphore.post(); + } + + if (!use_native_low_priority_threads && low_priority) { + // A low prioriry task was freed, so see if we can move a pending one to the high priority queue. + bool post = false; + task_mutex.lock(); + if (low_priority_task_queue.first()) { + Task *low_prio_task = low_priority_task_queue.first()->self(); + low_priority_task_queue.remove(low_priority_task_queue.first()); + task_queue.add_last(&low_prio_task->task_elem); + post = true; + } else { + low_priority_threads_used.decrement(); + } + task_mutex.lock(); + if (post) { + task_available_semaphore.post(); + } + } +} + +void WorkerThreadPool::_thread_function(void *p_user) { + while (true) { + singleton->task_available_semaphore.wait(); + if (singleton->exit_threads.is_set()) { + break; + } + singleton->_process_task_queue(); + } +} + +void WorkerThreadPool::_native_low_priority_thread_function(void *p_user) { + Task *task = (Task *)p_user; + singleton->_process_task(task); +} + +void WorkerThreadPool::_post_task(Task *p_task, bool p_high_priority) { + task_mutex.lock(); + p_task->low_priority = !p_high_priority; + if (!p_high_priority && use_native_low_priority_threads) { + task_mutex.unlock(); + p_task->low_priority_thread = native_thread_allocator.alloc(); + p_task->low_priority_thread->start(_native_low_priority_thread_function, p_task); // Pask task directly to thread. + + } else if (p_high_priority || low_priority_threads_used.get() < max_low_priority_threads) { + task_queue.add_last(&p_task->task_elem); + if (!p_high_priority) { + low_priority_threads_used.increment(); + } + task_mutex.unlock(); + task_available_semaphore.post(); + } else { + // Too many threads using low priority, must go to queue. + low_priority_task_queue.add_last(&p_task->task_elem); + task_mutex.unlock(); + } +} + +WorkerThreadPool::TaskID WorkerThreadPool::add_native_task(void (*p_func)(void *), void *p_userdata, bool p_high_priority, const String &p_description) { + return _add_task(Callable(), p_func, p_userdata, nullptr, p_high_priority, p_description); +} + +WorkerThreadPool::TaskID WorkerThreadPool::_add_task(const Callable &p_callable, void (*p_func)(void *), void *p_userdata, BaseTemplateUserdata *p_template_userdata, bool p_high_priority, const String &p_description) { + task_mutex.lock(); + // Get a free task + Task *task = task_allocator.alloc(); + TaskID id = last_task++; + task->callable = p_callable; + task->native_func = p_func; + task->native_func_userdata = p_userdata; + task->description = p_description; + task->template_userdata = p_template_userdata; + tasks.insert(id, task); + task_mutex.unlock(); + + _post_task(task, p_high_priority); + + return id; +} + +WorkerThreadPool::TaskID WorkerThreadPool::add_task(const Callable &p_action, bool p_high_priority, const String &p_description) { + return _add_task(p_action, nullptr, nullptr, nullptr, p_high_priority, p_description); +} + +bool WorkerThreadPool::is_task_completed(TaskID p_task_id) const { + task_mutex.lock(); + const Task *const *taskp = tasks.getptr(p_task_id); + if (!taskp) { + task_mutex.unlock(); + ERR_FAIL_V_MSG(false, "Invalid Task ID"); // Invalid task + } + + bool completed = (*taskp)->completed; + task_mutex.unlock(); + + return completed; +} + +void WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) { + task_mutex.lock(); + Task **taskp = tasks.getptr(p_task_id); + if (!taskp) { + task_mutex.unlock(); + ERR_FAIL_MSG("Invalid Task ID"); // Invalid task + } + Task *task = *taskp; + + if (task->waiting) { + String description = task->description; + task_mutex.unlock(); + if (description.is_empty()) { + ERR_FAIL_MSG("Another thread is waiting on this task: " + itos(p_task_id)); // Invalid task + } else { + ERR_FAIL_MSG("Another thread is waiting on this task: " + description + " (" + itos(p_task_id) + ")"); // Invalid task + } + } + + task->waiting = true; + + task_mutex.unlock(); + + if (use_native_low_priority_threads && task->low_priority) { + task->low_priority_thread->wait_to_finish(); + native_thread_allocator.free(task->low_priority_thread); + } else { + int *index = thread_ids.getptr(Thread::get_caller_id()); + + if (index) { + // We are an actual process thread, we must not be blocked so continue processing stuff if available. + while (true) { + if (task->done_semaphore.try_wait()) { + // If done, exit + break; + } + if (task_available_semaphore.try_wait()) { + // Solve tasks while they are around. + _process_task_queue(); + continue; + } + OS::get_singleton()->delay_usec(1); // Microsleep, this could be converted to waiting for multiple objects in supported platforms for a bit more performance. + } + } else { + task->done_semaphore.wait(); + } + } + + task_mutex.lock(); + tasks.erase(p_task_id); + task_allocator.free(task); + task_mutex.unlock(); +} + +WorkerThreadPool::GroupID WorkerThreadPool::_add_group_task(const Callable &p_callable, void (*p_func)(void *, uint32_t), void *p_userdata, BaseTemplateUserdata *p_template_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) { + ERR_FAIL_COND_V(p_elements < 0, INVALID_TASK_ID); + if (p_tasks < 0) { + p_tasks = threads.size(); + } + + task_mutex.lock(); + Group *group = group_allocator.alloc(); + GroupID id = last_task++; + group->max = p_elements; + group->self = id; + + Task **tasks_posted = nullptr; + if (p_elements == 0) { + // Should really not call it with zero Elements, but at least it should work. + group->completed.set_to(true); + group->done_semaphore.post(); + group->tasks_used = 0; + p_tasks = 0; + if (p_template_userdata) { + memdelete(p_template_userdata); + } + + } else { + group->tasks_used = p_tasks; + tasks_posted = (Task **)alloca(sizeof(Task *) * p_tasks); + for (int i = 0; i < p_tasks; i++) { + Task *task = task_allocator.alloc(); + task->native_group_func = p_func; + task->native_func_userdata = p_userdata; + task->description = p_description; + task->group = group; + task->callable = p_callable; + task->template_userdata = p_template_userdata; + tasks_posted[i] = task; + // No task ID is used. + } + } + + groups[id] = group; + task_mutex.unlock(); + + if (!p_high_priority && use_native_low_priority_threads) { + group->low_priority_native_tasks.resize(p_tasks); + } + + for (int i = 0; i < p_tasks; i++) { + _post_task(tasks_posted[i], p_high_priority); + if (!p_high_priority && use_native_low_priority_threads) { + group->low_priority_native_tasks[i] = tasks_posted[i]; + } + } + + return id; +} + +WorkerThreadPool::GroupID WorkerThreadPool::add_native_group_task(void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) { + return _add_group_task(Callable(), p_func, p_userdata, nullptr, p_elements, p_tasks, p_high_priority, p_description); +} + +WorkerThreadPool::GroupID WorkerThreadPool::add_group_task(const Callable &p_action, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) { + return _add_group_task(p_action, nullptr, nullptr, nullptr, p_elements, p_tasks, p_high_priority, p_description); +} + +uint32_t WorkerThreadPool::get_group_processed_element_count(GroupID p_group) const { + task_mutex.lock(); + const Group *const *groupp = groups.getptr(p_group); + if (!groupp) { + task_mutex.unlock(); + ERR_FAIL_V_MSG(0, "Invalid Group ID"); + } + uint32_t elements = (*groupp)->completed_index.get(); + task_mutex.unlock(); + return elements; +} +bool WorkerThreadPool::is_group_task_completed(GroupID p_group) const { + task_mutex.lock(); + const Group *const *groupp = groups.getptr(p_group); + if (!groupp) { + task_mutex.unlock(); + ERR_FAIL_V_MSG(false, "Invalid Group ID"); + } + bool completed = (*groupp)->completed.is_set(); + task_mutex.unlock(); + return completed; +} + +void WorkerThreadPool::wait_for_group_task_completion(GroupID p_group) { + task_mutex.lock(); + Group **groupp = groups.getptr(p_group); + task_mutex.unlock(); + if (!groupp) { + ERR_FAIL_MSG("Invalid Group ID"); + } + Group *group = *groupp; + + if (group->low_priority_native_tasks.size() > 0) { + for (uint32_t i = 0; i < group->low_priority_native_tasks.size(); i++) { + group->low_priority_native_tasks[i]->low_priority_thread->wait_to_finish(); + native_thread_allocator.free(group->low_priority_native_tasks[i]->low_priority_thread); + task_mutex.lock(); + task_allocator.free(group->low_priority_native_tasks[i]); + task_mutex.unlock(); + } + + task_mutex.lock(); + group_allocator.free(group); + task_mutex.unlock(); + } else { + group->done_semaphore.wait(); + + uint32_t max_users = group->tasks_used + 1; // Add 1 because the thread waiting for it is also user. Read before to avoid another thread freeing task after increment. + uint32_t finished_users = group->finished.increment(); // fetch happens before inc, so increment later. + + if (finished_users == max_users) { + // All tasks using this group are gone (finished before the group), so clear the gorup too. + task_mutex.lock(); + group_allocator.free(group); + task_mutex.unlock(); + } + } + + groups.erase(p_group); // Threads do not access this, so safe to erase here. +} + +void WorkerThreadPool::init(int p_thread_count, bool p_use_native_threads_low_priority, float p_low_priority_task_ratio) { + ERR_FAIL_COND(threads.size() > 0); + if (p_thread_count < 0) { + p_thread_count = OS::get_singleton()->get_default_thread_pool_size(); + } + + if (p_use_native_threads_low_priority) { + max_low_priority_threads = 0; + } else { + max_low_priority_threads = CLAMP(p_thread_count * p_low_priority_task_ratio, 1, p_thread_count); + } + + use_native_low_priority_threads = p_use_native_threads_low_priority; + + threads.resize(p_thread_count); + + for (uint32_t i = 0; i < threads.size(); i++) { + threads[i].index = i; + threads[i].thread.start(&WorkerThreadPool::_thread_function, &threads[i]); + thread_ids.insert(threads[i].thread.get_id(), i); + } +} + +void WorkerThreadPool::finish() { + if (threads.size() == 0) { + return; + } + + task_mutex.lock(); + SelfList<Task> *E = low_priority_task_queue.first(); + while (E) { + print_error("Task waiting was never re-claimed: " + E->self()->description); + E = E->next(); + } + task_mutex.unlock(); + + exit_threads.set_to(true); + + for (uint32_t i = 0; i < threads.size(); i++) { + task_available_semaphore.post(); + } + + for (uint32_t i = 0; i < threads.size(); i++) { + threads[i].thread.wait_to_finish(); + } + + threads.clear(); +} + +void WorkerThreadPool::_bind_methods() { + ClassDB::bind_method(D_METHOD("add_task", "action", "high_priority", "description"), &WorkerThreadPool::add_task, DEFVAL(false), DEFVAL(String())); + ClassDB::bind_method(D_METHOD("is_task_completed", "task_id"), &WorkerThreadPool::is_task_completed); + ClassDB::bind_method(D_METHOD("wait_for_task_completion", "task_id"), &WorkerThreadPool::wait_for_task_completion); + + ClassDB::bind_method(D_METHOD("add_group_task", "action", "elements", "tasks_needed", "high_priority", "description"), &WorkerThreadPool::add_group_task, DEFVAL(-1), DEFVAL(false), DEFVAL(String())); + ClassDB::bind_method(D_METHOD("is_group_task_completed", "group_id"), &WorkerThreadPool::is_group_task_completed); + ClassDB::bind_method(D_METHOD("get_group_processed_element_count", "group_id"), &WorkerThreadPool::get_group_processed_element_count); + ClassDB::bind_method(D_METHOD("wait_for_group_task_completion", "group_id"), &WorkerThreadPool::wait_for_group_task_completion); +} + +WorkerThreadPool::WorkerThreadPool() { + singleton = this; +} + +WorkerThreadPool::~WorkerThreadPool() { + finish(); +} diff --git a/core/object/worker_thread_pool.h b/core/object/worker_thread_pool.h new file mode 100644 index 0000000000..1debd9ca37 --- /dev/null +++ b/core/object/worker_thread_pool.h @@ -0,0 +1,198 @@ +/*************************************************************************/ +/* worker_thread_pool.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 WORKER_THREAD_POOL_H +#define WORKER_THREAD_POOL_H + +#include "core/os/memory.h" +#include "core/os/os.h" +#include "core/os/semaphore.h" +#include "core/os/thread.h" +#include "core/templates/local_vector.h" +#include "core/templates/paged_allocator.h" +#include "core/templates/rid.h" +#include "core/templates/safe_refcount.h" + +class WorkerThreadPool : public Object { + GDCLASS(WorkerThreadPool, Object) +public: + enum { + INVALID_TASK_ID = -1 + }; + + typedef int64_t TaskID; + typedef int64_t GroupID; + +private: + struct Task; + + struct BaseTemplateUserdata { + virtual void callback() {} + virtual void callback_indexed(uint32_t p_index) {} + virtual ~BaseTemplateUserdata() {} + }; + + struct Group { + GroupID self; + SafeNumeric<uint32_t> index; + SafeNumeric<uint32_t> completed_index; + uint32_t max = 0; + Semaphore done_semaphore; + SafeFlag completed; + SafeNumeric<uint32_t> finished; + uint32_t tasks_used = 0; + TightLocalVector<Task *> low_priority_native_tasks; + }; + + struct Task { + Callable callable; + void (*native_func)(void *) = nullptr; + void (*native_group_func)(void *, uint32_t) = nullptr; + void *native_func_userdata = nullptr; + String description; + Semaphore done_semaphore; + bool completed = false; + Group *group = nullptr; + SelfList<Task> task_elem; + bool waiting = false; // Waiting for completion + bool low_priority = false; + BaseTemplateUserdata *template_userdata = nullptr; + Thread *low_priority_thread = nullptr; + + void free_template_userdata(); + Task() : + task_elem(this) {} + }; + + PagedAllocator<Task> task_allocator; + PagedAllocator<Group> group_allocator; + PagedAllocator<Thread> native_thread_allocator; + + SelfList<Task>::List low_priority_task_queue; + SelfList<Task>::List task_queue; + + Mutex task_mutex; + Semaphore task_available_semaphore; + + struct ThreadData { + uint32_t index; + Thread thread; + }; + + TightLocalVector<ThreadData> threads; + SafeFlag exit_threads; + + HashMap<Thread::ID, int> thread_ids; + HashMap<TaskID, Task *> tasks; + HashMap<GroupID, Group *> groups; + + bool use_native_low_priority_threads = false; + uint32_t max_low_priority_threads = 0; + SafeNumeric<uint32_t> low_priority_threads_used; + + uint64_t last_task = 1; + + static void _thread_function(void *p_user); + static void _native_low_priority_thread_function(void *p_user); + + void _process_task_queue(); + void _process_task(Task *task); + + void _post_task(Task *p_task, bool p_high_priority); + + static WorkerThreadPool *singleton; + + TaskID _add_task(const Callable &p_callable, void (*p_func)(void *), void *p_userdata, BaseTemplateUserdata *p_template_userdata, bool p_high_priority, const String &p_description); + GroupID _add_group_task(const Callable &p_callable, void (*p_func)(void *, uint32_t), void *p_userdata, BaseTemplateUserdata *p_template_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description); + + template <class C, class M, class U> + struct TaskUserData : public BaseTemplateUserdata { + C *instance; + M method; + U userdata; + virtual void callback() override { + (instance->*method)(userdata); + } + }; + + template <class C, class M, class U> + struct GroupUserData : public BaseTemplateUserdata { + C *instance; + M method; + U userdata; + virtual void callback_indexed(uint32_t p_index) override { + (instance->*method)(p_index, userdata); + } + }; + +protected: + static void _bind_methods(); + +public: + template <class C, class M, class U> + TaskID add_template_task(C *p_instance, M p_method, U p_userdata, bool p_high_priority = false, const String &p_description = String()) { + typedef TaskUserData<C, M, U> TUD; + TUD *ud = memnew(TUD); + ud->instance = p_instance; + ud->method = p_method; + ud->userdata = p_userdata; + return _add_task(Callable(), nullptr, nullptr, ud, p_high_priority, p_description); + } + TaskID add_native_task(void (*p_func)(void *), void *p_userdata, bool p_high_priority = false, const String &p_description = String()); + TaskID add_task(const Callable &p_action, bool p_high_priority = false, const String &p_description = String()); + + bool is_task_completed(TaskID p_task_id) const; + void wait_for_task_completion(TaskID p_task_id); + + template <class C, class M, class U> + GroupID add_template_group_task(C *p_instance, M p_method, U p_userdata, int p_elements, int p_tasks = -1, bool p_high_priority = false, const String &p_description = String()) { + typedef GroupUserData<C, M, U> GUD; + GUD *ud = memnew(GUD); + ud->instance = p_instance; + ud->method = p_method; + ud->userdata = p_userdata; + return _add_group_task(Callable(), nullptr, nullptr, ud, p_elements, p_tasks, p_high_priority, p_description); + } + GroupID add_native_group_task(void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks = -1, bool p_high_priority = false, const String &p_description = String()); + GroupID add_group_task(const Callable &p_action, int p_elements, int p_tasks = -1, bool p_high_priority = false, const String &p_description = String()); + uint32_t get_group_processed_element_count(GroupID p_group) const; + bool is_group_task_completed(GroupID p_group) const; + void wait_for_group_task_completion(GroupID p_group); + + _FORCE_INLINE_ int get_thread_count() const { return threads.size(); } + + static WorkerThreadPool *get_singleton() { return singleton; } + void init(int p_thread_count = -1, bool p_use_native_threads_low_priority = true, float p_low_priority_task_ratio = 0.3); + void finish(); + WorkerThreadPool(); + ~WorkerThreadPool(); +}; + +#endif // WORKER_THREAD_POOL_H diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index 3e690991d9..a592791d06 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -61,7 +61,7 @@ static const _KeyCodeText _keycodes[] = { {Key::PAGEDOWN ,"PageDown"}, {Key::SHIFT ,"Shift"}, {Key::CTRL ,"Ctrl"}, -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED {Key::META ,"Command"}, #else {Key::META ,"Meta"}, diff --git a/core/os/os.cpp b/core/os/os.cpp index b9daf6fa53..619e3eb06f 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -159,7 +159,7 @@ int OS::get_process_id() const { } void OS::vibrate_handheld(int p_duration_ms) { - WARN_PRINT("vibrate_handheld() only works with Android and iOS"); + WARN_PRINT("vibrate_handheld() only works with Android, iOS and HTML5"); } bool OS::is_stdout_verbose() const { diff --git a/core/os/os.h b/core/os/os.h index 0428f6df2a..b9f7328929 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -142,6 +142,8 @@ public: virtual void set_low_processor_usage_mode_sleep_usec(int p_usec); virtual int get_low_processor_usage_mode_sleep_usec() const; + virtual Vector<String> get_system_fonts() const { return Vector<String>(); }; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const { return String(); }; virtual String get_executable_path() const; virtual Error execute(const String &p_path, const List<String> &p_arguments, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) = 0; virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) = 0; diff --git a/core/os/spin_lock.h b/core/os/spin_lock.h index 6e8d7f46d5..80eeef3386 100644 --- a/core/os/spin_lock.h +++ b/core/os/spin_lock.h @@ -48,4 +48,5 @@ public: locked.clear(std::memory_order_release); } }; + #endif // SPIN_LOCK_H diff --git a/core/os/thread.h b/core/os/thread.h index 3382dd81f9..0fb283e224 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -123,4 +123,5 @@ public: }; #endif // THREAD_H + #endif // PLATFORM_THREAD_OVERRIDE diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index e60d325f74..1ae5d1c83f 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -69,11 +69,10 @@ #include "core/math/geometry_3d.h" #include "core/math/random_number_generator.h" #include "core/math/triangle_mesh.h" -#include "core/multiplayer/multiplayer_api.h" -#include "core/multiplayer/multiplayer_peer.h" #include "core/object/class_db.h" #include "core/object/script_language_extension.h" #include "core/object/undo_redo.h" +#include "core/object/worker_thread_pool.h" #include "core/os/main_loop.h" #include "core/os/time.h" #include "core/string/optimized_translation.h" @@ -101,6 +100,8 @@ static IP *ip = nullptr; static core_bind::Geometry2D *_geometry_2d = nullptr; static core_bind::Geometry3D *_geometry_3d = nullptr; +static WorkerThreadPool *worker_thread_pool = nullptr; + extern Mutex _global_mutex; static NativeExtensionManager *native_extension_manager = nullptr; @@ -189,6 +190,8 @@ void register_core_types() { GDREGISTER_CLASS(PacketPeerUDP); GDREGISTER_CLASS(UDPServer); + GDREGISTER_ABSTRACT_CLASS(WorkerThreadPool); + ClassDB::register_custom_instance_class<HTTPClient>(); // Crypto @@ -207,9 +210,6 @@ void register_core_types() { resource_format_loader_crypto.instantiate(); ResourceLoader::add_resource_format_loader(resource_format_loader_crypto); - GDREGISTER_ABSTRACT_CLASS(MultiplayerPeer); - GDREGISTER_CLASS(MultiplayerPeerExtension); - GDREGISTER_CLASS(MultiplayerAPI); GDREGISTER_CLASS(MainLoop); GDREGISTER_CLASS(Translation); GDREGISTER_CLASS(OptimizedTranslation); @@ -271,6 +271,8 @@ void register_core_types() { GDREGISTER_NATIVE_STRUCT(AudioFrame, "float left;float right"); GDREGISTER_NATIVE_STRUCT(ScriptLanguageExtensionProfilingInfo, "StringName signature;uint64_t call_count;uint64_t total_time;uint64_t self_time"); + + worker_thread_pool = memnew(WorkerThreadPool); } void register_core_settings() { @@ -279,9 +281,18 @@ void register_core_settings() { ProjectSettings::get_singleton()->set_custom_property_info("network/limits/tcp/connect_timeout_seconds", PropertyInfo(Variant::INT, "network/limits/tcp/connect_timeout_seconds", PROPERTY_HINT_RANGE, "1,1800,1")); GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16)); ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater")); - GLOBAL_DEF("network/ssl/certificate_bundle_override", ""); ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificate_bundle_override", PropertyInfo(Variant::STRING, "network/ssl/certificate_bundle_override", PROPERTY_HINT_FILE, "*.crt")); + + int worker_threads = GLOBAL_DEF("threading/worker_pool/max_threads", -1); + bool low_priority_use_system_threads = GLOBAL_DEF("threading/worker_pool/use_system_threads_for_low_priority_tasks", true); + float low_property_ratio = GLOBAL_DEF("threading/worker_pool/low_priority_thread_ratio", 0.3); + + if (Engine::get_singleton()->is_editor_hint() || Engine::get_singleton()->is_project_manager_hint()) { + worker_thread_pool->init(); + } else { + worker_thread_pool->init(worker_threads, low_priority_use_system_threads, low_property_ratio); + } } void register_core_singletons() { @@ -319,6 +330,7 @@ void register_core_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("Time", Time::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("NativeExtensionManager", NativeExtensionManager::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceUID", ResourceUID::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("WorkerThreadPool", worker_thread_pool)); } void register_core_extensions() { @@ -350,6 +362,8 @@ void unregister_core_types() { memdelete(_geometry_2d); memdelete(_geometry_3d); + memdelete(worker_thread_pool); + ResourceLoader::remove_resource_format_loader(resource_format_image); resource_format_image.unref(); diff --git a/core/string/ustring.h b/core/string/ustring.h index 1b8bf3d234..7672663964 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -28,9 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +// Note: _GODOT suffix added to avoid conflict with ICU header with the same guard. + #ifndef USTRING_GODOT_H #define USTRING_GODOT_H -// Note: Renamed to avoid conflict with ICU header with the same name. #include "core/string/char_utils.h" #include "core/templates/cowdata.h" diff --git a/core/templates/bin_sorted_array.h b/core/templates/bin_sorted_array.h index d928bd7a82..38beb9c04d 100644 --- a/core/templates/bin_sorted_array.h +++ b/core/templates/bin_sorted_array.h @@ -178,4 +178,4 @@ public: } }; -#endif //BIN_SORTED_ARRAY_H +#endif // BIN_SORTED_ARRAY_H diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h index 547534f26a..d85cdf7adc 100644 --- a/core/templates/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -40,6 +40,8 @@ #include "core/math/vector2i.h" #include "core/math/vector3.h" #include "core/math/vector3i.h" +#include "core/math/vector4.h" +#include "core/math/vector4i.h" #include "core/object/object_id.h" #include "core/string/node_path.h" #include "core/string/string_name.h" @@ -332,6 +334,13 @@ struct HashMapHasherDefault { h = hash_murmur3_one_32(p_vec.z, h); return hash_fmix32(h); } + static _FORCE_INLINE_ uint32_t hash(const Vector4i &p_vec) { + uint32_t h = hash_murmur3_one_32(p_vec.x); + h = hash_murmur3_one_32(p_vec.y, h); + h = hash_murmur3_one_32(p_vec.z, h); + h = hash_murmur3_one_32(p_vec.w, h); + return hash_fmix32(h); + } static _FORCE_INLINE_ uint32_t hash(const Vector2 &p_vec) { uint32_t h = hash_murmur3_one_real(p_vec.x); h = hash_murmur3_one_real(p_vec.y, h); @@ -343,6 +352,13 @@ struct HashMapHasherDefault { h = hash_murmur3_one_real(p_vec.z, h); return hash_fmix32(h); } + static _FORCE_INLINE_ uint32_t hash(const Vector4 &p_vec) { + uint32_t h = hash_murmur3_one_real(p_vec.x); + h = hash_murmur3_one_real(p_vec.y, h); + h = hash_murmur3_one_real(p_vec.z, h); + h = hash_murmur3_one_real(p_vec.w, h); + return hash_fmix32(h); + } static _FORCE_INLINE_ uint32_t hash(const Rect2i &p_rect) { uint32_t h = hash_murmur3_one_32(p_rect.position.x); h = hash_murmur3_one_32(p_rect.position.y, h); diff --git a/core/templates/lru.h b/core/templates/lru.h index b08b6455b6..3a78de61db 100644 --- a/core/templates/lru.h +++ b/core/templates/lru.h @@ -124,4 +124,4 @@ public: } }; -#endif +#endif // LRU_H diff --git a/core/templates/rb_map.h b/core/templates/rb_map.h index c732ccd485..3393e6dd3e 100644 --- a/core/templates/rb_map.h +++ b/core/templates/rb_map.h @@ -758,4 +758,4 @@ public: } }; -#endif // MAP_H +#endif // RB_MAP_H diff --git a/core/templates/rb_set.h b/core/templates/rb_set.h index 226ea979c9..e87ea544fd 100644 --- a/core/templates/rb_set.h +++ b/core/templates/rb_set.h @@ -708,4 +708,4 @@ public: } }; -#endif // SET_H +#endif // RB_SET_H diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h index 3148283dca..1f6551762e 100644 --- a/core/templates/safe_refcount.h +++ b/core/templates/safe_refcount.h @@ -111,6 +111,7 @@ public: if (tmp >= p_value) { return tmp; // already greater, or equal } + if (value.compare_exchange_weak(tmp, p_value, std::memory_order_acq_rel)) { return p_value; } diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h deleted file mode 100644 index b0cebf04f1..0000000000 --- a/core/templates/thread_work_pool.h +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************/ -/* thread_work_pool.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 THREAD_WORK_POOL_H -#define THREAD_WORK_POOL_H - -#include "core/os/memory.h" -#include "core/os/semaphore.h" -#include "core/os/thread.h" - -#include <atomic> - -class ThreadWorkPool { - std::atomic<uint32_t> index; - - struct BaseWork { - std::atomic<uint32_t> *index = nullptr; - uint32_t max_elements = 0; - virtual void work() = 0; - virtual ~BaseWork() = default; - }; - - template <class C, class M, class U> - struct Work : public BaseWork { - C *instance; - M method; - U userdata; - virtual void work() override { - while (true) { - uint32_t work_index = index->fetch_add(1, std::memory_order_relaxed); - if (work_index >= max_elements) { - break; - } - (instance->*method)(work_index, userdata); - } - } - }; - - struct ThreadData { - Thread thread; - Semaphore start; - Semaphore completed; - std::atomic<bool> exit; - BaseWork *work = nullptr; - }; - - ThreadData *threads = nullptr; - uint32_t thread_count = 0; - uint32_t threads_working = 0; - BaseWork *current_work = nullptr; - - static void _thread_function(void *p_user); - -public: - template <class C, class M, class U> - void begin_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { - ERR_FAIL_COND(!threads); //never initialized - ERR_FAIL_COND(current_work != nullptr); - - index.store(0, std::memory_order_release); - - Work<C, M, U> *w = memnew((Work<C, M, U>)); - w->instance = p_instance; - w->userdata = p_userdata; - w->method = p_method; - w->index = &index; - w->max_elements = p_elements; - - current_work = w; - - threads_working = MIN(p_elements, thread_count); - - for (uint32_t i = 0; i < threads_working; i++) { - threads[i].work = w; - threads[i].start.post(); - } - } - - bool is_working() const { - return current_work != nullptr; - } - - bool is_done_dispatching() const { - ERR_FAIL_COND_V(current_work == nullptr, true); - return index.load(std::memory_order_acquire) >= current_work->max_elements; - } - - uint32_t get_work_index() const { - ERR_FAIL_COND_V(current_work == nullptr, 0); - uint32_t idx = index.load(std::memory_order_acquire); - return MIN(idx, current_work->max_elements); - } - - void end_work() { - ERR_FAIL_COND(current_work == nullptr); - for (uint32_t i = 0; i < threads_working; i++) { - threads[i].completed.wait(); - threads[i].work = nullptr; - } - - threads_working = 0; - memdelete(current_work); - current_work = nullptr; - } - - template <class C, class M, class U> - void do_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { - switch (p_elements) { - case 0: - // Nothing to do, so do nothing. - break; - case 1: - // No value in pushing the work to another thread if it's a single job - // and we're going to wait for it to finish. Just run it right here. - (p_instance->*p_method)(0, p_userdata); - break; - default: - // Multiple jobs to do; commence threaded business. - begin_work(p_elements, p_instance, p_method, p_userdata); - end_work(); - } - } - - _FORCE_INLINE_ int get_thread_count() const { return thread_count; } - void init(int p_thread_count = -1); - void finish(); - ~ThreadWorkPool(); -}; - -#endif // THREAD_POOL_H diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 84f894dcbf..f0c3b1ce38 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -136,7 +136,10 @@ VARIANT_ENUM_CAST(Vector2::Axis); VARIANT_ENUM_CAST(Vector2i::Axis); VARIANT_ENUM_CAST(Vector3::Axis); VARIANT_ENUM_CAST(Vector3i::Axis); +VARIANT_ENUM_CAST(Vector4::Axis); +VARIANT_ENUM_CAST(Vector4i::Axis); VARIANT_ENUM_CAST(Basis::EulerOrder); +VARIANT_ENUM_CAST(Projection::Planes); VARIANT_ENUM_CAST(Error); VARIANT_ENUM_CAST(Side); diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index 5453f0d5c6..8b9b5f41de 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -63,17 +63,19 @@ void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_retu } } -void Callable::rpc(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const { +Error Callable::rpc(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const { if (is_null()) { r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL; r_call_error.argument = 0; r_call_error.expected = 0; + return ERR_UNCONFIGURED; } else if (!is_custom()) { r_call_error.error = CallError::CALL_ERROR_INVALID_METHOD; r_call_error.argument = 0; r_call_error.expected = 0; + return ERR_UNCONFIGURED; } else { - custom->rpc(p_id, p_arguments, p_argcount, r_call_error); + return custom->rpc(p_id, p_arguments, p_argcount, r_call_error); } } @@ -316,10 +318,11 @@ StringName CallableCustom::get_method() const { ERR_FAIL_V_MSG(StringName(), vformat("Can't get method on CallableCustom \"%s\".", get_as_text())); } -void CallableCustom::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { +Error CallableCustom::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; r_call_error.argument = 0; r_call_error.expected = 0; + return ERR_UNCONFIGURED; } const Callable *CallableCustom::get_base_comparator() const { @@ -437,6 +440,6 @@ bool CallableComparator::operator()(const Variant &p_l, const Variant &p_r) cons Variant res; func.call(args, 2, res, err); ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false, - "Error calling compare method: " + Variant::get_callable_error_text(func, args, 1, err)); + "Error calling compare method: " + Variant::get_callable_error_text(func, args, 2, err)); return res; } diff --git a/core/variant/callable.h b/core/variant/callable.h index bbcf5427ba..954365d010 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -71,7 +71,7 @@ public: void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const; void call_deferred(const Variant **p_arguments, int p_argcount) const; - void rpc(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const; + Error rpc(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const; _FORCE_INLINE_ bool is_null() const { return method == StringName() && object == 0; @@ -129,7 +129,7 @@ public: virtual StringName get_method() const; virtual ObjectID get_object() const = 0; //must always be able to provide an object virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0; - virtual void rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const; + virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const; virtual const Callable *get_base_comparator() const; CallableCustom(); diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h index d0acf60c22..0ed70a5504 100644 --- a/core/variant/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -125,7 +125,10 @@ MAKE_PTRARG(Rect2); MAKE_PTRARG(Rect2i); MAKE_PTRARG_BY_REFERENCE(Vector3); MAKE_PTRARG_BY_REFERENCE(Vector3i); +MAKE_PTRARG_BY_REFERENCE(Vector4); +MAKE_PTRARG_BY_REFERENCE(Vector4i); MAKE_PTRARG(Transform2D); +MAKE_PTRARG(Projection); MAKE_PTRARG_BY_REFERENCE(Plane); MAKE_PTRARG(Quaternion); MAKE_PTRARG_BY_REFERENCE(AABB); diff --git a/core/variant/type_info.h b/core/variant/type_info.h index 1bd3a74289..7372c60754 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -144,12 +144,15 @@ MAKE_TYPE_INFO(Vector3, Variant::VECTOR3) MAKE_TYPE_INFO(Vector2i, Variant::VECTOR2I) MAKE_TYPE_INFO(Rect2i, Variant::RECT2I) MAKE_TYPE_INFO(Vector3i, Variant::VECTOR3I) +MAKE_TYPE_INFO(Vector4, Variant::VECTOR4) +MAKE_TYPE_INFO(Vector4i, Variant::VECTOR4I) MAKE_TYPE_INFO(Transform2D, Variant::TRANSFORM2D) MAKE_TYPE_INFO(Plane, Variant::PLANE) MAKE_TYPE_INFO(Quaternion, Variant::QUATERNION) MAKE_TYPE_INFO(AABB, Variant::AABB) MAKE_TYPE_INFO(Basis, Variant::BASIS) MAKE_TYPE_INFO(Transform3D, Variant::TRANSFORM3D) +MAKE_TYPE_INFO(Projection, Variant::PROJECTION) MAKE_TYPE_INFO(Color, Variant::COLOR) MAKE_TYPE_INFO(StringName, Variant::STRING_NAME) MAKE_TYPE_INFO(NodePath, Variant::NODE_PATH) diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index ae92d7b5c4..6763dd66b0 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -83,6 +83,12 @@ String Variant::get_type_name(Variant::Type p_type) { case VECTOR3I: { return "Vector3i"; } break; + case VECTOR4: { + return "Vector4"; + } break; + case VECTOR4I: { + return "Vector4i"; + } break; case PLANE: { return "Plane"; @@ -102,6 +108,10 @@ String Variant::get_type_name(Variant::Type p_type) { return "Transform3D"; } break; + case PROJECTION: { + return "Projection"; + + } break; // misc types case COLOR: { @@ -298,6 +308,24 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { valid_types = valid; } break; + case VECTOR4: { + static const Type valid[] = { + VECTOR4I, + NIL, + }; + + valid_types = valid; + + } break; + case VECTOR4I: { + static const Type valid[] = { + VECTOR4, + NIL, + }; + + valid_types = valid; + + } break; case QUATERNION: { static const Type valid[] = { @@ -322,6 +350,16 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { TRANSFORM2D, QUATERNION, BASIS, + PROJECTION, + NIL + }; + + valid_types = valid; + + } break; + case PROJECTION: { + static const Type valid[] = { + TRANSFORM3D, NIL }; @@ -604,6 +642,24 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type valid_types = valid; } break; + case VECTOR4: { + static const Type valid[] = { + VECTOR4I, + NIL, + }; + + valid_types = valid; + + } break; + case VECTOR4I: { + static const Type valid[] = { + VECTOR4, + NIL, + }; + + valid_types = valid; + + } break; case QUATERNION: { static const Type valid[] = { @@ -628,6 +684,16 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type TRANSFORM2D, QUATERNION, BASIS, + PROJECTION, + NIL + }; + + valid_types = valid; + + } break; + case PROJECTION: { + static const Type valid[] = { + TRANSFORM3D, NIL }; @@ -858,6 +924,14 @@ bool Variant::is_zero() const { return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(); } break; + case VECTOR4: { + return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(); + + } break; + case VECTOR4I: { + return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(); + + } break; case PLANE: { return *reinterpret_cast<const Plane *>(_data._mem) == Plane(); @@ -877,6 +951,10 @@ bool Variant::is_zero() const { return *_data._transform3d == Transform3D(); } break; + case PROJECTION: { + return *_data._projection == Projection(); + + } break; // misc types case COLOR: { @@ -998,6 +1076,14 @@ bool Variant::is_one() const { return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1); } break; + case VECTOR4: { + return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(1, 1, 1, 1); + + } break; + case VECTOR4I: { + return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(1, 1, 1, 1); + + } break; case PLANE: { return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1); @@ -1084,6 +1170,12 @@ void Variant::reference(const Variant &p_variant) { case VECTOR3I: { memnew_placement(_data._mem, Vector3i(*reinterpret_cast<const Vector3i *>(p_variant._data._mem))); } break; + case VECTOR4: { + memnew_placement(_data._mem, Vector4(*reinterpret_cast<const Vector4 *>(p_variant._data._mem))); + } break; + case VECTOR4I: { + memnew_placement(_data._mem, Vector4i(*reinterpret_cast<const Vector4i *>(p_variant._data._mem))); + } break; case PLANE: { memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem))); } break; @@ -1102,6 +1194,9 @@ void Variant::reference(const Variant &p_variant) { case TRANSFORM3D: { _data._transform3d = memnew(Transform3D(*p_variant._data._transform3d)); } break; + case PROJECTION: { + _data._projection = memnew(Projection(*p_variant._data._projection)); + } break; // misc types case COLOR: { @@ -1250,6 +1345,12 @@ void Variant::zero() { case VECTOR3I: *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i(); break; + case VECTOR4: + *reinterpret_cast<Vector4 *>(this->_data._mem) = Vector4(); + break; + case VECTOR4I: + *reinterpret_cast<Vector4i *>(this->_data._mem) = Vector4i(); + break; case PLANE: *reinterpret_cast<Plane *>(this->_data._mem) = Plane(); break; @@ -1291,7 +1392,9 @@ void Variant::_clear_internal() { case TRANSFORM3D: { memdelete(_data._transform3d); } break; - + case PROJECTION: { + memdelete(_data._projection); + } break; // misc types case STRING_NAME: { reinterpret_cast<StringName *>(_data._mem)->~StringName(); @@ -1681,6 +1784,10 @@ String Variant::stringify(int recursion_count) const { return operator Vector3(); case VECTOR3I: return operator Vector3i(); + case VECTOR4: + return operator Vector4(); + case VECTOR4I: + return operator Vector4i(); case PLANE: return operator Plane(); case AABB: @@ -1691,6 +1798,8 @@ String Variant::stringify(int recursion_count) const { return operator Basis(); case TRANSFORM3D: return operator Transform3D(); + case PROJECTION: + return operator Projection(); case STRING_NAME: return operator StringName(); case NODE_PATH: @@ -1812,6 +1921,10 @@ Variant::operator Vector2() const { return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y); } else if (type == VECTOR3I) { return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y); + } else if (type == VECTOR4) { + return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y); + } else if (type == VECTOR4I) { + return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y); } else { return Vector2(); } @@ -1826,6 +1939,10 @@ Variant::operator Vector2i() const { return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y); } else if (type == VECTOR3I) { return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y); + } else if (type == VECTOR4) { + return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y); + } else if (type == VECTOR4I) { + return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y); } else { return Vector2i(); } @@ -1860,6 +1977,10 @@ Variant::operator Vector3() const { return Vector3(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0); } else if (type == VECTOR2I) { return Vector3(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0); + } else if (type == VECTOR4) { + return Vector3(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z); + } else if (type == VECTOR4I) { + return Vector3(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z); } else { return Vector3(); } @@ -1874,11 +1995,52 @@ Variant::operator Vector3i() const { return Vector3i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0); } else if (type == VECTOR2I) { return Vector3i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0); + } else if (type == VECTOR4) { + return Vector3i(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z); + } else if (type == VECTOR4I) { + return Vector3i(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z); } else { return Vector3i(); } } +Variant::operator Vector4() const { + if (type == VECTOR4) { + return *reinterpret_cast<const Vector4 *>(_data._mem); + } else if (type == VECTOR4I) { + return *reinterpret_cast<const Vector4i *>(_data._mem); + } else if (type == VECTOR2) { + return Vector4(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR2I) { + return Vector4(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR3) { + return Vector4(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0); + } else if (type == VECTOR3I) { + return Vector4(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0); + } else { + return Vector4(); + } +} + +Variant::operator Vector4i() const { + if (type == VECTOR4I) { + return *reinterpret_cast<const Vector4i *>(_data._mem); + } else if (type == VECTOR4) { + const Vector4 &v4 = *reinterpret_cast<const Vector4 *>(_data._mem); + return Vector4i(v4.x, v4.y, v4.z, v4.w); + } else if (type == VECTOR2) { + return Vector4i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR2I) { + return Vector4i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR3) { + return Vector4i(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0); + } else if (type == VECTOR3I) { + return Vector4i(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0); + } else { + return Vector4i(); + } +} + Variant::operator Plane() const { if (type == PLANE) { return *reinterpret_cast<const Plane *>(_data._mem); @@ -1936,11 +2098,37 @@ Variant::operator Transform3D() const { m.origin[0] = t.columns[2][0]; m.origin[1] = t.columns[2][1]; return m; + } else if (type == PROJECTION) { + return *_data._projection; } else { return Transform3D(); } } +Variant::operator Projection() const { + if (type == TRANSFORM3D) { + return *_data._transform3d; + } else if (type == BASIS) { + return Transform3D(*_data._basis, Vector3()); + } else if (type == QUATERNION) { + return Transform3D(Basis(*reinterpret_cast<const Quaternion *>(_data._mem)), Vector3()); + } else if (type == TRANSFORM2D) { + const Transform2D &t = *_data._transform2d; + Transform3D m; + m.basis.rows[0][0] = t.columns[0][0]; + m.basis.rows[1][0] = t.columns[0][1]; + m.basis.rows[0][1] = t.columns[1][0]; + m.basis.rows[1][1] = t.columns[1][1]; + m.origin[0] = t.columns[2][0]; + m.origin[1] = t.columns[2][1]; + return m; + } else if (type == PROJECTION) { + return *_data._projection; + } else { + return Projection(); + } +} + Variant::operator Transform2D() const { if (type == TRANSFORM2D) { return *_data._transform2d; @@ -2384,6 +2572,16 @@ Variant::Variant(const Vector3i &p_vector3i) { memnew_placement(_data._mem, Vector3i(p_vector3i)); } +Variant::Variant(const Vector4 &p_vector4) { + type = VECTOR4; + memnew_placement(_data._mem, Vector4(p_vector4)); +} + +Variant::Variant(const Vector4i &p_vector4i) { + type = VECTOR4I; + memnew_placement(_data._mem, Vector4i(p_vector4i)); +} + Variant::Variant(const Vector2 &p_vector2) { type = VECTOR2; memnew_placement(_data._mem, Vector2(p_vector2)); @@ -2429,6 +2627,11 @@ Variant::Variant(const Transform3D &p_transform) { _data._transform3d = memnew(Transform3D(p_transform)); } +Variant::Variant(const Projection &pp_projection) { + type = PROJECTION; + _data._projection = memnew(Projection(pp_projection)); +} + Variant::Variant(const Transform2D &p_transform) { type = TRANSFORM2D; _data._transform2d = memnew(Transform2D(p_transform)); @@ -2656,6 +2859,12 @@ void Variant::operator=(const Variant &p_variant) { case VECTOR3I: { *reinterpret_cast<Vector3i *>(_data._mem) = *reinterpret_cast<const Vector3i *>(p_variant._data._mem); } break; + case VECTOR4: { + *reinterpret_cast<Vector4 *>(_data._mem) = *reinterpret_cast<const Vector4 *>(p_variant._data._mem); + } break; + case VECTOR4I: { + *reinterpret_cast<Vector4i *>(_data._mem) = *reinterpret_cast<const Vector4i *>(p_variant._data._mem); + } break; case PLANE: { *reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem); } break; @@ -2672,6 +2881,9 @@ void Variant::operator=(const Variant &p_variant) { case TRANSFORM3D: { *_data._transform3d = *(p_variant._data._transform3d); } break; + case PROJECTION: { + *_data._projection = *(p_variant._data._projection); + } break; // misc types case COLOR: { @@ -2817,6 +3029,12 @@ uint32_t Variant::recursive_hash(int recursion_count) const { case VECTOR3I: { return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3i *>(_data._mem)); } break; + case VECTOR4: { + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4 *>(_data._mem)); + } break; + case VECTOR4I: { + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4i *>(_data._mem)); + } break; case PLANE: { uint32_t h = HASH_MURMUR3_SEED; const Plane &p = *reinterpret_cast<const Plane *>(_data._mem); @@ -2869,6 +3087,27 @@ uint32_t Variant::recursive_hash(int recursion_count) const { h = hash_murmur3_one_real(t.origin.z, h); return hash_fmix32(h); } break; + case PROJECTION: { + uint32_t h = HASH_MURMUR3_SEED; + const Projection &t = *_data._projection; + h = hash_murmur3_one_real(t.matrix[0].x, h); + h = hash_murmur3_one_real(t.matrix[0].y, h); + h = hash_murmur3_one_real(t.matrix[0].z, h); + h = hash_murmur3_one_real(t.matrix[0].w, h); + h = hash_murmur3_one_real(t.matrix[1].x, h); + h = hash_murmur3_one_real(t.matrix[1].y, h); + h = hash_murmur3_one_real(t.matrix[1].z, h); + h = hash_murmur3_one_real(t.matrix[1].w, h); + h = hash_murmur3_one_real(t.matrix[2].x, h); + h = hash_murmur3_one_real(t.matrix[2].y, h); + h = hash_murmur3_one_real(t.matrix[2].z, h); + h = hash_murmur3_one_real(t.matrix[2].w, h); + h = hash_murmur3_one_real(t.matrix[3].x, h); + h = hash_murmur3_one_real(t.matrix[3].y, h); + h = hash_murmur3_one_real(t.matrix[3].z, h); + h = hash_murmur3_one_real(t.matrix[3].w, h); + return hash_fmix32(h); + } break; // misc types case COLOR: { uint32_t h = HASH_MURMUR3_SEED; @@ -3062,6 +3301,11 @@ uint32_t Variant::recursive_hash(int recursion_count) const { (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ (hash_compare_scalar((p_lhs).z, (p_rhs).z)) +#define hash_compare_vector4(p_lhs, p_rhs) \ + (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ + (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ + (hash_compare_scalar((p_lhs).z, (p_rhs).z)) && \ + (hash_compare_scalar((p_lhs).w, (p_rhs).w)) #define hash_compare_quaternion(p_lhs, p_rhs) \ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ @@ -3165,6 +3409,18 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const return *l == *r; } break; + case VECTOR4: { + const Vector4 *l = reinterpret_cast<const Vector4 *>(_data._mem); + const Vector4 *r = reinterpret_cast<const Vector4 *>(p_variant._data._mem); + + return hash_compare_vector4(*l, *r); + } break; + case VECTOR4I: { + const Vector4i *l = reinterpret_cast<const Vector4i *>(_data._mem); + const Vector4i *r = reinterpret_cast<const Vector4i *>(p_variant._data._mem); + + return *l == *r; + } break; case PLANE: { const Plane *l = reinterpret_cast<const Plane *>(_data._mem); @@ -3215,6 +3471,18 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const return hash_compare_vector3(l->origin, r->origin); } break; + case PROJECTION: { + const Projection *l = _data._projection; + const Projection *r = p_variant._data._projection; + + for (int i = 0; i < 4; i++) { + if (!(hash_compare_vector4(l->matrix[i], r->matrix[i]))) { + return false; + } + } + + return true; + } break; case COLOR: { const Color *l = reinterpret_cast<const Color *>(_data._mem); diff --git a/core/variant/variant.h b/core/variant/variant.h index 872b374b13..465c31730c 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -38,6 +38,7 @@ #include "core/math/color.h" #include "core/math/face3.h" #include "core/math/plane.h" +#include "core/math/projection.h" #include "core/math/quaternion.h" #include "core/math/rect2.h" #include "core/math/rect2i.h" @@ -47,6 +48,8 @@ #include "core/math/vector2i.h" #include "core/math/vector3.h" #include "core/math/vector3i.h" +#include "core/math/vector4.h" +#include "core/math/vector4i.h" #include "core/object/object_id.h" #include "core/os/keyboard.h" #include "core/string/node_path.h" @@ -91,11 +94,14 @@ public: VECTOR3, VECTOR3I, TRANSFORM2D, + VECTOR4, + VECTOR4I, PLANE, QUATERNION, AABB, BASIS, TRANSFORM3D, + PROJECTION, // misc types COLOR, @@ -210,6 +216,7 @@ private: ::AABB *_aabb; Basis *_basis; Transform3D *_transform3d; + Projection *_projection; PackedArrayRefBase *packed_array; void *_ptr; //generic pointer uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]{ 0 }; @@ -234,11 +241,14 @@ private: false, //VECTOR3, false, //VECTOR3I, true, //TRANSFORM2D, + false, //VECTOR4, + false, //VECTOR4I, false, //PLANE, false, //QUATERNION, true, //AABB, true, //BASIS, true, //TRANSFORM, + true, //PROJECTION, // misc types false, //COLOR, @@ -339,12 +349,15 @@ public: operator Rect2i() const; operator Vector3() const; operator Vector3i() const; + operator Vector4() const; + operator Vector4i() const; operator Plane() const; operator ::AABB() const; operator Quaternion() const; operator Basis() const; operator Transform2D() const; operator Transform3D() const; + operator Projection() const; operator Color() const; operator NodePath() const; @@ -409,12 +422,15 @@ public: Variant(const Rect2i &p_rect2i); Variant(const Vector3 &p_vector3); Variant(const Vector3i &p_vector3i); + Variant(const Vector4 &p_vector4); + Variant(const Vector4i &p_vector4i); Variant(const Plane &p_plane); Variant(const ::AABB &p_aabb); Variant(const Quaternion &p_quat); Variant(const Basis &p_matrix); Variant(const Transform2D &p_transform); Variant(const Transform3D &p_transform); + Variant(const Projection &p_projection); Variant(const Color &p_color); Variant(const NodePath &p_node_path); Variant(const ::RID &p_rid); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 8e16a767cf..56fc16c5a3 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1725,14 +1725,43 @@ static void _register_variant_builtin_methods() { bind_method(Vector3i, abs, sarray(), varray()); bind_method(Vector3i, clamp, sarray("min", "max"), varray()); + /* Vector4 */ + + bind_method(Vector4, min_axis_index, sarray(), varray()); + bind_method(Vector4, max_axis_index, sarray(), varray()); + bind_method(Vector4, length, sarray(), varray()); + bind_method(Vector4, length_squared, sarray(), varray()); + bind_method(Vector4, abs, sarray(), varray()); + bind_method(Vector4, sign, sarray(), varray()); + bind_method(Vector4, floor, sarray(), varray()); + bind_method(Vector4, ceil, sarray(), varray()); + bind_method(Vector4, round, sarray(), varray()); + bind_method(Vector4, lerp, sarray("to", "weight"), varray()); + bind_method(Vector4, clamp, sarray("min", "max"), varray()); + bind_method(Vector4, normalized, sarray(), varray()); + bind_method(Vector4, is_normalized, sarray(), varray()); + bind_method(Vector4, dot, sarray("with"), varray()); + bind_method(Vector4, inverse, sarray(), varray()); + bind_method(Vector4, is_equal_approx, sarray("with"), varray()); + + /* Vector4i */ + + bind_method(Vector4i, min_axis_index, sarray(), varray()); + bind_method(Vector4i, max_axis_index, sarray(), varray()); + bind_method(Vector4i, length, sarray(), varray()); + bind_method(Vector4i, length_squared, sarray(), varray()); + bind_method(Vector4i, sign, sarray(), varray()); + bind_method(Vector4i, abs, sarray(), varray()); + bind_method(Vector4i, clamp, sarray("min", "max"), varray()); + /* Plane */ bind_method(Plane, normalized, sarray(), varray()); bind_method(Plane, center, sarray(), varray()); bind_method(Plane, is_equal_approx, sarray("to_plane"), varray()); - bind_method(Plane, is_point_over, sarray("plane"), varray()); + bind_method(Plane, is_point_over, sarray("point"), varray()); bind_method(Plane, distance_to, sarray("point"), varray()); - bind_method(Plane, has_point, sarray("point", "epsilon"), varray(CMP_EPSILON)); + bind_method(Plane, has_point, sarray("point", "tolerance"), varray(CMP_EPSILON)); bind_method(Plane, project, sarray("point"), varray()); bind_methodv(Plane, intersect_3, &Plane::intersect_3_bind, sarray("b", "c"), varray()); bind_methodv(Plane, intersects_ray, &Plane::intersects_ray_bind, sarray("from", "dir"), varray()); @@ -1752,7 +1781,7 @@ static void _register_variant_builtin_methods() { bind_method(Quaternion, dot, sarray("with"), varray()); bind_method(Quaternion, slerp, sarray("to", "weight"), varray()); bind_method(Quaternion, slerpni, sarray("to", "weight"), varray()); - bind_method(Quaternion, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray()); + bind_method(Quaternion, spherical_cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray()); bind_method(Quaternion, get_euler, sarray(), varray()); bind_method(Quaternion, get_axis, sarray(), varray()); bind_method(Quaternion, get_angle, sarray(), varray()); @@ -1854,7 +1883,7 @@ static void _register_variant_builtin_methods() { bind_method(Transform2D, orthonormalized, sarray(), varray()); bind_method(Transform2D, rotated, sarray("angle"), varray()); bind_method(Transform2D, scaled, sarray("scale"), varray()); - bind_method(Transform2D, translated, sarray("offset"), varray()); + bind_method(Transform2D, translated_local, sarray("offset"), varray()); bind_method(Transform2D, basis_xform, sarray("v"), varray()); bind_method(Transform2D, basis_xform_inv, sarray("v"), varray()); bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray()); @@ -1919,12 +1948,46 @@ static void _register_variant_builtin_methods() { bind_method(Transform3D, orthonormalized, sarray(), varray()); bind_method(Transform3D, rotated, sarray("axis", "angle"), varray()); bind_method(Transform3D, scaled, sarray("scale"), varray()); - bind_method(Transform3D, translated, sarray("offset"), varray()); + bind_method(Transform3D, translated_local, sarray("offset"), varray()); bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); - bind_method(Transform3D, sphere_interpolate_with, sarray("xform", "weight"), varray()); + bind_method(Transform3D, spherical_interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform3D, is_equal_approx, sarray("xform"), varray()); + /* Projection */ + + bind_static_method(Projection, create_depth_correction, sarray("flip_y"), varray()); + bind_static_method(Projection, create_light_atlas_rect, sarray("rect"), varray()); + bind_static_method(Projection, create_perspective, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov"), varray(false)); + bind_static_method(Projection, create_perspective_hmd, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov", "eye", "intraocular_dist", " convergence_dist"), varray()); + bind_static_method(Projection, create_for_hmd, sarray("eye", "aspect", "intraocular_dist", "display_width", "display_to_lens", "oversample", "z_near", "z_far"), varray()); + bind_static_method(Projection, create_orthogonal, sarray("left", "right", "bottom", "top", "z_near", "z_far"), varray()); + bind_static_method(Projection, create_orthogonal_aspect, sarray("size", "aspect", "z_near", "z_far", "flip_fov"), varray(false)); + bind_static_method(Projection, create_frustum, sarray("left", "right", "bottom", "top", "z_near", "z_far"), varray()); + bind_static_method(Projection, create_frustum_aspect, sarray("size", "aspect", "offset", "z_near", "z_far", "flip_fov"), varray(false)); + bind_static_method(Projection, create_fit_aabb, sarray("aabb"), varray()); + + bind_method(Projection, determinant, sarray(), varray()); + bind_method(Projection, perspective_znear_adjusted, sarray("new_znear"), varray()); + bind_method(Projection, get_projection_plane, sarray("plane"), varray()); + bind_method(Projection, flipped_y, sarray(), varray()); + bind_method(Projection, jitter_offseted, sarray("offset"), varray()); + + bind_static_method(Projection, get_fovy, sarray("fovx", "aspect"), varray()); + + bind_method(Projection, get_z_far, sarray(), varray()); + bind_method(Projection, get_z_near, sarray(), varray()); + bind_method(Projection, get_aspect, sarray(), varray()); + bind_method(Projection, get_fov, sarray(), varray()); + bind_method(Projection, is_orthogonal, sarray(), varray()); + + bind_method(Projection, get_viewport_half_extents, sarray(), varray()); + bind_method(Projection, get_far_plane_half_extents, sarray(), varray()); + + bind_method(Projection, inverse, sarray(), varray()); + bind_method(Projection, get_pixels_per_meter, sarray("for_pixel_width"), varray()); + bind_method(Projection, get_lod_multiplier, sarray(), varray()); + /* Dictionary */ bind_method(Dictionary, size, sarray(), varray()); @@ -2253,6 +2316,19 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1)); _VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1)); + _VariantCall::add_constant(Variant::VECTOR4, "AXIS_X", Vector4::AXIS_X); + _VariantCall::add_constant(Variant::VECTOR4, "AXIS_Y", Vector4::AXIS_Y); + _VariantCall::add_constant(Variant::VECTOR4, "AXIS_Z", Vector4::AXIS_Z); + _VariantCall::add_constant(Variant::VECTOR4, "AXIS_W", Vector4::AXIS_W); + + _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_X", Vector4::AXIS_X); + _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_Y", Vector4::AXIS_Y); + _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_Z", Vector4::AXIS_Z); + _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_W", Vector4::AXIS_W); + _VariantCall::add_variant_constant(Variant::VECTOR4, "ZERO", Vector4(0, 0, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR4, "ONE", Vector4(1, 1, 1, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR4, "INF", Vector4(INFINITY, INFINITY, INFINITY, INFINITY)); + _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_X", Vector3i::AXIS_X); _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Y", Vector3i::AXIS_Y); _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Z", Vector3i::AXIS_Z); @@ -2261,6 +2337,19 @@ static void _register_variant_builtin_methods() { _VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_Y", Vector3i::AXIS_Y); _VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_Z", Vector3i::AXIS_Z); + _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_X", Vector4i::AXIS_X); + _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_Y", Vector4i::AXIS_Y); + _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_Z", Vector4i::AXIS_Z); + _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_W", Vector4i::AXIS_W); + + _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_X", Vector4i::AXIS_X); + _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_Y", Vector4i::AXIS_Y); + _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_Z", Vector4i::AXIS_Z); + _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_W", Vector4i::AXIS_W); + + _VariantCall::add_variant_constant(Variant::VECTOR4I, "ZERO", Vector4i(0, 0, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR4I, "ONE", Vector4i(1, 1, 1, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "ZERO", Vector3i(0, 0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR3I, "ONE", Vector3i(1, 1, 1)); _VariantCall::add_variant_constant(Variant::VECTOR3I, "LEFT", Vector3i(-1, 0, 0)); @@ -2338,6 +2427,25 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XY", Plane(Vector3(0, 0, 1), 0)); _VariantCall::add_variant_constant(Variant::QUATERNION, "IDENTITY", Quaternion(0, 0, 0, 1)); + + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_NEAR", Projection::PLANE_NEAR); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_FAR", Projection::PLANE_FAR); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_LEFT", Projection::PLANE_LEFT); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_TOP", Projection::PLANE_TOP); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_RIGHT", Projection::PLANE_RIGHT); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_BOTTOM", Projection::PLANE_BOTTOM); + + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_NEAR", Projection::PLANE_NEAR); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_FAR", Projection::PLANE_FAR); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_LEFT", Projection::PLANE_LEFT); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_TOP", Projection::PLANE_TOP); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_RIGHT", Projection::PLANE_RIGHT); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_BOTTOM", Projection::PLANE_BOTTOM); + + Projection p; + _VariantCall::add_variant_constant(Variant::PROJECTION, "IDENTITY", p); + p.set_zero(); + _VariantCall::add_variant_constant(Variant::PROJECTION, "ZERO", p); } void Variant::_register_variant_methods() { diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 78d5433d8c..3a0b6c1bb9 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -111,6 +111,16 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<Vector3i, Vector3>>(sarray("from")); add_constructor<VariantConstructor<Vector3i, int64_t, int64_t, int64_t>>(sarray("x", "y", "z")); + add_constructor<VariantConstructNoArgs<Vector4>>(sarray()); + add_constructor<VariantConstructor<Vector4, Vector4>>(sarray("from")); + add_constructor<VariantConstructor<Vector4, Vector4i>>(sarray("from")); + add_constructor<VariantConstructor<Vector4, double, double, double, double>>(sarray("x", "y", "z", "w")); + + add_constructor<VariantConstructNoArgs<Vector4i>>(sarray()); + add_constructor<VariantConstructor<Vector4i, Vector4i>>(sarray("from")); + add_constructor<VariantConstructor<Vector4i, Vector4>>(sarray("from")); + add_constructor<VariantConstructor<Vector4i, int64_t, int64_t, int64_t, int64_t>>(sarray("x", "y", "z", "w")); + add_constructor<VariantConstructNoArgs<Transform2D>>(sarray()); add_constructor<VariantConstructor<Transform2D, Transform2D>>(sarray("from")); add_constructor<VariantConstructor<Transform2D, float, Vector2>>(sarray("rotation", "position")); @@ -147,6 +157,11 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<Transform3D, Transform3D>>(sarray("from")); add_constructor<VariantConstructor<Transform3D, Basis, Vector3>>(sarray("basis", "origin")); add_constructor<VariantConstructor<Transform3D, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin")); + add_constructor<VariantConstructor<Transform3D, Projection>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<Projection>>(sarray()); + add_constructor<VariantConstructor<Projection, Projection>>(sarray("from")); + add_constructor<VariantConstructor<Projection, Transform3D>>(sarray("from")); add_constructor<VariantConstructNoArgs<Color>>(sarray()); add_constructor<VariantConstructor<Color, Color>>(sarray("from")); diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h index 638c0136f3..58a0f34c1e 100644 --- a/core/variant/variant_construct.h +++ b/core/variant/variant_construct.h @@ -63,12 +63,15 @@ MAKE_PTRCONSTRUCT(Rect2); MAKE_PTRCONSTRUCT(Rect2i); MAKE_PTRCONSTRUCT(Vector3); MAKE_PTRCONSTRUCT(Vector3i); +MAKE_PTRCONSTRUCT(Vector4); +MAKE_PTRCONSTRUCT(Vector4i); MAKE_PTRCONSTRUCT(Transform2D); MAKE_PTRCONSTRUCT(Plane); MAKE_PTRCONSTRUCT(Quaternion); MAKE_PTRCONSTRUCT(AABB); MAKE_PTRCONSTRUCT(Basis); MAKE_PTRCONSTRUCT(Transform3D); +MAKE_PTRCONSTRUCT(Projection); MAKE_PTRCONSTRUCT(Color); MAKE_PTRCONSTRUCT(StringName); MAKE_PTRCONSTRUCT(NodePath); diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index e0cfb42e1e..961c0f3a51 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -138,6 +138,10 @@ public: _FORCE_INLINE_ static const Vector3 *get_vector3(const Variant *v) { return reinterpret_cast<const Vector3 *>(v->_data._mem); } _FORCE_INLINE_ static Vector3i *get_vector3i(Variant *v) { return reinterpret_cast<Vector3i *>(v->_data._mem); } _FORCE_INLINE_ static const Vector3i *get_vector3i(const Variant *v) { return reinterpret_cast<const Vector3i *>(v->_data._mem); } + _FORCE_INLINE_ static Vector4 *get_vector4(Variant *v) { return reinterpret_cast<Vector4 *>(v->_data._mem); } + _FORCE_INLINE_ static const Vector4 *get_vector4(const Variant *v) { return reinterpret_cast<const Vector4 *>(v->_data._mem); } + _FORCE_INLINE_ static Vector4i *get_vector4i(Variant *v) { return reinterpret_cast<Vector4i *>(v->_data._mem); } + _FORCE_INLINE_ static const Vector4i *get_vector4i(const Variant *v) { return reinterpret_cast<const Vector4i *>(v->_data._mem); } _FORCE_INLINE_ static Transform2D *get_transform2d(Variant *v) { return v->_data._transform2d; } _FORCE_INLINE_ static const Transform2D *get_transform2d(const Variant *v) { return v->_data._transform2d; } _FORCE_INLINE_ static Plane *get_plane(Variant *v) { return reinterpret_cast<Plane *>(v->_data._mem); } @@ -150,6 +154,8 @@ public: _FORCE_INLINE_ static const Basis *get_basis(const Variant *v) { return v->_data._basis; } _FORCE_INLINE_ static Transform3D *get_transform(Variant *v) { return v->_data._transform3d; } _FORCE_INLINE_ static const Transform3D *get_transform(const Variant *v) { return v->_data._transform3d; } + _FORCE_INLINE_ static Projection *get_projection(Variant *v) { return v->_data._projection; } + _FORCE_INLINE_ static const Projection *get_projection(const Variant *v) { return v->_data._projection; } // Misc types. _FORCE_INLINE_ static Color *get_color(Variant *v) { return reinterpret_cast<Color *>(v->_data._mem); } @@ -224,6 +230,10 @@ public: v->_data._transform3d = memnew(Transform3D); v->type = Variant::TRANSFORM3D; } + _FORCE_INLINE_ static void init_projection(Variant *v) { + v->_data._projection = memnew(Projection); + v->type = Variant::PROJECTION; + } _FORCE_INLINE_ static void init_string_name(Variant *v) { memnew_placement(v->_data._mem, StringName); v->type = Variant::STRING_NAME; @@ -331,12 +341,18 @@ public: return get_vector3(v); case Variant::VECTOR3I: return get_vector3i(v); + case Variant::VECTOR4: + return get_vector4(v); + case Variant::VECTOR4I: + return get_vector4i(v); case Variant::RECT2: return get_rect2(v); case Variant::RECT2I: return get_rect2i(v); case Variant::TRANSFORM3D: return get_transform(v); + case Variant::PROJECTION: + return get_projection(v); case Variant::TRANSFORM2D: return get_transform2d(v); case Variant::QUATERNION: @@ -409,12 +425,18 @@ public: return get_vector3(v); case Variant::VECTOR3I: return get_vector3i(v); + case Variant::VECTOR4: + return get_vector4(v); + case Variant::VECTOR4I: + return get_vector4i(v); case Variant::RECT2: return get_rect2(v); case Variant::RECT2I: return get_rect2i(v); case Variant::TRANSFORM3D: return get_transform(v); + case Variant::PROJECTION: + return get_projection(v); case Variant::TRANSFORM2D: return get_transform2d(v); case Variant::QUATERNION: @@ -599,6 +621,17 @@ struct VariantGetInternalPtr<Vector3i> { }; template <> +struct VariantGetInternalPtr<Vector4> { + static Vector4 *get_ptr(Variant *v) { return VariantInternal::get_vector4(v); } + static const Vector4 *get_ptr(const Variant *v) { return VariantInternal::get_vector4(v); } +}; + +template <> +struct VariantGetInternalPtr<Vector4i> { + static Vector4i *get_ptr(Variant *v) { return VariantInternal::get_vector4i(v); } + static const Vector4i *get_ptr(const Variant *v) { return VariantInternal::get_vector4i(v); } +}; +template <> struct VariantGetInternalPtr<Transform2D> { static Transform2D *get_ptr(Variant *v) { return VariantInternal::get_transform2d(v); } static const Transform2D *get_ptr(const Variant *v) { return VariantInternal::get_transform2d(v); } @@ -611,6 +644,12 @@ struct VariantGetInternalPtr<Transform3D> { }; template <> +struct VariantGetInternalPtr<Projection> { + static Projection *get_ptr(Variant *v) { return VariantInternal::get_projection(v); } + static const Projection *get_ptr(const Variant *v) { return VariantInternal::get_projection(v); } +}; + +template <> struct VariantGetInternalPtr<Plane> { static Plane *get_ptr(Variant *v) { return VariantInternal::get_plane(v); } static const Plane *get_ptr(const Variant *v) { return VariantInternal::get_plane(v); } @@ -772,6 +811,10 @@ VARIANT_ACCESSOR_NUMBER(Vector2::Axis) VARIANT_ACCESSOR_NUMBER(Vector2i::Axis) VARIANT_ACCESSOR_NUMBER(Vector3::Axis) VARIANT_ACCESSOR_NUMBER(Vector3i::Axis) +VARIANT_ACCESSOR_NUMBER(Vector4::Axis) +VARIANT_ACCESSOR_NUMBER(Vector4i::Axis) + +VARIANT_ACCESSOR_NUMBER(Projection::Planes) template <> struct VariantInternalAccessor<Basis::EulerOrder> { @@ -840,6 +883,17 @@ struct VariantInternalAccessor<Vector3i> { }; template <> +struct VariantInternalAccessor<Vector4> { + static _FORCE_INLINE_ const Vector4 &get(const Variant *v) { return *VariantInternal::get_vector4(v); } + static _FORCE_INLINE_ void set(Variant *v, const Vector4 &p_value) { *VariantInternal::get_vector4(v) = p_value; } +}; + +template <> +struct VariantInternalAccessor<Vector4i> { + static _FORCE_INLINE_ const Vector4i &get(const Variant *v) { return *VariantInternal::get_vector4i(v); } + static _FORCE_INLINE_ void set(Variant *v, const Vector4i &p_value) { *VariantInternal::get_vector4i(v) = p_value; } +}; +template <> struct VariantInternalAccessor<Transform2D> { static _FORCE_INLINE_ const Transform2D &get(const Variant *v) { return *VariantInternal::get_transform2d(v); } static _FORCE_INLINE_ void set(Variant *v, const Transform2D &p_value) { *VariantInternal::get_transform2d(v) = p_value; } @@ -852,6 +906,12 @@ struct VariantInternalAccessor<Transform3D> { }; template <> +struct VariantInternalAccessor<Projection> { + static _FORCE_INLINE_ const Projection &get(const Variant *v) { return *VariantInternal::get_projection(v); } + static _FORCE_INLINE_ void set(Variant *v, const Projection &p_value) { *VariantInternal::get_projection(v) = p_value; } +}; + +template <> struct VariantInternalAccessor<Plane> { static _FORCE_INLINE_ const Plane &get(const Variant *v) { return *VariantInternal::get_plane(v); } static _FORCE_INLINE_ void set(Variant *v, const Plane &p_value) { *VariantInternal::get_plane(v) = p_value; } @@ -1041,6 +1101,8 @@ INITIALIZER_INT(Vector2::Axis) INITIALIZER_INT(Vector2i::Axis) INITIALIZER_INT(Vector3::Axis) INITIALIZER_INT(Vector3i::Axis) +INITIALIZER_INT(Vector4::Axis) +INITIALIZER_INT(Vector4i::Axis) template <> struct VariantInitializer<double> { @@ -1086,8 +1148,16 @@ template <> struct VariantInitializer<Vector3i> { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3i>(v); } }; +template <> +struct VariantInitializer<Vector4> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector4>(v); } +}; template <> +struct VariantInitializer<Vector4i> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector4i>(v); } +}; +template <> struct VariantInitializer<Transform2D> { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform2d(v); } }; @@ -1116,6 +1186,10 @@ template <> struct VariantInitializer<Transform3D> { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform(v); } }; +template <> +struct VariantInitializer<Projection> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_projection(v); } +}; template <> struct VariantInitializer<Color> { @@ -1267,6 +1341,16 @@ struct VariantZeroAssigner<Vector3i> { }; template <> +struct VariantZeroAssigner<Vector4> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector4(v) = Vector4(); } +}; + +template <> +struct VariantZeroAssigner<Vector4i> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector4i(v) = Vector4i(); } +}; + +template <> struct VariantZeroAssigner<Transform2D> { static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform2d(v) = Transform2D(); } }; @@ -1297,6 +1381,11 @@ struct VariantZeroAssigner<Transform3D> { }; template <> +struct VariantZeroAssigner<Projection> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_projection(v) = Projection(); } +}; + +template <> struct VariantZeroAssigner<Color> { static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_color(v) = Color(); } }; diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index adace2b534..669e18b5f7 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -165,6 +165,70 @@ public: static Variant::Type get_return_type() { return GetTypeInfo<Vector3>::VARIANT_TYPE; } }; +// + +template <> +class OperatorEvaluatorMul<Vector4, Vector4i, double> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left); + const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_right); + *r_ret = Vector4(a.x, a.y, a.z, a.w) * b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(left)->x, VariantGetInternalPtr<Vector4i>::get_ptr(left)->y, VariantGetInternalPtr<Vector4i>::get_ptr(left)->z, VariantGetInternalPtr<Vector4i>::get_ptr(left)->w) * *VariantGetInternalPtr<double>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(left).x, PtrToArg<Vector4i>::convert(left).y, PtrToArg<Vector4i>::convert(left).z, PtrToArg<Vector4i>::convert(left).w) * PtrToArg<double>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; } +}; + +template <> +class OperatorEvaluatorMul<Vector4, double, Vector4i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right); + const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_left); + *r_ret = Vector4(a.x, a.y, a.z, a.w) * b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(right)->x, VariantGetInternalPtr<Vector4i>::get_ptr(right)->y, VariantGetInternalPtr<Vector4i>::get_ptr(right)->z, VariantGetInternalPtr<Vector4i>::get_ptr(right)->w) * *VariantGetInternalPtr<double>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(right).x, PtrToArg<Vector4i>::convert(right).y, PtrToArg<Vector4i>::convert(right).z, PtrToArg<Vector4i>::convert(right).w) * PtrToArg<double>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; } +}; + +template <> +class OperatorEvaluatorDivNZ<Vector4, Vector4i, double> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left); + const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_right); + if (unlikely(b == 0)) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = Vector4(a.x, a.y, a.z, a.w) / b; + r_valid = true; + } + + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(left)->x, VariantGetInternalPtr<Vector4i>::get_ptr(left)->y, VariantGetInternalPtr<Vector4i>::get_ptr(left)->z, VariantGetInternalPtr<Vector4i>::get_ptr(left)->w) / *VariantGetInternalPtr<double>::get_ptr(right); + } + + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(left).x, PtrToArg<Vector4i>::convert(left).y, PtrToArg<Vector4i>::convert(left).z, PtrToArg<Vector4i>::convert(left).w) / PtrToArg<double>::convert(right), r_ret); + } + + static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; } +}; + void Variant::_register_variant_operators() { memset(operator_return_type_table, 0, sizeof(operator_return_type_table)); memset(operator_evaluator_table, 0, sizeof(operator_evaluator_table)); @@ -182,6 +246,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorAdd<Vector3i, Vector3i, Vector3i>>(Variant::OP_ADD, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorAdd<Vector4, Vector4, Vector4>>(Variant::OP_ADD, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorAdd<Vector4i, Vector4i, Vector4i>>(Variant::OP_ADD, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorAdd<Quaternion, Quaternion, Quaternion>>(Variant::OP_ADD, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorAdd<Color, Color, Color>>(Variant::OP_ADD, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorAddArray>(Variant::OP_ADD, Variant::ARRAY, Variant::ARRAY); @@ -203,6 +269,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorSub<Vector2i, Vector2i, Vector2i>>(Variant::OP_SUBTRACT, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorSub<Vector3, Vector3, Vector3>>(Variant::OP_SUBTRACT, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorSub<Vector3i, Vector3i, Vector3i>>(Variant::OP_SUBTRACT, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorSub<Vector4, Vector4, Vector4>>(Variant::OP_SUBTRACT, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorSub<Vector4i, Vector4i, Vector4i>>(Variant::OP_SUBTRACT, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorSub<Quaternion, Quaternion, Quaternion>>(Variant::OP_SUBTRACT, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorSub<Color, Color, Color>>(Variant::OP_SUBTRACT, Variant::COLOR, Variant::COLOR); @@ -212,6 +280,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Vector2i, int64_t, Vector2i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR2I); register_op<OperatorEvaluatorMul<Vector3, int64_t, Vector3>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR3); register_op<OperatorEvaluatorMul<Vector3i, int64_t, Vector3i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR3I); + register_op<OperatorEvaluatorMul<Vector4, int64_t, Vector4>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR4); + register_op<OperatorEvaluatorMul<Vector4i, int64_t, Vector4i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR4I); register_op<OperatorEvaluatorMul<double, double, double>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::FLOAT); register_op<OperatorEvaluatorMul<double, double, int64_t>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::INT); @@ -219,6 +289,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Vector2, double, Vector2i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR2I); register_op<OperatorEvaluatorMul<Vector3, double, Vector3>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR3); register_op<OperatorEvaluatorMul<Vector3, double, Vector3i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR3I); + register_op<OperatorEvaluatorMul<Vector4, double, Vector4>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR4); + register_op<OperatorEvaluatorMul<Vector4, double, Vector4i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR4I); register_op<OperatorEvaluatorMul<Vector2, Vector2, Vector2>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::VECTOR2); register_op<OperatorEvaluatorMul<Vector2, Vector2, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::INT); @@ -236,6 +308,14 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Vector3i, Vector3i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::INT); register_op<OperatorEvaluatorMul<Vector3, Vector3i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Vector4, Vector4, Vector4>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorMul<Vector4, Vector4, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::INT); + register_op<OperatorEvaluatorMul<Vector4, Vector4, double>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::FLOAT); + + register_op<OperatorEvaluatorMul<Vector4i, Vector4i, Vector4i>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::VECTOR4I); + register_op<OperatorEvaluatorMul<Vector4i, Vector4i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::INT); + register_op<OperatorEvaluatorMul<Vector4, Vector4i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Quaternion, Quaternion, Quaternion>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorMul<Quaternion, Quaternion, int64_t>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::INT); register_op<OperatorEvaluatorMul<Quaternion, Quaternion, double>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::FLOAT); @@ -264,6 +344,11 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform3D, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::PACKED_VECTOR3_ARRAY); register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform3D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorXForm<Vector4, Projection, Vector4>>(Variant::OP_MULTIPLY, Variant::PROJECTION, Variant::VECTOR4); + register_op<OperatorEvaluatorXFormInv<Vector4, Vector4, Projection>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::PROJECTION); + + register_op<OperatorEvaluatorMul<Projection, Projection, Projection>>(Variant::OP_MULTIPLY, Variant::PROJECTION, Variant::PROJECTION); + register_op<OperatorEvaluatorMul<Basis, Basis, Basis>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorMul<Basis, Basis, int64_t>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::INT); register_op<OperatorEvaluatorMul<Basis, Basis, double>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::FLOAT); @@ -309,6 +394,14 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorDivNZ<Vector3, Vector3i, double>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::FLOAT); register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::INT); + register_op<OperatorEvaluatorDiv<Vector4, Vector4, Vector4>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorDiv<Vector4, Vector4, double>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<Vector4, Vector4, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::INT); + + register_op<OperatorEvaluatorDivNZ<Vector4i, Vector4i, Vector4i>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::VECTOR4I); + register_op<OperatorEvaluatorDivNZ<Vector4, Vector4i, double>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::FLOAT); + register_op<OperatorEvaluatorDivNZ<Vector4i, Vector4i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::INT); + register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, double>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::FLOAT); register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, int64_t>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::INT); @@ -323,6 +416,9 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, Vector3i>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::VECTOR3I); register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::INT); + register_op<OperatorEvaluatorModNZ<Vector4i, Vector4i, Vector4i>>(Variant::OP_MODULE, Variant::VECTOR4I, Variant::VECTOR4I); + register_op<OperatorEvaluatorModNZ<Vector4i, Vector4i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR4I, Variant::INT); + register_op<OperatorEvaluatorStringModNil>(Variant::OP_MODULE, Variant::STRING, Variant::NIL); register_op<OperatorEvaluatorStringModT<bool>>(Variant::OP_MODULE, Variant::STRING, Variant::BOOL); @@ -335,12 +431,15 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorStringModT<Rect2i>>(Variant::OP_MODULE, Variant::STRING, Variant::RECT2I); register_op<OperatorEvaluatorStringModT<Vector3>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3); register_op<OperatorEvaluatorStringModT<Vector3i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3I); + register_op<OperatorEvaluatorStringModT<Vector4>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR4); + register_op<OperatorEvaluatorStringModT<Vector4i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR4I); register_op<OperatorEvaluatorStringModT<Transform2D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM2D); register_op<OperatorEvaluatorStringModT<Plane>>(Variant::OP_MODULE, Variant::STRING, Variant::PLANE); register_op<OperatorEvaluatorStringModT<Quaternion>>(Variant::OP_MODULE, Variant::STRING, Variant::QUATERNION); register_op<OperatorEvaluatorStringModT<::AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB); register_op<OperatorEvaluatorStringModT<Basis>>(Variant::OP_MODULE, Variant::STRING, Variant::BASIS); register_op<OperatorEvaluatorStringModT<Transform3D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorStringModT<Projection>>(Variant::OP_MODULE, Variant::STRING, Variant::PROJECTION); register_op<OperatorEvaluatorStringModT<Color>>(Variant::OP_MODULE, Variant::STRING, Variant::COLOR); register_op<OperatorEvaluatorStringModT<StringName>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING_NAME); @@ -372,6 +471,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNeg<Vector2i, Vector2i>>(Variant::OP_NEGATE, Variant::VECTOR2I, Variant::NIL); register_op<OperatorEvaluatorNeg<Vector3, Vector3>>(Variant::OP_NEGATE, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorNeg<Vector3i, Vector3i>>(Variant::OP_NEGATE, Variant::VECTOR3I, Variant::NIL); + register_op<OperatorEvaluatorNeg<Vector4, Vector4>>(Variant::OP_NEGATE, Variant::VECTOR4, Variant::NIL); + register_op<OperatorEvaluatorNeg<Vector4i, Vector4i>>(Variant::OP_NEGATE, Variant::VECTOR4I, Variant::NIL); register_op<OperatorEvaluatorNeg<Quaternion, Quaternion>>(Variant::OP_NEGATE, Variant::QUATERNION, Variant::NIL); register_op<OperatorEvaluatorNeg<Plane, Plane>>(Variant::OP_NEGATE, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorNeg<Color, Color>>(Variant::OP_NEGATE, Variant::COLOR, Variant::NIL); @@ -382,6 +483,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorPos<Vector2i, Vector2i>>(Variant::OP_POSITIVE, Variant::VECTOR2I, Variant::NIL); register_op<OperatorEvaluatorPos<Vector3, Vector3>>(Variant::OP_POSITIVE, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorPos<Vector3i, Vector3i>>(Variant::OP_POSITIVE, Variant::VECTOR3I, Variant::NIL); + register_op<OperatorEvaluatorPos<Vector4, Vector4>>(Variant::OP_POSITIVE, Variant::VECTOR4, Variant::NIL); + register_op<OperatorEvaluatorPos<Vector4i, Vector4i>>(Variant::OP_POSITIVE, Variant::VECTOR4I, Variant::NIL); register_op<OperatorEvaluatorPos<Quaternion, Quaternion>>(Variant::OP_POSITIVE, Variant::QUATERNION, Variant::NIL); register_op<OperatorEvaluatorPos<Plane, Plane>>(Variant::OP_POSITIVE, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorPos<Color, Color>>(Variant::OP_POSITIVE, Variant::COLOR, Variant::NIL); @@ -409,11 +512,14 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorEqual<Vector3, Vector3>>(Variant::OP_EQUAL, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorEqual<Vector3i, Vector3i>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); register_op<OperatorEvaluatorEqual<Transform2D, Transform2D>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorEqual<Vector4, Vector4>>(Variant::OP_EQUAL, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorEqual<Vector4i, Vector4i>>(Variant::OP_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorEqual<Plane, Plane>>(Variant::OP_EQUAL, Variant::PLANE, Variant::PLANE); register_op<OperatorEvaluatorEqual<Quaternion, Quaternion>>(Variant::OP_EQUAL, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorEqual<::AABB, ::AABB>>(Variant::OP_EQUAL, Variant::AABB, Variant::AABB); register_op<OperatorEvaluatorEqual<Basis, Basis>>(Variant::OP_EQUAL, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorEqual<Transform3D, Transform3D>>(Variant::OP_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorEqual<Projection, Projection>>(Variant::OP_EQUAL, Variant::PROJECTION, Variant::PROJECTION); register_op<OperatorEvaluatorEqual<Color, Color>>(Variant::OP_EQUAL, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorEqual<StringName, String>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING); @@ -451,6 +557,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::RECT2I, Variant::NIL>>(Variant::OP_EQUAL, Variant::RECT2I, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR3, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR3I, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::NIL); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR4, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR4, Variant::NIL); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR4I, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR4I, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::NIL>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::PLANE, Variant::NIL>>(Variant::OP_EQUAL, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::QUATERNION, Variant::NIL>>(Variant::OP_EQUAL, Variant::QUATERNION, Variant::NIL); @@ -485,6 +593,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::RECT2I>>(Variant::OP_EQUAL, Variant::NIL, Variant::RECT2I); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3I>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3I); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4I>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4I); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::TRANSFORM2D>>(Variant::OP_EQUAL, Variant::NIL, Variant::TRANSFORM2D); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::PLANE>>(Variant::OP_EQUAL, Variant::NIL, Variant::PLANE); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::QUATERNION>>(Variant::OP_EQUAL, Variant::NIL, Variant::QUATERNION); @@ -522,12 +632,15 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNotEqual<Rect2i, Rect2i>>(Variant::OP_NOT_EQUAL, Variant::RECT2I, Variant::RECT2I); register_op<OperatorEvaluatorNotEqual<Vector3, Vector3>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorNotEqual<Vector3i, Vector3i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorNotEqual<Vector4, Vector4>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorNotEqual<Vector4i, Vector4i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorNotEqual<Transform2D, Transform2D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); register_op<OperatorEvaluatorNotEqual<Plane, Plane>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::PLANE); register_op<OperatorEvaluatorNotEqual<Quaternion, Quaternion>>(Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorNotEqual<::AABB, ::AABB>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::AABB); register_op<OperatorEvaluatorNotEqual<Basis, Basis>>(Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorNotEqual<Transform3D, Transform3D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorNotEqual<Projection, Projection>>(Variant::OP_NOT_EQUAL, Variant::PROJECTION, Variant::PROJECTION); register_op<OperatorEvaluatorNotEqual<Color, Color>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorNotEqual<StringName, String>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING); @@ -566,6 +679,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::NIL); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::NIL); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::AABB, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::NIL); @@ -599,6 +714,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::RECT2I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::RECT2I); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3I); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4I); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::TRANSFORM2D>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::TRANSFORM2D); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::PLANE>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::PLANE); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::QUATERNION>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::QUATERNION); @@ -634,6 +751,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorLess<Vector2i, Vector2i>>(Variant::OP_LESS, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorLess<Vector3, Vector3>>(Variant::OP_LESS, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorLess<Vector3i, Vector3i>>(Variant::OP_LESS, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorLess<Vector4, Vector4>>(Variant::OP_LESS, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorLess<Vector4i, Vector4i>>(Variant::OP_LESS, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorLess<::RID, ::RID>>(Variant::OP_LESS, Variant::RID, Variant::RID); register_op<OperatorEvaluatorLess<Array, Array>>(Variant::OP_LESS, Variant::ARRAY, Variant::ARRAY); @@ -647,6 +766,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorLessEqual<Vector2i, Vector2i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorLessEqual<Vector3, Vector3>>(Variant::OP_LESS_EQUAL, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorLessEqual<Vector3i, Vector3i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorLessEqual<Vector4, Vector4>>(Variant::OP_LESS_EQUAL, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorLessEqual<Vector4i, Vector4i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorLessEqual<::RID, ::RID>>(Variant::OP_LESS_EQUAL, Variant::RID, Variant::RID); register_op<OperatorEvaluatorLessEqual<Array, Array>>(Variant::OP_LESS_EQUAL, Variant::ARRAY, Variant::ARRAY); @@ -661,6 +782,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorGreater<Vector2i, Vector2i>>(Variant::OP_GREATER, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorGreater<Vector3, Vector3>>(Variant::OP_GREATER, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorGreater<Vector3i, Vector3i>>(Variant::OP_GREATER, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorGreater<Vector4, Vector4>>(Variant::OP_GREATER, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorGreater<Vector4i, Vector4i>>(Variant::OP_GREATER, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorGreater<::RID, ::RID>>(Variant::OP_GREATER, Variant::RID, Variant::RID); register_op<OperatorEvaluatorGreater<Array, Array>>(Variant::OP_GREATER, Variant::ARRAY, Variant::ARRAY); @@ -674,6 +797,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorGreaterEqual<Vector2i, Vector2i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorGreaterEqual<Vector3, Vector3>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorGreaterEqual<Vector3i, Vector3i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorGreaterEqual<Vector4, Vector4>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorGreaterEqual<Vector4i, Vector4i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorGreaterEqual<::RID, ::RID>>(Variant::OP_GREATER_EQUAL, Variant::RID, Variant::RID); register_op<OperatorEvaluatorGreaterEqual<Array, Array>>(Variant::OP_GREATER_EQUAL, Variant::ARRAY, Variant::ARRAY); @@ -788,12 +913,15 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorInDictionaryHas<Rect2i>>(Variant::OP_IN, Variant::RECT2I, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Vector3>>(Variant::OP_IN, Variant::VECTOR3, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Vector3i>>(Variant::OP_IN, Variant::VECTOR3I, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Vector4>>(Variant::OP_IN, Variant::VECTOR4, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Vector4i>>(Variant::OP_IN, Variant::VECTOR4I, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Transform2D>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Plane>>(Variant::OP_IN, Variant::PLANE, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Quaternion>>(Variant::OP_IN, Variant::QUATERNION, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<::AABB>>(Variant::OP_IN, Variant::AABB, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Basis>>(Variant::OP_IN, Variant::BASIS, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Transform3D>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Projection>>(Variant::OP_IN, Variant::PROJECTION, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Color>>(Variant::OP_IN, Variant::COLOR, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::DICTIONARY); @@ -825,12 +953,15 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorInArrayFind<Rect2i, Array>>(Variant::OP_IN, Variant::RECT2I, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Vector3, Array>>(Variant::OP_IN, Variant::VECTOR3, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Vector3i, Array>>(Variant::OP_IN, Variant::VECTOR3I, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector4, Array>>(Variant::OP_IN, Variant::VECTOR4, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector4i, Array>>(Variant::OP_IN, Variant::VECTOR4I, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Transform2D, Array>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Plane, Array>>(Variant::OP_IN, Variant::PLANE, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Quaternion, Array>>(Variant::OP_IN, Variant::QUATERNION, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<::AABB, Array>>(Variant::OP_IN, Variant::AABB, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Basis, Array>>(Variant::OP_IN, Variant::BASIS, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Transform3D, Array>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Projection, Array>>(Variant::OP_IN, Variant::PROJECTION, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Color, Array>>(Variant::OP_IN, Variant::COLOR, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<StringName, Array>>(Variant::OP_IN, Variant::STRING_NAME, Variant::ARRAY); diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h index 3e9bae1078..ec1ce67445 100644 --- a/core/variant/variant_op.h +++ b/core/variant/variant_op.h @@ -234,6 +234,30 @@ public: static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; } }; +template <> +class OperatorEvaluatorDivNZ<Vector4i, Vector4i, Vector4i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left); + const Vector4i &b = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right); + if (unlikely(b.x == 0 || b.y == 0 || b.z == 0 || b.w == 0)) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = a / b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector4i>::change(r_ret); + *VariantGetInternalPtr<Vector4i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector4i>::get_ptr(left) / *VariantGetInternalPtr<Vector4i>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4i>::encode(PtrToArg<Vector4i>::convert(left) / PtrToArg<Vector4i>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; } +}; + template <class R, class A, class B> class OperatorEvaluatorMod { public: @@ -323,6 +347,30 @@ public: static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; } }; +template <> +class OperatorEvaluatorModNZ<Vector4i, Vector4i, Vector4i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left); + const Vector4i &b = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right); + if (unlikely(b.x == 0 || b.y == 0 || b.z == 0 || b.w == 0)) { + r_valid = false; + *r_ret = "Module by zero error"; + return; + } + *r_ret = a % b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector4i>::change(r_ret); + *VariantGetInternalPtr<Vector4i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector4i>::get_ptr(left) % *VariantGetInternalPtr<Vector4i>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4i>::encode(PtrToArg<Vector4i>::convert(left) % PtrToArg<Vector4i>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; } +}; + template <class R, class A> class OperatorEvaluatorNeg { public: diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 259ca8a60d..1df5fa969e 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -649,6 +649,32 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } value = Vector3i(args[0], args[1], args[2]); + } else if (id == "Vector4") { + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); + if (err) { + return err; + } + + if (args.size() != 4) { + r_err_str = "Expected 4 arguments for constructor"; + return ERR_PARSE_ERROR; + } + + value = Vector4(args[0], args[1], args[2], args[3]); + } else if (id == "Vector4i") { + Vector<int32_t> args; + Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str); + if (err) { + return err; + } + + if (args.size() != 4) { + r_err_str = "Expected 4 arguments for constructor"; + return ERR_PARSE_ERROR; + } + + value = Vector4i(args[0], args[1], args[2], args[3]); } else if (id == "Transform2D" || id == "Matrix32") { //compatibility Vector<real_t> args; Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); @@ -731,6 +757,19 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } value = Transform3D(Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]), Vector3(args[9], args[10], args[11])); + } else if (id == "Projection") { // "Transform" kept for compatibility with Godot <4. + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); + if (err) { + return err; + } + + if (args.size() != 16) { + r_err_str = "Expected 16 arguments for constructor"; + return ERR_PARSE_ERROR; + } + + value = Projection(Vector4(args[0], args[1], args[2], args[3]), Vector4(args[4], args[5], args[6], args[7]), Vector4(args[8], args[9], args[10], args[11]), Vector4(args[12], args[13], args[14], args[15])); } else if (id == "Color") { Vector<float> args; Error err = _parse_construct<float>(p_stream, args, line, r_err_str); @@ -1534,6 +1573,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str Vector3i v = p_variant; p_store_string_func(p_store_string_ud, "Vector3i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ")"); } break; + case Variant::VECTOR4: { + Vector4 v = p_variant; + p_store_string_func(p_store_string_ud, "Vector4(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ", " + rtos_fix(v.z) + ")"); + } break; + case Variant::VECTOR4I: { + Vector4i v = p_variant; + p_store_string_func(p_store_string_ud, "Vector4i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ")"); + } break; case Variant::PLANE: { Plane p = p_variant; p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")"); @@ -1596,6 +1643,20 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, s + ")"); } break; + case Variant::PROJECTION: { + String s = "Projection("; + Projection t = p_variant; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (i != 0 || j != 0) { + s += ", "; + } + s += rtos_fix(t.matrix[i][j]); + } + } + + p_store_string_func(p_store_string_ud, s + ")"); + } break; // misc types case Variant::COLOR: { diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 3839da495f..57b953f7f0 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -77,6 +77,16 @@ void register_named_setters_getters() { REGISTER_MEMBER(Vector3i, y); REGISTER_MEMBER(Vector3i, z); + REGISTER_MEMBER(Vector4, x); + REGISTER_MEMBER(Vector4, y); + REGISTER_MEMBER(Vector4, z); + REGISTER_MEMBER(Vector4, w); + + REGISTER_MEMBER(Vector4i, x); + REGISTER_MEMBER(Vector4i, y); + REGISTER_MEMBER(Vector4i, z); + REGISTER_MEMBER(Vector4i, w); + REGISTER_MEMBER(Rect2, position); REGISTER_MEMBER(Rect2, size); REGISTER_MEMBER(Rect2, end); @@ -111,6 +121,11 @@ void register_named_setters_getters() { REGISTER_MEMBER(Transform3D, basis); REGISTER_MEMBER(Transform3D, origin); + REGISTER_MEMBER(Projection, x); + REGISTER_MEMBER(Projection, y); + REGISTER_MEMBER(Projection, z); + REGISTER_MEMBER(Projection, w); + REGISTER_MEMBER(Color, r); REGISTER_MEMBER(Color, g); REGISTER_MEMBER(Color, b); @@ -804,11 +819,14 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2, double, real_t, 2) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2i, int64_t, int32_t, 2) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3, double, real_t, 3) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3i, int64_t, int32_t, 3) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector4, double, real_t, 4) +INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector4i, int64_t, int32_t, 4) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quaternion, double, real_t, 4) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4) INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .columns, 3) INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_column, get_column, 3) +INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Projection, Vector4, .matrix, 4) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t) @@ -867,10 +885,13 @@ void register_indexed_setters_getters() { REGISTER_INDEXED_MEMBER(Vector2i); REGISTER_INDEXED_MEMBER(Vector3); REGISTER_INDEXED_MEMBER(Vector3i); + REGISTER_INDEXED_MEMBER(Vector4); + REGISTER_INDEXED_MEMBER(Vector4i); REGISTER_INDEXED_MEMBER(Quaternion); REGISTER_INDEXED_MEMBER(Color); REGISTER_INDEXED_MEMBER(Transform2D); REGISTER_INDEXED_MEMBER(Basis); + REGISTER_INDEXED_MEMBER(Projection); REGISTER_INDEXED_MEMBER(PackedByteArray); REGISTER_INDEXED_MEMBER(PackedInt32Array); diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h index bc4dc4b408..570277dc7a 100644 --- a/core/variant/variant_setget.h +++ b/core/variant/variant_setget.h @@ -281,6 +281,16 @@ SETGET_NUMBER_STRUCT(Vector3i, int64_t, x) SETGET_NUMBER_STRUCT(Vector3i, int64_t, y) SETGET_NUMBER_STRUCT(Vector3i, int64_t, z) +SETGET_NUMBER_STRUCT(Vector4, double, x) +SETGET_NUMBER_STRUCT(Vector4, double, y) +SETGET_NUMBER_STRUCT(Vector4, double, z) +SETGET_NUMBER_STRUCT(Vector4, double, w) + +SETGET_NUMBER_STRUCT(Vector4i, int64_t, x) +SETGET_NUMBER_STRUCT(Vector4i, int64_t, y) +SETGET_NUMBER_STRUCT(Vector4i, int64_t, z) +SETGET_NUMBER_STRUCT(Vector4i, int64_t, w) + SETGET_STRUCT(Rect2, Vector2, position) SETGET_STRUCT(Rect2, Vector2, size) SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end) @@ -315,6 +325,11 @@ SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_column, get_column, 2) SETGET_STRUCT(Transform3D, Basis, basis) SETGET_STRUCT(Transform3D, Vector3, origin) +SETGET_STRUCT_CUSTOM(Projection, Vector4, x, matrix[0]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, y, matrix[1]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, z, matrix[2]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, w, matrix[3]) + SETGET_NUMBER_STRUCT(Color, double, r) SETGET_NUMBER_STRUCT(Color, double, g) SETGET_NUMBER_STRUCT(Color, double, b) diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 2bca5f8284..c1a0ad73b0 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -132,6 +132,12 @@ struct VariantUtilityFunctions { case Variant::VECTOR3I: { return VariantInternalAccessor<Vector3i>::get(&x).abs(); } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&x).abs(); + } break; + case Variant::VECTOR4I: { + return VariantInternalAccessor<Vector4i>::get(&x).abs(); + } break; default: { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); @@ -168,6 +174,12 @@ struct VariantUtilityFunctions { case Variant::VECTOR3I: { return VariantInternalAccessor<Vector3i>::get(&x).sign(); } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&x).sign(); + } break; + case Variant::VECTOR4I: { + return VariantInternalAccessor<Vector4i>::get(&x).sign(); + } break; default: { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 7acec9e63b..709863b70f 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1222,6 +1222,8 @@ <member name="VisualScriptCustomNodes" type="VisualScriptCustomNodes" setter="" getter=""> The [VisualScriptCustomNodes] singleton. </member> + <member name="WorkerThreadPool" type="WorkerThreadPool" setter="" getter=""> + </member> <member name="XRServer" type="XRServer" setter="" getter=""> The [XRServer] singleton. </member> @@ -2726,24 +2728,6 @@ <constant name="METHOD_FLAGS_DEFAULT" value="1" enum="MethodFlags"> Default method flags. </constant> - <constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode"> - Used with [method Node.rpc_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. - </constant> - <constant name="RPC_MODE_ANY_PEER" value="1" enum="RPCMode"> - Used with [method Node.rpc_config] to set a method to be callable remotely by any peer. Analogous to the [code]@rpc(any)[/code] annotation. Calls are accepted from all remote peers, no matter if they are node's authority or not. - </constant> - <constant name="RPC_MODE_AUTHORITY" value="2" enum="RPCMode"> - Used with [method Node.rpc_config] to set a method to be callable remotely only by the current multiplayer authority (which is the server by default). Analogous to the [code]@rpc(authority)[/code] annotation. See [method Node.set_multiplayer_authority]. - </constant> - <constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode"> - Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always consider whether the order matters. - </constant> - <constant name="TRANSFER_MODE_UNRELIABLE_ORDERED" value="1" enum="TransferMode"> - Packets are not acknowledged, no resend attempts are made for lost packets. Packets are received in the order they were sent in. Potentially faster than [constant TRANSFER_MODE_RELIABLE]. Use for non-critical data or data that would be outdated if received late due to resend attempt(s) anyway, for example movement and positional data. - </constant> - <constant name="TRANSFER_MODE_RELIABLE" value="2" enum="TransferMode"> - Packets must be received and resend attempts should be made until the packets are acknowledged. Packets must be received in the order they were sent in. Most reliable transfer mode, but potentially the slowest due to the overhead. Use for critical data that must be transmitted and arrive in order, for example an ability being triggered or a chat message. Consider carefully if the information really is critical, and use sparingly. - </constant> <constant name="TYPE_NIL" value="0" enum="Variant.Type"> Variable is [code]null[/code]. </constant> @@ -2780,76 +2764,82 @@ <constant name="TYPE_TRANSFORM2D" value="11" enum="Variant.Type"> Variable is of type [Transform2D]. </constant> - <constant name="TYPE_PLANE" value="12" enum="Variant.Type"> + <constant name="TYPE_VECTOR4" value="12" enum="Variant.Type"> + </constant> + <constant name="TYPE_VECTOR4I" value="13" enum="Variant.Type"> + </constant> + <constant name="TYPE_PLANE" value="14" enum="Variant.Type"> Variable is of type [Plane]. </constant> - <constant name="TYPE_QUATERNION" value="13" enum="Variant.Type"> + <constant name="TYPE_QUATERNION" value="15" enum="Variant.Type"> Variable is of type [Quaternion]. </constant> - <constant name="TYPE_AABB" value="14" enum="Variant.Type"> + <constant name="TYPE_AABB" value="16" enum="Variant.Type"> Variable is of type [AABB]. </constant> - <constant name="TYPE_BASIS" value="15" enum="Variant.Type"> + <constant name="TYPE_BASIS" value="17" enum="Variant.Type"> Variable is of type [Basis]. </constant> - <constant name="TYPE_TRANSFORM3D" value="16" enum="Variant.Type"> + <constant name="TYPE_TRANSFORM3D" value="18" enum="Variant.Type"> Variable is of type [Transform3D]. </constant> - <constant name="TYPE_COLOR" value="17" enum="Variant.Type"> + <constant name="TYPE_PROJECTION" value="19" enum="Variant.Type"> + </constant> + <constant name="TYPE_COLOR" value="20" enum="Variant.Type"> Variable is of type [Color]. </constant> - <constant name="TYPE_STRING_NAME" value="18" enum="Variant.Type"> + <constant name="TYPE_STRING_NAME" value="21" enum="Variant.Type"> Variable is of type [StringName]. </constant> - <constant name="TYPE_NODE_PATH" value="19" enum="Variant.Type"> + <constant name="TYPE_NODE_PATH" value="22" enum="Variant.Type"> Variable is of type [NodePath]. </constant> - <constant name="TYPE_RID" value="20" enum="Variant.Type"> + <constant name="TYPE_RID" value="23" enum="Variant.Type"> Variable is of type [RID]. </constant> - <constant name="TYPE_OBJECT" value="21" enum="Variant.Type"> + <constant name="TYPE_OBJECT" value="24" enum="Variant.Type"> Variable is of type [Object]. </constant> - <constant name="TYPE_CALLABLE" value="22" enum="Variant.Type"> + <constant name="TYPE_CALLABLE" value="25" enum="Variant.Type"> Variable is of type [Callable]. </constant> - <constant name="TYPE_SIGNAL" value="23" enum="Variant.Type"> + <constant name="TYPE_SIGNAL" value="26" enum="Variant.Type"> Variable is of type [Signal]. </constant> - <constant name="TYPE_DICTIONARY" value="24" enum="Variant.Type"> + <constant name="TYPE_DICTIONARY" value="27" enum="Variant.Type"> Variable is of type [Dictionary]. </constant> - <constant name="TYPE_ARRAY" value="25" enum="Variant.Type"> + <constant name="TYPE_ARRAY" value="28" enum="Variant.Type"> Variable is of type [Array]. </constant> - <constant name="TYPE_PACKED_BYTE_ARRAY" value="26" enum="Variant.Type"> + <constant name="TYPE_PACKED_BYTE_ARRAY" value="29" enum="Variant.Type"> Variable is of type [PackedByteArray]. </constant> - <constant name="TYPE_PACKED_INT32_ARRAY" value="27" enum="Variant.Type"> + <constant name="TYPE_PACKED_INT32_ARRAY" value="30" enum="Variant.Type"> Variable is of type [PackedInt32Array]. </constant> - <constant name="TYPE_PACKED_INT64_ARRAY" value="28" enum="Variant.Type"> + <constant name="TYPE_PACKED_INT64_ARRAY" value="31" enum="Variant.Type"> Variable is of type [PackedInt64Array]. </constant> - <constant name="TYPE_PACKED_FLOAT32_ARRAY" value="29" enum="Variant.Type"> + <constant name="TYPE_PACKED_FLOAT32_ARRAY" value="32" enum="Variant.Type"> Variable is of type [PackedFloat32Array]. </constant> - <constant name="TYPE_PACKED_FLOAT64_ARRAY" value="30" enum="Variant.Type"> + <constant name="TYPE_PACKED_FLOAT64_ARRAY" value="33" enum="Variant.Type"> Variable is of type [PackedFloat64Array]. </constant> - <constant name="TYPE_PACKED_STRING_ARRAY" value="31" enum="Variant.Type"> + <constant name="TYPE_PACKED_STRING_ARRAY" value="34" enum="Variant.Type"> Variable is of type [PackedStringArray]. </constant> - <constant name="TYPE_PACKED_VECTOR2_ARRAY" value="32" enum="Variant.Type"> + <constant name="TYPE_PACKED_VECTOR2_ARRAY" value="35" enum="Variant.Type"> Variable is of type [PackedVector2Array]. </constant> - <constant name="TYPE_PACKED_VECTOR3_ARRAY" value="33" enum="Variant.Type"> + <constant name="TYPE_PACKED_VECTOR3_ARRAY" value="36" enum="Variant.Type"> Variable is of type [PackedVector3Array]. </constant> - <constant name="TYPE_PACKED_COLOR_ARRAY" value="34" enum="Variant.Type"> + <constant name="TYPE_PACKED_COLOR_ARRAY" value="37" enum="Variant.Type"> Variable is of type [PackedColorArray]. </constant> - <constant name="TYPE_MAX" value="35" enum="Variant.Type"> + <constant name="TYPE_MAX" value="38" enum="Variant.Type"> Represents the size of the [enum Variant.Type] enum. </constant> <constant name="OP_EQUAL" value="0" enum="Variant.Operator"> diff --git a/doc/classes/AnimationNodeStateMachineTransition.xml b/doc/classes/AnimationNodeStateMachineTransition.xml index 206164d675..0badb831de 100644 --- a/doc/classes/AnimationNodeStateMachineTransition.xml +++ b/doc/classes/AnimationNodeStateMachineTransition.xml @@ -23,7 +23,7 @@ Use an expression as a condition for state machine transitions. It is possible to create complex animation advance conditions for switching between states and gives much greater flexibility for creating complex state machines by directly interfacing with the script code. </member> <member name="advance_expression_base_node" type="NodePath" setter="set_advance_expression_base_node" getter="get_advance_expression_base_node" default="NodePath("")"> - The path to the [Node] used to evaluate an [Expression] if one is not explictly specified internally. + The path to the [Node] used to evaluate an [Expression] if one is not explicitly specified internally. </member> <member name="auto_advance" type="bool" setter="set_auto_advance" getter="has_auto_advance" default="false"> Turn on the transition automatically when this state is reached. This works best with [constant SWITCH_MODE_AT_END]. diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml index 653607610d..b24c439432 100644 --- a/doc/classes/AnimationPlayer.xml +++ b/doc/classes/AnimationPlayer.xml @@ -220,6 +220,10 @@ <member name="method_call_mode" type="int" setter="set_method_call_mode" getter="get_method_call_mode" enum="AnimationPlayer.AnimationMethodCallMode" default="0"> The call mode to use for Call Method tracks. </member> + <member name="movie_quit_on_finish" type="bool" setter="set_movie_quit_on_finish_enabled" getter="is_movie_quit_on_finish_enabled" default="false"> + If [code]true[/code] and the engine is running in Movie Maker mode (see [MovieWriter]), exits the engine with [method SceneTree.quit] as soon as an animation is done playing in this [AnimationPlayer]. A message is printed when the engine quits for this reason. + [b]Note:[/b] This obeys the same logic as the [signal animation_finished] signal, so it will not quit the engine if the animation is set to be looping. + </member> <member name="playback_active" type="bool" setter="set_active" getter="is_active"> If [code]true[/code], updates animations in response to process-related notifications. </member> @@ -253,6 +257,7 @@ <argument index="0" name="anim_name" type="StringName" /> <description> Notifies when an animation finished playing. + [b]Note:[/b] This signal is not emitted if an animation is looping. </description> </signal> <signal name="animation_started"> diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml index ecac228a26..45d9152564 100644 --- a/doc/classes/AnimationTree.xml +++ b/doc/classes/AnimationTree.xml @@ -38,7 +38,7 @@ If [code]true[/code], the [AnimationTree] will be processing. </member> <member name="advance_expression_base_node" type="NodePath" setter="set_advance_expression_base_node" getter="get_advance_expression_base_node" default="NodePath(".")"> - The path to the [Node] used to evaluate the AnimationNode [Expression] if one is not explictly specified internally. + The path to the [Node] used to evaluate the AnimationNode [Expression] if one is not explicitly specified internally. </member> <member name="anim_player" type="NodePath" setter="set_animation_player" getter="get_animation_player" default="NodePath("")"> The path to the [AnimationPlayer] used for animating. diff --git a/doc/classes/AudioEffectRecord.xml b/doc/classes/AudioEffectRecord.xml index 9728011bb2..32a6aea340 100644 --- a/doc/classes/AudioEffectRecord.xml +++ b/doc/classes/AudioEffectRecord.xml @@ -14,7 +14,7 @@ </tutorials> <methods> <method name="get_recording" qualifiers="const"> - <return type="AudioStreamSample" /> + <return type="AudioStreamWAV" /> <description> Returns the recorded sample. </description> @@ -34,8 +34,8 @@ </method> </methods> <members> - <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamSample.Format" default="1"> - Specifies the format in which the sample will be recorded. See [enum AudioStreamSample.Format] for available formats. + <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamWAV.Format" default="1"> + Specifies the format in which the sample will be recorded. See [enum AudioStreamWAV.Format] for available formats. </member> </members> </class> diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml index 1e076654fb..28dcd2794e 100644 --- a/doc/classes/AudioServer.xml +++ b/doc/classes/AudioServer.xml @@ -275,6 +275,12 @@ Sets the volume of the bus at index [code]bus_idx[/code] to [code]volume_db[/code]. </description> </method> + <method name="set_enable_tagging_used_audio_streams"> + <return type="void" /> + <argument index="0" name="enable" type="bool" /> + <description> + </description> + </method> <method name="swap_bus_effects"> <return type="void" /> <argument index="0" name="bus_idx" type="int" /> diff --git a/doc/classes/AudioStream.xml b/doc/classes/AudioStream.xml index 6343da6eed..7645cafe86 100644 --- a/doc/classes/AudioStream.xml +++ b/doc/classes/AudioStream.xml @@ -4,7 +4,7 @@ Base class for audio streams. </brief_description> <description> - Base class for audio streams. Audio streams are used for sound effects and music playback, and support WAV (via [AudioStreamSample]) and OGG (via [AudioStreamOGGVorbis]) file formats. + Base class for audio streams. Audio streams are used for sound effects and music playback, and support WAV (via [AudioStreamWAV]) and Ogg (via [AudioStreamOggVorbis]) file formats. </description> <tutorials> <link title="Audio streams">$DOCS_URL/tutorials/audio/audio_streams.html</link> @@ -13,6 +13,16 @@ <link title="Audio Spectrum Demo">https://godotengine.org/asset-library/asset/528</link> </tutorials> <methods> + <method name="_get_beat_count" qualifiers="virtual const"> + <return type="int" /> + <description> + </description> + </method> + <method name="_get_bpm" qualifiers="virtual const"> + <return type="float" /> + <description> + </description> + </method> <method name="_get_length" qualifiers="virtual const"> <return type="float" /> <description> @@ -23,7 +33,7 @@ <description> </description> </method> - <method name="_instance_playback" qualifiers="virtual const"> + <method name="_instantiate_playback" qualifiers="virtual const"> <return type="AudioStreamPlayback" /> <description> </description> @@ -39,10 +49,10 @@ Returns the length of the audio stream in seconds. </description> </method> - <method name="instance_playback"> + <method name="instantiate_playback"> <return type="AudioStreamPlayback" /> <description> - Returns an AudioStreamPlayback. Useful for when you want to extend `_instance_playback` but call `instance_playback` from an internally held AudioStream subresource. An example of this can be found in the source files for `AudioStreamRandomPitch::instance_playback`. + Returns an AudioStreamPlayback. Useful for when you want to extend [method _instantiate_playback] but call [method instantiate_playback] from an internally held AudioStream subresource. An example of this can be found in the source files for [code]AudioStreamRandomPitch::instantiate_playback[/code]. </description> </method> <method name="is_monophonic" qualifiers="const"> diff --git a/doc/classes/AudioStreamPlayback.xml b/doc/classes/AudioStreamPlayback.xml index 1909c4b621..f1a1c18c1c 100644 --- a/doc/classes/AudioStreamPlayback.xml +++ b/doc/classes/AudioStreamPlayback.xml @@ -4,7 +4,7 @@ Meta class for playing back audio. </brief_description> <description> - Can play, loop, pause a scroll through audio. See [AudioStream] and [AudioStreamOGGVorbis] for usage. + Can play, loop, pause a scroll through audio. See [AudioStream] and [AudioStreamOggVorbis] for usage. </description> <tutorials> <link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link> @@ -50,5 +50,10 @@ <description> </description> </method> + <method name="_tag_used_streams" qualifiers="virtual"> + <return type="void" /> + <description> + </description> + </method> </methods> </class> diff --git a/doc/classes/AudioStreamSample.xml b/doc/classes/AudioStreamWAV.xml index 62f27ce876..17595aec2f 100644 --- a/doc/classes/AudioStreamSample.xml +++ b/doc/classes/AudioStreamWAV.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamSample" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="AudioStreamWAV" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> Stores audio data loaded from WAV files. </brief_description> <description> - AudioStreamSample stores sound samples loaded from WAV files. To play the stored sound, use an [AudioStreamPlayer] (for non-positional audio) or [AudioStreamPlayer2D]/[AudioStreamPlayer3D] (for positional audio). The sound can be looped. + AudioStreamWAV stores sound samples loaded from WAV files. To play the stored sound, use an [AudioStreamPlayer] (for non-positional audio) or [AudioStreamPlayer2D]/[AudioStreamPlayer3D] (for positional audio). The sound can be looped. This class can also be used to store dynamically-generated PCM audio data. See also [AudioStreamGenerator] for procedural audio generation. </description> <tutorials> @@ -14,7 +14,7 @@ <return type="int" enum="Error" /> <argument index="0" name="path" type="String" /> <description> - Saves the AudioStreamSample as a WAV file to [code]path[/code]. Samples with IMA ADPCM format can't be saved. + Saves the AudioStreamWAV as a WAV file to [code]path[/code]. Samples with IMA ADPCM format can't be saved. [b]Note:[/b] A [code].wav[/code] extension is automatically appended to [code]path[/code] if it is missing. </description> </method> @@ -24,7 +24,7 @@ Contains the audio data in bytes. [b]Note:[/b] This property expects signed PCM8 data. To convert unsigned PCM8 to signed PCM8, subtract 128 from each byte. </member> - <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamSample.Format" default="0"> + <member name="format" type="int" setter="set_format" getter="get_format" enum="AudioStreamWAV.Format" default="0"> Audio format. See [enum Format] constants for values. </member> <member name="loop_begin" type="int" setter="set_loop_begin" getter="get_loop_begin" default="0"> @@ -33,7 +33,7 @@ <member name="loop_end" type="int" setter="set_loop_end" getter="get_loop_end" default="0"> The loop end point (in number of samples, relative to the beginning of the sample). This information will be imported automatically from the WAV file if present. </member> - <member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" enum="AudioStreamSample.LoopMode" default="0"> + <member name="loop_mode" type="int" setter="set_loop_mode" getter="get_loop_mode" enum="AudioStreamWAV.LoopMode" default="0"> The loop mode. This information will be imported automatically from the WAV file if present. See [enum LoopMode] constants for values. </member> <member name="mix_rate" type="int" setter="set_mix_rate" getter="get_mix_rate" default="44100"> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index d3ae85101d..b3cea7217e 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -374,10 +374,10 @@ [b]Note:[/b] This is only effective for objects whose geometry is point-based rather than triangle-based. See also [member point_size]. </member> <member name="uv1_offset" type="Vector3" setter="set_uv1_offset" getter="get_uv1_offset" default="Vector3(0, 0, 0)"> - How much to offset the [code]UV[/code] coordinates. This amount will be added to [code]UV[/code] in the vertex function. This can be used to offset a texture. + How much to offset the [code]UV[/code] coordinates. This amount will be added to [code]UV[/code] in the vertex function. This can be used to offset a texture. The Z component is used when [member uv1_triplanar] is enabled, but it is not used anywhere else. </member> <member name="uv1_scale" type="Vector3" setter="set_uv1_scale" getter="get_uv1_scale" default="Vector3(1, 1, 1)"> - How much to scale the [code]UV[/code] coordinates. This is multiplied by [code]UV[/code] in the vertex function. + How much to scale the [code]UV[/code] coordinates. This is multiplied by [code]UV[/code] in the vertex function. The Z component is used when [member uv1_triplanar] is enabled, but it is not used anywhere else. </member> <member name="uv1_triplanar" type="bool" setter="set_flag" getter="get_flag" default="false"> If [code]true[/code], instead of using [code]UV[/code] textures will use a triplanar texture lookup to determine how to apply textures. Triplanar uses the orientation of the object's surface to blend between texture coordinates. It reads from the source texture 3 times, once for each axis and then blends between the results based on how closely the pixel aligns with each axis. This is often used for natural features to get a realistic blend of materials. Because triplanar texturing requires many more texture reads per-pixel it is much slower than normal UV texturing. Additionally, because it is blending the texture between the three axes, it is unsuitable when you are trying to achieve crisp texturing. @@ -389,10 +389,10 @@ If [code]true[/code], triplanar mapping for [code]UV[/code] is calculated in world space rather than object local space. See also [member uv1_triplanar]. </member> <member name="uv2_offset" type="Vector3" setter="set_uv2_offset" getter="get_uv2_offset" default="Vector3(0, 0, 0)"> - How much to offset the [code]UV2[/code] coordinates. This amount will be added to [code]UV2[/code] in the vertex function. This can be used to offset a texture. + How much to offset the [code]UV2[/code] coordinates. This amount will be added to [code]UV2[/code] in the vertex function. This can be used to offset a texture. The Z component is used when [member uv2_triplanar] is enabled, but it is not used anywhere else. </member> <member name="uv2_scale" type="Vector3" setter="set_uv2_scale" getter="get_uv2_scale" default="Vector3(1, 1, 1)"> - How much to scale the [code]UV2[/code] coordinates. This is multiplied by [code]UV2[/code] in the vertex function. + How much to scale the [code]UV2[/code] coordinates. This is multiplied by [code]UV2[/code] in the vertex function. The Z component is used when [member uv2_triplanar] is enabled, but it is not used anywhere else. </member> <member name="uv2_triplanar" type="bool" setter="set_flag" getter="get_flag" default="false"> If [code]true[/code], instead of using [code]UV2[/code] textures will use a triplanar texture lookup to determine how to apply textures. Triplanar uses the orientation of the object's surface to blend between texture coordinates. It reads from the source texture 3 times, once for each axis and then blends between the results based on how closely the pixel aligns with each axis. This is often used for natural features to get a realistic blend of materials. Because triplanar texturing requires many more texture reads per-pixel it is much slower than normal UV texturing. Additionally, because it is blending the texture between the three axes, it is unsuitable when you are trying to achieve crisp texturing. diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml index 468fddcfc1..3aedbbd1e6 100644 --- a/doc/classes/Camera3D.xml +++ b/doc/classes/Camera3D.xml @@ -189,7 +189,7 @@ <member name="near" type="float" setter="set_near" getter="get_near" default="0.05"> The distance to the near culling boundary for this camera relative to its local Z axis. </member> - <member name="projection" type="int" setter="set_projection" getter="get_projection" enum="Camera3D.Projection" default="0"> + <member name="projection" type="int" setter="set_projection" getter="get_projection" enum="Camera3D.ProjectionType" default="0"> The camera's projection mode. In [constant PROJECTION_PERSPECTIVE] mode, objects' Z distance from the camera's local space scales their perceived size. </member> <member name="size" type="float" setter="set_size" getter="get_size" default="1.0"> @@ -200,13 +200,13 @@ </member> </members> <constants> - <constant name="PROJECTION_PERSPECTIVE" value="0" enum="Projection"> + <constant name="PROJECTION_PERSPECTIVE" value="0" enum="ProjectionType"> Perspective projection. Objects on the screen becomes smaller when they are far away. </constant> - <constant name="PROJECTION_ORTHOGONAL" value="1" enum="Projection"> + <constant name="PROJECTION_ORTHOGONAL" value="1" enum="ProjectionType"> Orthogonal projection, also known as orthographic projection. Objects remain the same size on the screen no matter how far away they are. </constant> - <constant name="PROJECTION_FRUSTUM" value="2" enum="Projection"> + <constant name="PROJECTION_FRUSTUM" value="2" enum="ProjectionType"> Frustum projection. This mode allows adjusting [member frustum_offset] to create "tilted frustum" effects. </constant> <constant name="KEEP_WIDTH" value="0" enum="KeepAspect"> diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml index 861b4b480c..b86104a5e3 100644 --- a/doc/classes/Decal.xml +++ b/doc/classes/Decal.xml @@ -63,14 +63,14 @@ <member name="cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask" default="1048575"> Specifies which [member VisualInstance3D.layers] this decal will project on. By default, Decals affect all layers. This is used so you can specify which types of objects receive the Decal and which do not. This is especially useful so you can ensure that dynamic objects don't accidentally receive a Decal intended for the terrain under them. </member> - <member name="distance_fade_begin" type="float" setter="set_distance_fade_begin" getter="get_distance_fade_begin" default="10.0"> - Distance from the camera at which the Decal begins to fade away. + <member name="distance_fade_begin" type="float" setter="set_distance_fade_begin" getter="get_distance_fade_begin" default="40.0"> + The distance from the camera at which the Decal begins to fade away (in 3D units). </member> <member name="distance_fade_enabled" type="bool" setter="set_enable_distance_fade" getter="is_distance_fade_enabled" default="false"> - If [code]true[/code], decals will smoothly fade away when far from the active [Camera3D] starting at [member distance_fade_begin]. The Decal will fade out over [member distance_fade_length], after which it will be culled and not sent to the shader at all. Use this to reduce the number of active Decals in a scene and thus improve performance. + If [code]true[/code], decals will smoothly fade away when far from the active [Camera3D] starting at [member distance_fade_begin]. The Decal will fade out over [member distance_fade_begin] + [member distance_fade_length], after which it will be culled and not sent to the shader at all. Use this to reduce the number of active Decals in a scene and thus improve performance. </member> - <member name="distance_fade_length" type="float" setter="set_distance_fade_length" getter="get_distance_fade_length" default="1.0"> - Distance over which the Decal fades. The Decal becomes slowly more transparent over this distance and is completely invisible at the end. + <member name="distance_fade_length" type="float" setter="set_distance_fade_length" getter="get_distance_fade_length" default="10.0"> + The distance over which the Decal fades (in 3D units). The Decal becomes slowly more transparent over this distance and is completely invisible at the end. </member> <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy" default="1.0"> Energy multiplier for the emission texture. This will make the decal emit light at a higher intensity. diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml index 8aa2db2cf8..f217fbaf48 100644 --- a/doc/classes/EditorExportPlugin.xml +++ b/doc/classes/EditorExportPlugin.xml @@ -96,7 +96,7 @@ Adds a static lib from the given [code]path[/code] to the iOS project. </description> </method> - <method name="add_osx_plugin_file"> + <method name="add_macos_plugin_file"> <return type="void" /> <argument index="0" name="path" type="String" /> <description> diff --git a/doc/classes/EditorFeatureProfile.xml b/doc/classes/EditorFeatureProfile.xml index 2ab87b0dd1..a6bdc294ac 100644 --- a/doc/classes/EditorFeatureProfile.xml +++ b/doc/classes/EditorFeatureProfile.xml @@ -57,7 +57,7 @@ <return type="int" enum="Error" /> <argument index="0" name="path" type="String" /> <description> - Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] button. + Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] method. </description> </method> <method name="set_disable_class"> diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index 506992e3af..36dfee833b 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -151,6 +151,12 @@ [/codeblocks] </description> </method> + <method name="get_write_movie_path" qualifiers="const"> + <return type="String" /> + <description> + Returns the path to the [MovieWriter]'s output file, or an empty string if the engine wasn't started in Movie Maker mode. This path can be absolute or relative depending on how the user specified it. + </description> + </method> <method name="has_singleton" qualifiers="const"> <return type="bool" /> <argument index="0" name="name" type="StringName" /> diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml index e95f444d55..ec2776f636 100644 --- a/doc/classes/Font.xml +++ b/doc/classes/Font.xml @@ -14,8 +14,8 @@ <argument index="0" name="canvas_item" type="RID" /> <argument index="1" name="pos" type="Vector2" /> <argument index="2" name="char" type="int" /> - <argument index="3" name="modulate" type="int" /> - <argument index="4" name="arg4" type="Color" default="Color(1, 1, 1, 1)" /> + <argument index="3" name="font_size" type="int" /> + <argument index="4" name="modulate" type="Color" default="Color(1, 1, 1, 1)" /> <description> Draw a single Unicode character [code]char[/code] into a canvas item using the font, at a given position, with [code]modulate[/code] color. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. [b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead. @@ -26,9 +26,9 @@ <argument index="0" name="canvas_item" type="RID" /> <argument index="1" name="pos" type="Vector2" /> <argument index="2" name="char" type="int" /> - <argument index="3" name="size" type="int" /> - <argument index="4" name="modulate" type="int" default="-1" /> - <argument index="5" name="arg5" type="Color" default="Color(1, 1, 1, 1)" /> + <argument index="3" name="font_size" type="int" /> + <argument index="4" name="size" type="int" default="-1" /> + <argument index="5" name="modulate" type="Color" default="Color(1, 1, 1, 1)" /> <description> Draw a single Unicode character [code]char[/code] outline into a canvas item using the font, at a given position, with [code]modulate[/code] color and [code]size[/code] outline size. [code]position[/code] specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. [b]Note:[/b] Do not use this function to draw strings character by character, use [method draw_string] or [TextLine] instead. @@ -129,7 +129,7 @@ <method name="get_char_size" qualifiers="const"> <return type="Vector2" /> <argument index="0" name="char" type="int" /> - <argument index="1" name="arg1" type="int" /> + <argument index="1" name="font_size" type="int" /> <description> Returns the size of a character, optionally taking kerning into account if the next character is provided. [b]Note:[/b] Do not use this function to calculate width of the string character by character, use [method get_string_size] or [TextLine] instead. The height returned is the font height (see also [method get_height]) and has no relation to the glyph height. @@ -226,9 +226,12 @@ <argument index="5" name="direction" type="int" enum="TextServer.Direction" default="0" /> <argument index="6" name="orientation" type="int" enum="TextServer.Orientation" default="0" /> <description> - Returns the size of a bounding box of a string, taking kerning and advance into account. + Returns the size of a bounding box of a single-line string, taking kerning and advance into account. See also [method get_multiline_string_size] and [method draw_string]. + For example, to get the string size as displayed by a single-line Label, use: + [codeblock] + var string_size = $Label.get_theme_font("font").get_string_size($Label.text, HORIZONTAL_ALIGNMENT_LEFT, -1, $Label.get_theme_font_size("font_size")) + [/codeblock] [b]Note:[/b] Real height of the string is context-dependent and can be significantly different from the value returned by [method get_height]. - See also [method draw_string]. </description> </method> <method name="get_supported_chars" qualifiers="const"> diff --git a/doc/classes/FontFile.xml b/doc/classes/FontFile.xml index aaf871d55a..dc2cbdde63 100644 --- a/doc/classes/FontFile.xml +++ b/doc/classes/FontFile.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="FontFile" inherits="Font" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - FontFile source data and prerendered glyph cache, imported from dynamic or bitmap font. + Font source data and prerendered glyph cache, imported from dynamic or bitmap font. </brief_description> <description> [FontFile] contains a set of glyphs to represent Unicode characters imported from a font file, as well as a cache of rasterized glyphs, and a set of fallback [Font]s to use. diff --git a/doc/classes/Geometry2D.xml b/doc/classes/Geometry2D.xml index b84e221d1c..195c481187 100644 --- a/doc/classes/Geometry2D.xml +++ b/doc/classes/Geometry2D.xml @@ -126,7 +126,7 @@ <return type="Dictionary" /> <argument index="0" name="sizes" type="PackedVector2Array" /> <description> - Given an array of [Vector2]s representing tiles, builds an atlas. The returned dictionary has two keys: [code]points[/code] is a vector of [Vector2] that specifies the positions of each tile, [code]size[/code] contains the overall size of the whole atlas as [Vector2]. + Given an array of [Vector2]s representing tiles, builds an atlas. The returned dictionary has two keys: [code]points[/code] is an array of [Vector2] that specifies the positions of each tile, [code]size[/code] contains the overall size of the whole atlas as [Vector2]. </description> </method> <method name="merge_polygons"> diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml index 8b85309dee..084bf7e809 100644 --- a/doc/classes/ImageTexture.xml +++ b/doc/classes/ImageTexture.xml @@ -42,6 +42,14 @@ Returns the format of the texture, one of [enum Image.Format]. </description> </method> + <method name="set_image"> + <return type="void" /> + <argument index="0" name="image" type="Image" /> + <description> + Replaces the texture's data with a new [Image]. This will re-allocate new memory for the texture. + If you want to update the image, but don't need to change its parameters (format, size), use [method update] instead for better performance. + </description> + </method> <method name="set_size_override"> <return type="void" /> <argument index="0" name="size" type="Vector2i" /> @@ -54,8 +62,8 @@ <argument index="0" name="image" type="Image" /> <description> Replaces the texture's data with a new [Image]. - [b]Note:[/b] The texture has to be initialized first with the [method create_from_image] method before it can be updated. The new image dimensions, format, and mipmaps configuration should match the existing texture's image configuration, otherwise it has to be re-created with the [method create_from_image] method. - Use this method over [method create_from_image] if you need to update the texture frequently, which is faster than allocating additional memory for a new texture each time. + [b]Note:[/b] The texture has to be created using [method create_from_image] or initialized first with the [method set_image] method before it can be updated. The new image dimensions, format, and mipmaps configuration should match the existing texture's image configuration. + Use this method over [method set_image] if you need to update the texture frequently, which is faster than allocating additional memory for a new texture each time. </description> </method> </methods> diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index e73021ead4..796a80873f 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -354,9 +354,11 @@ <return type="void" /> <argument index="0" name="duration_ms" type="int" default="500" /> <description> - Vibrate Android and iOS devices. + Vibrate handheld devices. + [b]Note:[/b] This method is implemented on Android, iOS, and HTML5. [b]Note:[/b] For Android, it requires enabling the [code]VIBRATE[/code] permission in the export preset. [b]Note:[/b] For iOS, specifying the duration is supported in iOS 13 and later. + [b]Note:[/b] Some web browsers such as Safari and Firefox for Android do not support this method. </description> </method> <method name="warp_mouse"> diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index 1eac58b9f2..1ebf770f7e 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -49,6 +49,8 @@ <member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0"> Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants. </member> + <member name="label_settings" type="LabelSettings" setter="set_label_settings" getter="get_label_settings"> + </member> <member name="language" type="String" setter="set_language" getter="get_language" default=""""> Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. </member> diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml index 2c3c27079a..5ba0a2d79a 100644 --- a/doc/classes/Label3D.xml +++ b/doc/classes/Label3D.xml @@ -79,7 +79,7 @@ </member> <member name="outline_render_priority" type="int" setter="set_outline_render_priority" getter="get_outline_render_priority" default="-1"> Sets the render priority for the text outline. Higher priority objects will be sorted in front of lower priority objects. - [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). </member> <member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0"> @@ -90,7 +90,7 @@ </member> <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority" default="0"> Sets the render priority for the text. Higher priority objects will be sorted in front of lower priority objects. - [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). </member> <member name="shaded" type="bool" setter="set_draw_flag" getter="get_draw_flag" default="false"> @@ -126,7 +126,7 @@ If set, lights in the environment affect the label. </constant> <constant name="FLAG_DOUBLE_SIDED" value="1" enum="DrawFlags"> - If set, text can be seen from the back as well. If not, the texture is invisible when looking at it from behind. + If set, text can be seen from the back as well. If not, the text is invisible when looking at it from behind. </constant> <constant name="FLAG_DISABLE_DEPTH_TEST" value="2" enum="DrawFlags"> Disables the depth test, so this object is drawn on top of all others. However, objects drawn after it in the draw order may cover it. diff --git a/doc/classes/LabelSettings.xml b/doc/classes/LabelSettings.xml new file mode 100644 index 0000000000..227313d3b3 --- /dev/null +++ b/doc/classes/LabelSettings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="LabelSettings" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <members> + <member name="font" type="Font" setter="set_font" getter="get_font"> + </member> + <member name="font_color" type="Color" setter="set_font_color" getter="get_font_color" default="Color(0.875, 0.875, 0.875, 1)"> + </member> + <member name="font_size" type="int" setter="set_font_size" getter="get_font_size" default="16"> + </member> + <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0"> + </member> + <member name="outline_color" type="Color" setter="set_outline_color" getter="get_outline_color" default="Color(1, 1, 1, 1)"> + </member> + <member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0"> + </member> + <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color(1, 1, 1, 1)"> + </member> + <member name="shadow_offset" type="Vector2" setter="set_shadow_offset" getter="get_shadow_offset" default="Vector2(1, 1)"> + </member> + <member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" default="0"> + </member> + </members> +</class> diff --git a/doc/classes/LightmapGIData.xml b/doc/classes/LightmapGIData.xml index 20113ac309..13f44150d7 100644 --- a/doc/classes/LightmapGIData.xml +++ b/doc/classes/LightmapGIData.xml @@ -22,7 +22,7 @@ <method name="clear_users"> <return type="void" /> <description> - Clear all objects that are considred baked within this [LightmapGIData]. + Clear all objects that are considered baked within this [LightmapGIData]. </description> </method> <method name="get_user_count" qualifiers="const"> diff --git a/doc/classes/MovieWriter.xml b/doc/classes/MovieWriter.xml index bc702adde6..d47e52d7c0 100644 --- a/doc/classes/MovieWriter.xml +++ b/doc/classes/MovieWriter.xml @@ -68,7 +68,7 @@ <return type="void" /> <argument index="0" name="writer" type="MovieWriter" /> <description> - Adds a writer to be usable by the engine. The supported file extensions can be set by overridding [method _handles_file]. + Adds a writer to be usable by the engine. The supported file extensions can be set by overriding [method _handles_file]. [b]Note:[/b] [method add_writer] must be called early enough in the engine initialization to work, as movie writing is designed to start at the same time as the rest of the engine. </description> </method> diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml index 631b2ea050..9d8f1e1e5d 100644 --- a/doc/classes/MultiMesh.xml +++ b/doc/classes/MultiMesh.xml @@ -91,7 +91,8 @@ <member name="custom_data_array" type="PackedColorArray" setter="_set_custom_data_array" getter="_get_custom_data_array"> </member> <member name="instance_count" type="int" setter="set_instance_count" getter="get_instance_count" default="0"> - Number of instances that will get drawn. This clears and (re)sizes the buffers. By default, all instances are drawn but you can limit this with [member visible_instance_count]. + Number of instances that will get drawn. This clears and (re)sizes the buffers. Setting data format or flags afterwards will have no effect. + By default, all instances are drawn but you can limit this with [member visible_instance_count]. </member> <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> Mesh to be drawn. diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml index 059d147979..06658bf004 100644 --- a/doc/classes/MultiplayerAPI.xml +++ b/doc/classes/MultiplayerAPI.xml @@ -1,88 +1,108 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="MultiplayerAPI" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - High-level multiplayer API. + High-level multiplayer API interface. </brief_description> <description> - This class implements the high-level multiplayer API. See also [MultiplayerPeer]. - By default, [SceneTree] has a reference to this class that is used to provide multiplayer capabilities (i.e. RPCs) across the whole scene. + Base class for high-level multiplayer API implementations. See also [MultiplayerPeer]. + By default, [SceneTree] has a reference to an implementation of this class and uses it to provide multiplayer capabilities (i.e. RPCs) across the whole scene. It is possible to override the MultiplayerAPI instance used by specific tree branches by calling the [method SceneTree.set_multiplayer] method, effectively allowing to run both client and server in the same scene. - [b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice. - [b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android. + It is also possible to extend or replace the default implementation via scripting or native extensions. See [MultiplayerAPIExtension] for details about extensions, [SceneMultiplayer] for the details about the default implementation. </description> <tutorials> </tutorials> <methods> - <method name="clear"> - <return type="void" /> + <method name="create_default_interface" qualifiers="static"> + <return type="MultiplayerAPI" /> + <description> + Returns a new instance of the default MultiplayerAPI. + </description> + </method> + <method name="get_default_interface" qualifiers="static"> + <return type="StringName" /> <description> - Clears the current MultiplayerAPI network state (you shouldn't call this unless you know what you are doing). + Returns the default MultiplayerAPI implementation class name. This is usually [code]"SceneMultiplayer"[/code] when [SceneMultiplayer] is available. See [method set_default_interface]. </description> </method> - <method name="get_peers" qualifiers="const"> + <method name="get_peers"> <return type="PackedInt32Array" /> <description> Returns the peer IDs of all connected peers of this MultiplayerAPI's [member multiplayer_peer]. </description> </method> - <method name="get_remote_sender_id" qualifiers="const"> + <method name="get_remote_sender_id"> <return type="int" /> <description> Returns the sender's peer ID for the RPC currently being executed. [b]Note:[/b] If not inside an RPC this method will return 0. </description> </method> - <method name="get_unique_id" qualifiers="const"> + <method name="get_unique_id"> <return type="int" /> <description> Returns the unique peer ID of this MultiplayerAPI's [member multiplayer_peer]. </description> </method> - <method name="has_multiplayer_peer" qualifiers="const"> + <method name="has_multiplayer_peer"> <return type="bool" /> <description> Returns [code]true[/code] if there is a [member multiplayer_peer] set. </description> </method> - <method name="is_server" qualifiers="const"> + <method name="is_server"> <return type="bool" /> <description> Returns [code]true[/code] if this MultiplayerAPI's [member multiplayer_peer] is valid and in server mode (listening for connections). </description> </method> + <method name="object_configuration_add"> + <return type="int" enum="Error" /> + <argument index="0" name="object" type="Object" /> + <argument index="1" name="configuration" type="Variant" /> + <description> + Notifies the MultiplayerAPI of a new [code]configuration[/code] for the given [code]object[/code]. This method is used internally by [SceneTree] to configure the root path for this MultiplayerAPI (passing [code]null[/code] and a valid [NodePath] as [code]configuration[/code]). This method can be further used by MultiplayerAPI implementations to provide additional features, refer to specific implementation (e.g. [SceneMultiplayer]) for details on how they use it. + [b]Note:[/b] This method is mostly relevant when extending or overriding the MultiplayerAPI behavior via [MultiplayerAPIExtension]. + </description> + </method> + <method name="object_configuration_remove"> + <return type="int" enum="Error" /> + <argument index="0" name="object" type="Object" /> + <argument index="1" name="configuration" type="Variant" /> + <description> + Notifies the MultiplayerAPI to remove a [code]configuration[/code] for the given [code]object[/code]. This method is used internally by [SceneTree] to configure the root path for this MultiplayerAPI (passing [code]null[/code] and an empty [NodePath] as [code]configuration[/code]). This method can be further used by MultiplayerAPI implementations to provide additional features, refer to specific implementation (e.g. [SceneMultiplayer]) for details on how they use it. + [b]Note:[/b] This method is mostly relevant when extending or overriding the MultiplayerAPI behavior via [MultiplayerAPIExtension]. + </description> + </method> <method name="poll"> - <return type="void" /> + <return type="int" enum="Error" /> <description> Method used for polling the MultiplayerAPI. You only need to worry about this if you set [member SceneTree.multiplayer_poll] to [code]false[/code]. By default, [SceneTree] will poll its MultiplayerAPI(s) for you. [b]Note:[/b] This method results in RPCs being called, so they will be executed in the same context of this function (e.g. [code]_process[/code], [code]physics[/code], [Thread]). </description> </method> - <method name="send_bytes"> + <method name="rpc"> <return type="int" enum="Error" /> - <argument index="0" name="bytes" type="PackedByteArray" /> - <argument index="1" name="id" type="int" default="0" /> - <argument index="2" name="mode" type="int" enum="TransferMode" default="2" /> - <argument index="3" name="channel" type="int" default="0" /> + <argument index="0" name="peer" type="int" /> + <argument index="1" name="object" type="Object" /> + <argument index="2" name="method" type="StringName" /> + <argument index="3" name="arguments" type="Array" default="[]" /> + <description> + Sends an RPC to the target [code]peer[/code]. The given [code]method[/code] will be called on the remote [code]object[/code] with the provided [code]arguments[/code]. The RPC may also be called locally depending on the implementation and RPC configuration. See [method Node.rpc] and [method Node.rpc_config]. + [b]Note:[/b] Prefer using [method Node.rpc], [method Node.rpc_id], or [code]my_method.rpc(peer, arg1, arg2, ...)[/code] (in GDScript), since they are faster. This method is mostly useful in conjunction with [MultiplayerAPIExtension] when augmenting or replacing the multiplayer capabilities. + </description> + </method> + <method name="set_default_interface" qualifiers="static"> + <return type="void" /> + <argument index="0" name="interface_name" type="StringName" /> <description> - Sends the given raw [code]bytes[/code] to a specific peer identified by [code]id[/code] (see [method MultiplayerPeer.set_target_peer]). Default ID is [code]0[/code], i.e. broadcast to all peers. + Sets the default MultiplayerAPI implementation class. This method can be used by modules and extensions to configure which implementation will be used by [SceneTree] when the engine starts. </description> </method> </methods> <members> - <member name="allow_object_decoding" type="bool" setter="set_allow_object_decoding" getter="is_object_decoding_allowed" default="false"> - If [code]true[/code], the MultiplayerAPI will allow encoding and decoding of object during RPCs. - [b]Warning:[/b] Deserialized objects can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threats such as remote code execution. - </member> <member name="multiplayer_peer" type="MultiplayerPeer" setter="set_multiplayer_peer" getter="get_multiplayer_peer"> The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_server]) and will set root node's network mode to authority, or it will become a regular client peer. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals. </member> - <member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" default="false"> - If [code]true[/code], the MultiplayerAPI's [member multiplayer_peer] refuses new incoming connections. - </member> - <member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath("")"> - The root path to use for RPCs and replication. Instead of an absolute path, a relative path will be used to find the node upon which the RPC should be executed. - This effectively allows to have different branches of the scene tree to be managed by different MultiplayerAPI, allowing for example to run both client and server in the same scene. - </member> </members> <signals> <signal name="connected_to_server"> @@ -107,17 +127,21 @@ Emitted when this MultiplayerAPI's [member multiplayer_peer] disconnects from a peer. Clients get notified when other clients disconnect from the same server. </description> </signal> - <signal name="peer_packet"> - <argument index="0" name="id" type="int" /> - <argument index="1" name="packet" type="PackedByteArray" /> - <description> - Emitted when this MultiplayerAPI's [member multiplayer_peer] receives a [code]packet[/code] with custom data (see [method send_bytes]). ID is the peer ID of the peer that sent the packet. - </description> - </signal> <signal name="server_disconnected"> <description> Emitted when this MultiplayerAPI's [member multiplayer_peer] disconnects from server. Only emitted on clients. </description> </signal> </signals> + <constants> + <constant name="RPC_MODE_DISABLED" value="0" enum="RPCMode"> + Used with [method Node.rpc_config] to disable a method or property for all RPC calls, making it unavailable. Default for all methods. + </constant> + <constant name="RPC_MODE_ANY_PEER" value="1" enum="RPCMode"> + Used with [method Node.rpc_config] to set a method to be callable remotely by any peer. Analogous to the [code]@rpc(any)[/code] annotation. Calls are accepted from all remote peers, no matter if they are node's authority or not. + </constant> + <constant name="RPC_MODE_AUTHORITY" value="2" enum="RPCMode"> + Used with [method Node.rpc_config] to set a method to be callable remotely only by the current multiplayer authority (which is the server by default). Analogous to the [code]@rpc(authority)[/code] annotation. See [method Node.set_multiplayer_authority]. + </constant> + </constants> </class> diff --git a/doc/classes/MultiplayerAPIExtension.xml b/doc/classes/MultiplayerAPIExtension.xml new file mode 100644 index 0000000000..c369977d57 --- /dev/null +++ b/doc/classes/MultiplayerAPIExtension.xml @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="MultiplayerAPIExtension" inherits="MultiplayerAPI" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Base class used for extending the [MultiplayerAPI]. + </brief_description> + <description> + This class can be used to augment or replace the default [MultiplayerAPI] implementation via script or extensions. + The following example augment the default implemenation ([SceneMultiplayer]) by logging every RPC being made, and every object being configured for replication. + [codeblocks] + [gdscript] + extends MultiplayerAPIExtension + class_name LogMultiplayer + + # We want to augment the default SceneMultiplayer. + var base_multiplayer = SceneMultiplayer.new() + + func _init(): + # Just passthourgh base signals (copied to var to avoid cyclic reference) + var cts = connected_to_server + var cf = connection_failed + var pc = peer_connected + var pd = peer_disconnected + base_multiplayer.connected_to_server.connect(func(): cts.emit()) + base_multiplayer.connection_failed.connect(func(): cf.emit()) + base_multiplayer.peer_connected.connect(func(id): pc.emit(id)) + base_multiplayer.peer_disconnected.connect(func(id): pd.emit(id)) + + # Log RPC being made and forward it to the default multiplayer. + func _rpc(peer: int, object: Object, method: StringName, args: Array) -> int: # Error + print("Got RPC for %d: %s::%s(%s)" % [peer, object, method, args]) + return base_multiplayer.rpc(peer, object, method, args) + + # Log configuration add. E.g. root path (nullptr, NodePath), replication (Node, Spawner|Synchronizer), custom. + func _object_configuration_add(object, config: Variant) -> int: # Error + if config is MultiplayerSynchronizer: + print("Adding synchronization configuration for %s. Synchronizer: %s" % [object, config]) + elif config is MultiplayerSpawner: + print("Adding node %s to the spawn list. Spawner: %s" % [object, config]) + return base_multiplayer.object_configuration_add(object, config) + + # Log configuration remove. E.g. root path (nullptr, NodePath), replication (Node, Spawner|Synchronizer), custom. + func _object_configuration_remove(object, config: Variant) -> int: # Error + if config is MultiplayerSynchronizer: + print("Removing synchronization configuration for %s. Synchronizer: %s" % [object, config]) + elif config is MultiplayerSpawner: + print("Removing node %s from the spawn list. Spawner: %s" % [object, config]) + return base_multiplayer.object_configuration_remove(object, config) + + # These can be optional, but in our case we want to augment SceneMultiplayer, so forward everything. + func _set_multiplayer_peer(p_peer: MultiplayerPeer): + base_multiplayer.multiplayer_peer = p_peer + + func _get_multiplayer_peer() -> MultiplayerPeer: + return base_multiplayer.multiplayer_peer + + func _get_unique_id() -> int: + return base_multiplayer.get_unique_id() + + func _get_peer_ids() -> PackedInt32Array: + return base_multiplayer.get_peers() + [/gdscript] + [/codeblocks] + Then in your main scene or in an autoload call [method SceneTree.set_multiplayer] to start using your custom [MultiplayerAPI]: + [codeblocks] + [gdscript] + # autoload.gd + func _enter_tree(): + # Sets our custom multiplayer as the main one in SceneTree. + get_tree().set_multiplayer(LogMultiplayer.new()) + [/gdscript] + [/codeblocks] + Native extensions can alternatively use the [method MultiplayerAPI.set_default_interface] method during initialization to configure themselves as the default implementation. + </description> + <tutorials> + </tutorials> + <methods> + <method name="_get_multiplayer_peer" qualifiers="virtual"> + <return type="MultiplayerPeer" /> + <description> + Called when the [member MultiplayerAPI.multiplayer_peer] is retrieved. + </description> + </method> + <method name="_get_peer_ids" qualifiers="virtual const"> + <return type="PackedInt32Array" /> + <description> + Callback for [method MultiplayerAPI.get_peers]. + </description> + </method> + <method name="_get_remote_sender_id" qualifiers="virtual const"> + <return type="int" /> + <description> + Callback for [method MultiplayerAPI.get_remote_sender_id]. + </description> + </method> + <method name="_get_unique_id" qualifiers="virtual const"> + <return type="int" /> + <description> + Callback for [method MultiplayerAPI.get_unique_id]. + </description> + </method> + <method name="_object_configuration_add" qualifiers="virtual"> + <return type="int" /> + <argument index="0" name="object" type="Object" /> + <argument index="1" name="configuration" type="Variant" /> + <description> + Callback for [method MultiplayerAPI.object_configuration_add]. + </description> + </method> + <method name="_object_configuration_remove" qualifiers="virtual"> + <return type="int" /> + <argument index="0" name="object" type="Object" /> + <argument index="1" name="configuration" type="Variant" /> + <description> + Callback for [method MultiplayerAPI.object_configuration_remove]. + </description> + </method> + <method name="_poll" qualifiers="virtual"> + <return type="int" /> + <description> + Callback for [method MultiplayerAPI.poll]. + </description> + </method> + <method name="_rpc" qualifiers="virtual"> + <return type="int" /> + <argument index="0" name="peer" type="int" /> + <argument index="1" name="object" type="Object" /> + <argument index="2" name="method" type="StringName" /> + <argument index="3" name="args" type="Array" /> + <description> + Callback for [method MultiplayerAPI.rpc]. + </description> + </method> + <method name="_set_multiplayer_peer" qualifiers="virtual"> + <return type="void" /> + <argument index="0" name="multiplayer_peer" type="MultiplayerPeer" /> + <description> + Called when the [member MultiplayerAPI.multiplayer_peer] is set. + </description> + </method> + </methods> +</class> diff --git a/doc/classes/MultiplayerPeer.xml b/doc/classes/MultiplayerPeer.xml index 4a3559b0f7..6dde40f018 100644 --- a/doc/classes/MultiplayerPeer.xml +++ b/doc/classes/MultiplayerPeer.xml @@ -60,7 +60,7 @@ The channel to use to send packets. Many network APIs such as ENet and WebRTC allow the creation of multiple independent channels which behaves, in a way, like separate connections. This means that reliable data will only block delivery of other packets on that channel, and ordering will only be in respect to the channel the packet is being sent on. Using different channels to send [b]different and independent[/b] state updates is a common way to optimize network usage and decrease latency in fast-paced games. [b]Note:[/b] The default channel ([code]0[/code]) actually works as 3 separate channels (one for each [enum TransferMode]) so that [constant TRANSFER_MODE_RELIABLE] and [constant TRANSFER_MODE_UNRELIABLE_ORDERED] does not interact with each other by default. Refer to the specific network API documentation (e.g. ENet or WebRTC) to learn how to set up channels correctly. </member> - <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" enum="TransferMode" default="2"> + <member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" enum="MultiplayerPeer.TransferMode" default="2"> The manner in which to send packets to the [code]target_peer[/code]. See [enum TransferMode]. </member> </members> @@ -109,5 +109,14 @@ <constant name="TARGET_PEER_SERVER" value="1"> Packets are sent to the server alone. </constant> + <constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode"> + Packets are not acknowledged, no resend attempts are made for lost packets. Packets may arrive in any order. Potentially faster than [constant TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always consider whether the order matters. + </constant> + <constant name="TRANSFER_MODE_UNRELIABLE_ORDERED" value="1" enum="TransferMode"> + Packets are not acknowledged, no resend attempts are made for lost packets. Packets are received in the order they were sent in. Potentially faster than [constant TRANSFER_MODE_RELIABLE]. Use for non-critical data or data that would be outdated if received late due to resend attempt(s) anyway, for example movement and positional data. + </constant> + <constant name="TRANSFER_MODE_RELIABLE" value="2" enum="TransferMode"> + Packets must be received and resend attempts should be made until the packets are acknowledged. Packets must be received in the order they were sent in. Most reliable transfer mode, but potentially the slowest due to the overhead. Use for critical data that must be transmitted and arrive in order, for example an ability being triggered or a chat message. Consider carefully if the information really is critical, and use sparingly. + </constant> </constants> </class> diff --git a/doc/classes/MultiplayerPeerExtension.xml b/doc/classes/MultiplayerPeerExtension.xml index bd11c76039..f837171e2f 100644 --- a/doc/classes/MultiplayerPeerExtension.xml +++ b/doc/classes/MultiplayerPeerExtension.xml @@ -41,6 +41,12 @@ Called when the ID of the [MultiplayerPeer] who sent the most recent packet is requested (see [method MultiplayerPeer.get_packet_peer]). </description> </method> + <method name="_get_packet_script" qualifiers="virtual"> + <return type="PackedByteArray" /> + <description> + Called when a packet needs to be received by the [MultiplayerAPI], if [method _get_packet] isn't implemented. Use this when extending this class via GDScript. + </description> + </method> <method name="_get_transfer_channel" qualifiers="virtual const"> <return type="int" /> <description> @@ -85,6 +91,13 @@ Called when a packet needs to be sent by the [MultiplayerAPI], with [code]p_buffer_size[/code] being the size of the binary [code]p_buffer[/code] in bytes. </description> </method> + <method name="_put_packet_script" qualifiers="virtual"> + <return type="int" /> + <argument index="0" name="p_buffer" type="PackedByteArray" /> + <description> + Called when a packet needs to be sent by the [MultiplayerAPI], if [method _put_packet] isn't implemented. Use this when extending this class via GDScript. + </description> + </method> <method name="_set_refuse_new_connections" qualifiers="virtual"> <return type="void" /> <argument index="0" name="p_enable" type="bool" /> diff --git a/doc/classes/MultiplayerSynchronizer.xml b/doc/classes/MultiplayerSynchronizer.xml deleted file mode 100644 index ac067791e6..0000000000 --- a/doc/classes/MultiplayerSynchronizer.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="MultiplayerSynchronizer" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <members> - <member name="replication_config" type="SceneReplicationConfig" setter="set_replication_config" getter="get_replication_config"> - </member> - <member name="replication_interval" type="float" setter="set_replication_interval" getter="get_replication_interval" default="0.0"> - </member> - <member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath("..")"> - </member> - </members> -</class> diff --git a/doc/classes/NavigationRegion2D.xml b/doc/classes/NavigationRegion2D.xml index c48ca18e9e..75b6544827 100644 --- a/doc/classes/NavigationRegion2D.xml +++ b/doc/classes/NavigationRegion2D.xml @@ -8,7 +8,7 @@ Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer2D.map_set_edge_connection_margin]. [b]Note:[/b] Overlapping two regions' polygons is not enough for connecting two regions. They must share a similar edge. The pathfinding cost of entering this region from another region can be controlled with the [member enter_cost] value. - [b]Note[/b]: This value is not added to the path cost when the start position is already inside this region. + [b]Note:[/b] This value is not added to the path cost when the start position is already inside this region. The pathfinding cost of traveling distances inside this region can be controlled with the [member travel_cost] multiplier. </description> <tutorials> diff --git a/doc/classes/NavigationRegion3D.xml b/doc/classes/NavigationRegion3D.xml index 9f4feee072..f5824a24fd 100644 --- a/doc/classes/NavigationRegion3D.xml +++ b/doc/classes/NavigationRegion3D.xml @@ -8,7 +8,7 @@ Two regions can be connected to each other if they share a similar edge. You can set the minimum distance between two vertices required to connect two edges by using [method NavigationServer3D.map_set_edge_connection_margin]. [b]Note:[/b] Overlapping two regions' navmeshes is not enough for connecting two regions. They must share a similar edge. The cost of entering this region from another region can be controlled with the [member enter_cost] value. - [b]Note[/b]: This value is not added to the path cost when the start position is already inside this region. + [b]Note:[/b] This value is not added to the path cost when the start position is already inside this region. The cost of traveling distances inside this region can be controlled with the [member travel_cost] multiplier. </description> <tutorials> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index b7591ed4f4..8cc8498609 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -622,7 +622,7 @@ </description> </method> <method name="rpc" qualifiers="vararg"> - <return type="void" /> + <return type="int" enum="Error" /> <argument index="0" name="method" type="StringName" /> <description> Sends a remote procedure call request for the given [code]method[/code] to peers on the network (and locally), optionally sending all additional arguments as arguments to the method called by the RPC. The call request will only be received by nodes with the same [NodePath], including the exact same node name. Behaviour depends on the RPC configuration for the given method, see [method rpc_config]. Methods are not exposed to RPCs by default. Returns [code]null[/code]. @@ -630,18 +630,24 @@ </description> </method> <method name="rpc_config"> - <return type="int" /> + <return type="void" /> <argument index="0" name="method" type="StringName" /> - <argument index="1" name="rpc_mode" type="int" enum="RPCMode" /> - <argument index="2" name="call_local" type="bool" default="false" /> - <argument index="3" name="transfer_mode" type="int" enum="TransferMode" default="2" /> - <argument index="4" name="channel" type="int" default="0" /> + <argument index="1" name="config" type="Variant" /> <description> - Changes the RPC mode for the given [code]method[/code] to the given [code]rpc_mode[/code], optionally specifying the [code]transfer_mode[/code] and [code]channel[/code] (on supported peers). See [enum RPCMode] and [enum TransferMode]. An alternative is annotating methods and properties with the corresponding annotation ([code]@rpc(any)[/code], [code]@rpc(authority)[/code]). By default, methods are not exposed to networking (and RPCs). + Changes the RPC mode for the given [code]method[/code] with the given [code]config[/code] which should be [code]null[/code] (to disable) or a [Dictionary] in the form: + [codeblock] + { + rpc_mode = MultiplayerAPI.RPCMode, + transfer_mode = MultiplayerPeer.TranferMode, + call_local = false, + channel = 0, + } + [/codeblock] + See [enum MultiplayerAPI.RPCMode] and [enum MultiplayerPeer.TransferMode]. An alternative is annotating methods and properties with the corresponding annotation ([code]@rpc(any)[/code], [code]@rpc(authority)[/code]). By default, methods are not exposed to networking (and RPCs). </description> </method> <method name="rpc_id" qualifiers="vararg"> - <return type="void" /> + <return type="int" enum="Error" /> <argument index="0" name="peer_id" type="int" /> <argument index="1" name="method" type="StringName" /> <description> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index aaf08dec2f..5473347cb1 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -385,6 +385,23 @@ [b]Note:[/b] Shared storage is implemented on Android and allows to differentiate between app specific and shared directories. Shared directories have additional restrictions on Android. </description> </method> + <method name="get_system_font_path" qualifiers="const"> + <return type="String" /> + <argument index="0" name="font_name" type="String" /> + <argument index="1" name="bold" type="bool" default="false" /> + <argument index="2" name="italic" type="bool" default="false" /> + <description> + Returns path to the system font file with [code]font_name[/code] and style. Return empty string if no matching fonts found. + [b]Note:[/b] This method is implemented on iOS, Linux, macOS and Windows. + </description> + </method> + <method name="get_system_fonts" qualifiers="const"> + <return type="PackedStringArray" /> + <description> + Returns list of font family names available. + [b]Note:[/b] This method is implemented on iOS, Linux, macOS and Windows. + </description> + </method> <method name="get_thread_caller_id" qualifiers="const"> <return type="int" /> <description> diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml index 6fefcef0a1..32eb71f1c7 100644 --- a/doc/classes/Plane.xml +++ b/doc/classes/Plane.xml @@ -83,9 +83,9 @@ <method name="has_point" qualifiers="const"> <return type="bool" /> <argument index="0" name="point" type="Vector3" /> - <argument index="1" name="epsilon" type="float" default="1e-05" /> + <argument index="1" name="tolerance" type="float" default="1e-05" /> <description> - Returns [code]true[/code] if [code]point[/code] is inside the plane. Comparison uses a custom minimum [code]epsilon[/code] threshold. + Returns [code]true[/code] if [code]point[/code] is inside the plane. Comparison uses a custom minimum [code]tolerance[/code] threshold. </description> </method> <method name="intersect_3" qualifiers="const"> @@ -109,7 +109,7 @@ <argument index="0" name="from" type="Vector3" /> <argument index="1" name="to" type="Vector3" /> <description> - Returns the intersection point of a segment from position [code]begin[/code] to position [code]end[/code] with this plane. If no intersection is found, [code]null[/code] is returned. + Returns the intersection point of a segment from position [code]from[/code] to position [code]to[/code] with this plane. If no intersection is found, [code]null[/code] is returned. </description> </method> <method name="is_equal_approx" qualifiers="const"> @@ -121,7 +121,7 @@ </method> <method name="is_point_over" qualifiers="const"> <return type="bool" /> - <argument index="0" name="plane" type="Vector3" /> + <argument index="0" name="point" type="Vector3" /> <description> Returns [code]true[/code] if [code]point[/code] is located above the plane. </description> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 898d34b385..a2e92fb61b 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1632,13 +1632,13 @@ Sets the number of MSAA samples to use (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware. See also bilinear scaling 3d [member rendering/scaling_3d/mode] for supersampling, which provides higher quality but is much more expensive. </member> <member name="rendering/anti_aliasing/quality/screen_space_aa" type="int" setter="" getter="" default="0"> - Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. + Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry. The blurriness can be counteracted to an extent by using a negative mipmap LOD bias ([member rendering/textures/default_filters/texture_mipmap_bias]). Another way to combat specular aliasing is to enable [member rendering/anti_aliasing/screen_space_roughness_limiter/enabled]. </member> <member name="rendering/anti_aliasing/quality/use_debanding" type="bool" setter="" getter="" default="false"> </member> <member name="rendering/anti_aliasing/quality/use_taa" type="bool" setter="" getter="" default="false"> - Enables Temporal Anti-Aliasing for the default screen [Viewport]. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion. + Enables Temporal Anti-Aliasing for the default screen [Viewport]. TAA works by jittering the camera and accumulating the images of the last rendered frames, motion vector rendering is used to account for camera and object motion. Enabling TAA can make the image blurrier, which can be counteracted to an extent by using a negative mipmap LOD bias ([member rendering/textures/default_filters/texture_mipmap_bias]). [b]Note:[/b] The implementation is not complete yet, some visual instances such as particles and skinned meshes may show artifacts. </member> <member name="rendering/anti_aliasing/screen_space_roughness_limiter/amount" type="float" setter="" getter="" default="0.25"> @@ -1856,9 +1856,6 @@ <member name="rendering/reflections/sky_reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false"> Lower-end override for [member rendering/reflections/sky_reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support. </member> - <member name="rendering/scaling_3d/fsr_mipmap_bias" type="float" setter="" getter="" default="0.0"> - Affects the final texture sharpness by reading from a lower or higher mipmap. Negative values make textures sharper, while positive values make textures blurrier. When using FSR, this value is used to adjust the mipmap bias calculated internally which is based on the selected quality. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code] - </member> <member name="rendering/scaling_3d/fsr_sharpness" type="float" setter="" getter="" default="0.2"> Determines how sharp the upscaled image will be when using the FSR upscaling mode. Sharpness halves with every whole number. Values go from 0.0 (sharpest) to 2.0. Values above 2.0 won't make a visible difference. </member> @@ -1940,6 +1937,11 @@ Sets the maximum number of samples to take when using anisotropic filtering on textures (as a power of two). A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. A value of [code]0[/code] forcibly disables anisotropic filtering, even on materials where it is enabled. [b]Note:[/b] This property is only read when the project starts. There is currently no way to change this setting at run-time. </member> + <member name="rendering/textures/default_filters/texture_mipmap_bias" type="float" setter="" getter="" default="0.0"> + Affects the final texture sharpness by reading from a lower or higher mipmap (also called "texture LOD bias"). Negative values make mipmapped textures sharper but grainier when viewed at a distance, while positive values make mipmapped textures blurrier (even when up close). To get sharper textures at a distance without introducing too much graininess, set this between [code]-0.75[/code] and [code]0.0[/code]. Enabling temporal antialiasing ([member rendering/anti_aliasing/quality/use_taa]) can help reduce the graininess visible when using negative mipmap bias. + [b]Note:[/b] When the 3D scaling mode is set to FSR 1.0, this value is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code]. + [b]Note:[/b] This property is only read when the project starts. To change the mipmap LOD bias at run-time, set [member Viewport.texture_mipmap_bias] instead. + </member> <member name="rendering/textures/default_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false"> If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used. [b]Note:[/b] This property is only read when the project starts. There is currently no way to change this setting at run-time. @@ -1986,6 +1988,12 @@ </member> <member name="rendering/vulkan/staging_buffer/texture_upload_region_size_px" type="int" setter="" getter="" default="64"> </member> + <member name="threading/worker_pool/low_priority_thread_ratio" type="float" setter="" getter="" default="0.3"> + </member> + <member name="threading/worker_pool/max_threads" type="int" setter="" getter="" default="-1"> + </member> + <member name="threading/worker_pool/use_system_threads_for_low_priority_tasks" type="bool" setter="" getter="" default="true"> + </member> <member name="xr/openxr/default_action_map" type="String" setter="" getter="" default=""res://openxr_action_map.tres""> Action map configuration to load by default. </member> diff --git a/doc/classes/Projection.xml b/doc/classes/Projection.xml new file mode 100644 index 0000000000..115015c2d7 --- /dev/null +++ b/doc/classes/Projection.xml @@ -0,0 +1,273 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Projection" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <constructors> + <constructor name="Projection"> + <return type="Projection" /> + <description> + </description> + </constructor> + <constructor name="Projection"> + <return type="Projection" /> + <argument index="0" name="from" type="Projection" /> + <description> + </description> + </constructor> + <constructor name="Projection"> + <return type="Projection" /> + <argument index="0" name="from" type="Transform3D" /> + <description> + </description> + </constructor> + </constructors> + <methods> + <method name="create_depth_correction" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="flip_y" type="bool" /> + <description> + </description> + </method> + <method name="create_fit_aabb" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="aabb" type="AABB" /> + <description> + </description> + </method> + <method name="create_for_hmd" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="eye" type="int" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="intraocular_dist" type="float" /> + <argument index="3" name="display_width" type="float" /> + <argument index="4" name="display_to_lens" type="float" /> + <argument index="5" name="oversample" type="float" /> + <argument index="6" name="z_near" type="float" /> + <argument index="7" name="z_far" type="float" /> + <description> + </description> + </method> + <method name="create_frustum" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="left" type="float" /> + <argument index="1" name="right" type="float" /> + <argument index="2" name="bottom" type="float" /> + <argument index="3" name="top" type="float" /> + <argument index="4" name="z_near" type="float" /> + <argument index="5" name="z_far" type="float" /> + <description> + </description> + </method> + <method name="create_frustum_aspect" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="size" type="float" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="offset" type="Vector2" /> + <argument index="3" name="z_near" type="float" /> + <argument index="4" name="z_far" type="float" /> + <argument index="5" name="flip_fov" type="bool" default="false" /> + <description> + </description> + </method> + <method name="create_light_atlas_rect" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="rect" type="Rect2" /> + <description> + </description> + </method> + <method name="create_orthogonal" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="left" type="float" /> + <argument index="1" name="right" type="float" /> + <argument index="2" name="bottom" type="float" /> + <argument index="3" name="top" type="float" /> + <argument index="4" name="z_near" type="float" /> + <argument index="5" name="z_far" type="float" /> + <description> + </description> + </method> + <method name="create_orthogonal_aspect" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="size" type="float" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="z_near" type="float" /> + <argument index="3" name="z_far" type="float" /> + <argument index="4" name="flip_fov" type="bool" default="false" /> + <description> + </description> + </method> + <method name="create_perspective" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="fovy" type="float" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="z_near" type="float" /> + <argument index="3" name="z_far" type="float" /> + <argument index="4" name="flip_fov" type="bool" default="false" /> + <description> + </description> + </method> + <method name="create_perspective_hmd" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="fovy" type="float" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="z_near" type="float" /> + <argument index="3" name="z_far" type="float" /> + <argument index="4" name="flip_fov" type="bool" /> + <argument index="5" name="eye" type="int" /> + <argument index="6" name="intraocular_dist" type="float" /> + <argument index="7" name=" convergence_dist" type="float" /> + <description> + </description> + </method> + <method name="determinant" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="flipped_y" qualifiers="const"> + <return type="Projection" /> + <description> + </description> + </method> + <method name="get_aspect" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="get_far_plane_half_extents" qualifiers="const"> + <return type="Vector2" /> + <description> + </description> + </method> + <method name="get_fov" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="get_fovy" qualifiers="static"> + <return type="float" /> + <argument index="0" name="fovx" type="float" /> + <argument index="1" name="aspect" type="float" /> + <description> + </description> + </method> + <method name="get_lod_multiplier" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="get_pixels_per_meter" qualifiers="const"> + <return type="int" /> + <argument index="0" name="for_pixel_width" type="int" /> + <description> + </description> + </method> + <method name="get_projection_plane" qualifiers="const"> + <return type="Plane" /> + <argument index="0" name="plane" type="int" /> + <description> + </description> + </method> + <method name="get_viewport_half_extents" qualifiers="const"> + <return type="Vector2" /> + <description> + </description> + </method> + <method name="get_z_far" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="get_z_near" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="inverse" qualifiers="const"> + <return type="Projection" /> + <description> + </description> + </method> + <method name="is_orthogonal" qualifiers="const"> + <return type="bool" /> + <description> + </description> + </method> + <method name="jitter_offseted" qualifiers="const"> + <return type="Projection" /> + <argument index="0" name="offset" type="Vector2" /> + <description> + </description> + </method> + <method name="perspective_znear_adjusted" qualifiers="const"> + <return type="Projection" /> + <argument index="0" name="new_znear" type="float" /> + <description> + </description> + </method> + </methods> + <members> + <member name="w" type="Vector4" setter="" getter="" default="Vector4(0, 0, 0)"> + </member> + <member name="x" type="Vector4" setter="" getter="" default="Vector4(1, 0, 0)"> + </member> + <member name="y" type="Vector4" setter="" getter="" default="Vector4(0, 1, 0)"> + </member> + <member name="z" type="Vector4" setter="" getter="" default="Vector4(0, 0, 1)"> + </member> + </members> + <constants> + <constant name="PLANE_NEAR" value="0"> + </constant> + <constant name="PLANE_FAR" value="1"> + </constant> + <constant name="PLANE_LEFT" value="2"> + </constant> + <constant name="PLANE_TOP" value="3"> + </constant> + <constant name="PLANE_RIGHT" value="4"> + </constant> + <constant name="PLANE_BOTTOM" value="5"> + </constant> + <constant name="IDENTITY" value="Projection(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)"> + </constant> + <constant name="ZERO" value="Projection(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)"> + </constant> + </constants> + <operators> + <operator name="operator !="> + <return type="bool" /> + <argument index="0" name="right" type="Projection" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Projection" /> + <argument index="0" name="right" type="Projection" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator =="> + <return type="bool" /> + <argument index="0" name="right" type="Projection" /> + <description> + </description> + </operator> + <operator name="operator []"> + <return type="Vector4" /> + <argument index="0" name="index" type="int" /> + <description> + </description> + </operator> + </operators> +</class> diff --git a/doc/classes/Quaternion.xml b/doc/classes/Quaternion.xml index 48e6317b11..30e96607da 100644 --- a/doc/classes/Quaternion.xml +++ b/doc/classes/Quaternion.xml @@ -74,16 +74,6 @@ [b]Note:[/b] This method has an abnormally high amount of floating-point error, so methods such as [code]is_zero_approx[/code] will not work reliably. </description> </method> - <method name="cubic_slerp" qualifiers="const"> - <return type="Quaternion" /> - <argument index="0" name="b" type="Quaternion" /> - <argument index="1" name="pre_a" type="Quaternion" /> - <argument index="2" name="post_b" type="Quaternion" /> - <argument index="3" name="weight" type="float" /> - <description> - Performs a cubic spherical interpolation between quaternions [code]pre_a[/code], this vector, [code]b[/code], and [code]post_b[/code], by the given amount [code]weight[/code]. - </description> - </method> <method name="dot" qualifiers="const"> <return type="float" /> <argument index="0" name="with" type="Quaternion" /> @@ -171,6 +161,16 @@ Returns the result of the spherical linear interpolation between this quaternion and [code]to[/code] by amount [code]weight[/code], but without checking if the rotation path is not bigger than 90 degrees. </description> </method> + <method name="spherical_cubic_interpolate" qualifiers="const"> + <return type="Quaternion" /> + <argument index="0" name="b" type="Quaternion" /> + <argument index="1" name="pre_a" type="Quaternion" /> + <argument index="2" name="post_b" type="Quaternion" /> + <argument index="3" name="weight" type="float" /> + <description> + Performs a spherical cubic interpolation between quaternions [code]pre_a[/code], this vector, [code]b[/code], and [code]post_b[/code], by the given amount [code]weight[/code]. + </description> + </method> </methods> <members> <member name="w" type="float" setter="" getter="" default="1.0"> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 6199c7b4e6..9616ab3515 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1293,45 +1293,45 @@ If [code]half_resolution[/code] is [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting. See also [member ProjectSettings.rendering/global_illumination/gi/use_half_resolution]. </description> </method> - <method name="global_variable_add"> + <method name="global_shader_uniform_add"> <return type="void" /> <argument index="0" name="name" type="StringName" /> - <argument index="1" name="type" type="int" enum="RenderingServer.GlobalVariableType" /> + <argument index="1" name="type" type="int" enum="RenderingServer.GlobalShaderUniformType" /> <argument index="2" name="default_value" type="Variant" /> <description> </description> </method> - <method name="global_variable_get" qualifiers="const"> + <method name="global_shader_uniform_get" qualifiers="const"> <return type="Variant" /> <argument index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_variable_get_list" qualifiers="const"> + <method name="global_shader_uniform_get_list" qualifiers="const"> <return type="PackedStringArray" /> <description> </description> </method> - <method name="global_variable_get_type" qualifiers="const"> - <return type="int" enum="RenderingServer.GlobalVariableType" /> + <method name="global_shader_uniform_get_type" qualifiers="const"> + <return type="int" enum="RenderingServer.GlobalShaderUniformType" /> <argument index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_variable_remove"> + <method name="global_shader_uniform_remove"> <return type="void" /> <argument index="0" name="name" type="StringName" /> <description> </description> </method> - <method name="global_variable_set"> + <method name="global_shader_uniform_set"> <return type="void" /> <argument index="0" name="name" type="StringName" /> <argument index="1" name="value" type="Variant" /> <description> </description> </method> - <method name="global_variable_set_override"> + <method name="global_shader_uniform_set_override"> <return type="void" /> <argument index="0" name="name" type="StringName" /> <argument index="1" name="value" type="Variant" /> @@ -2748,6 +2748,13 @@ Returns the parameters of a shader. </description> </method> + <method name="shader_set_code"> + <return type="void" /> + <argument index="0" name="shader" type="RID" /> + <argument index="1" name="code" type="String" /> + <description> + </description> + </method> <method name="shader_set_default_texture_param"> <return type="void" /> <argument index="0" name="shader" type="RID" /> @@ -2759,6 +2766,13 @@ [b]Note:[/b] If the sampler array is used use [code]index[/code] to access the specified texture. </description> </method> + <method name="shader_set_path_hint"> + <return type="void" /> + <argument index="0" name="shader" type="RID" /> + <argument index="1" name="path" type="String" /> + <description> + </description> + </method> <method name="skeleton_allocate_data"> <return type="void" /> <argument index="0" name="skeleton" type="RID" /> @@ -3161,14 +3175,6 @@ If [code]true[/code], rendering of a viewport's environment is disabled. </description> </method> - <method name="viewport_set_fsr_mipmap_bias"> - <return type="void" /> - <argument index="0" name="viewport" type="RID" /> - <argument index="1" name="mipmap_bias" type="float" /> - <description> - Affects the final texture sharpness by reading from a lower or higher mipmap. Negative values make textures sharper, while positive values make textures blurrier. When using FSR, this value is used to adjust the mipmap bias calculated internally which is based on the selected quality. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code] - </description> - </method> <method name="viewport_set_fsr_sharpness"> <return type="void" /> <argument index="0" name="viewport" type="RID" /> @@ -3311,6 +3317,15 @@ <description> </description> </method> + <method name="viewport_set_texture_mipmap_bias"> + <return type="void" /> + <argument index="0" name="viewport" type="RID" /> + <argument index="1" name="mipmap_bias" type="float" /> + <description> + Affects the final texture sharpness by reading from a lower or higher mipmap (also called "texture LOD bias"). Negative values make mipmapped textures sharper but grainier when viewed at a distance, while positive values make mipmapped textures blurrier (even when up close). To get sharper textures at a distance without introducing too much graininess, set this between [code]-0.75[/code] and [code]0.0[/code]. Enabling temporal antialiasing ([member ProjectSettings.rendering/anti_aliasing/quality/use_taa]) can help reduce the graininess visible when using negative mipmap bias. + [b]Note:[/b] When the 3D scaling mode is set to FSR 1.0, this value is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code]. + </description> + </method> <method name="viewport_set_transparent_background"> <return type="void" /> <argument index="0" name="viewport" type="RID" /> @@ -4522,63 +4537,63 @@ <constant name="CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE" value="2" enum="CanvasOccluderPolygonCullMode"> Culling of the canvas occluder is counterclockwise. </constant> - <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalShaderUniformType"> </constant> - <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalVariableType"> + <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalShaderUniformType"> </constant> <constant name="RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME" value="0" enum="RenderingInfo"> </constant> diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml index 36b64f5a86..fef94b5f3b 100644 --- a/doc/classes/ResourceFormatLoader.xml +++ b/doc/classes/ResourceFormatLoader.xml @@ -17,6 +17,12 @@ <description> </description> </method> + <method name="_get_classes_used" qualifiers="virtual const"> + <return type="PackedStringArray" /> + <argument index="0" name="path" type="String" /> + <description> + </description> + </method> <method name="_get_dependencies" qualifiers="virtual const"> <return type="PackedStringArray" /> <argument index="0" name="path" type="String" /> diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml index d6e9a233b0..dd52d09750 100644 --- a/doc/classes/ResourceLoader.xml +++ b/doc/classes/ResourceLoader.xml @@ -6,6 +6,7 @@ <description> Singleton used to load resource files from the filesystem. It uses the many [ResourceFormatLoader] classes registered in the engine (either built-in or from a plugin) to load files into memory and convert them to a format that can be used by the engine. + [b]Note:[/b] You have to import the files into the engine first to load them using [method load]. If you want to load [Image]s at run-time, you may use [method Image.load]. If you want to import audio files, you can use the snippet described in [member AudioStreamMP3.data]. </description> <tutorials> <link title="OS Test Demo">https://godotengine.org/asset-library/asset/677</link> @@ -17,7 +18,7 @@ <argument index="1" name="at_front" type="bool" default="false" /> <description> Registers a new [ResourceFormatLoader]. The ResourceLoader will use the ResourceFormatLoader as described in [method load]. - This method is performed implictly for ResourceFormatLoaders written in GDScript (see [ResourceFormatLoader] for more information). + This method is performed implicitly for ResourceFormatLoaders written in GDScript (see [ResourceFormatLoader] for more information). </description> </method> <method name="exists"> diff --git a/doc/classes/ResourceSaver.xml b/doc/classes/ResourceSaver.xml index 213d8c585a..240c72a131 100644 --- a/doc/classes/ResourceSaver.xml +++ b/doc/classes/ResourceSaver.xml @@ -16,7 +16,7 @@ <argument index="1" name="at_front" type="bool" default="false" /> <description> Registers a new [ResourceFormatSaver]. The ResourceSaver will use the ResourceFormatSaver as described in [method save]. - This method is performed implictly for ResourceFormatSavers written in GDScript (see [ResourceFormatSaver] for more information). + This method is performed implicitly for ResourceFormatSavers written in GDScript (see [ResourceFormatSaver] for more information). </description> </method> <method name="get_recognized_extensions"> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 3c9e9b1bfc..8228bcc442 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -272,6 +272,7 @@ <method name="push_font"> <return type="void" /> <argument index="0" name="font" type="Font" /> + <argument index="1" name="font_size" type="int" /> <description> Adds a [code][font][/code] tag to the tag stack. Overrides default fonts for its duration. </description> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index cf6ab977db..9982cc0d60 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -18,8 +18,7 @@ <argument index="0" name="group" type="StringName" /> <argument index="1" name="method" type="StringName" /> <description> - Calls [code]method[/code] on each member of the given group. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. - [b]Note:[/b] Due to design limitations, [method call_group] will fail silently if one of the arguments is [code]null[/code]. + Calls [code]method[/code] on each member of the given group. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. If a node doesn't have the given method or the argument list does not match (either in count or in types), it will be skipped. [b]Note:[/b] [method call_group] will call methods immediately on all members at once, which can cause stuttering if an expensive method is called on lots of members. To wait for one frame after [method call_group] was called, use [method call_group_flags] with the [constant GROUP_CALL_DEFERRED] flag. </description> </method> @@ -29,12 +28,11 @@ <argument index="1" name="group" type="StringName" /> <argument index="2" name="method" type="StringName" /> <description> - Calls [code]method[/code] on each member of the given group, respecting the given [enum GroupCallFlags]. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. + Calls [code]method[/code] on each member of the given group, respecting the given [enum GroupCallFlags]. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. If a node doesn't have the given method or the argument list does not match (either in count or in types), it will be skipped. [codeblock] # Call the method in a deferred manner and in reverse order. get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED | SceneTree.GROUP_CALL_REVERSE) [/codeblock] - [b]Note:[/b] Due to design limitations, [method call_group_flags] will fail silently if one of the arguments is [code]null[/code]. [b]Note:[/b] Group call flags are used to control the method calling behavior. By default, methods will be called immediately in a way similar to [method call_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [code]flags[/code] argument, methods will be called with a one-frame delay in a way similar to [method Object.set_deferred]. </description> </method> diff --git a/doc/classes/ScriptExtension.xml b/doc/classes/ScriptExtension.xml index 91fa6206d7..4e432ca9a8 100644 --- a/doc/classes/ScriptExtension.xml +++ b/doc/classes/ScriptExtension.xml @@ -65,8 +65,8 @@ <description> </description> </method> - <method name="_get_rpc_methods" qualifiers="virtual const"> - <return type="Dictionary[]" /> + <method name="_get_rpc_config" qualifiers="virtual const"> + <return type="Variant" /> <description> </description> </method> diff --git a/doc/classes/ShaderInclude.xml b/doc/classes/ShaderInclude.xml new file mode 100644 index 0000000000..40072a933b --- /dev/null +++ b/doc/classes/ShaderInclude.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="ShaderInclude" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <members> + <member name="code" type="String" setter="set_code" getter="get_code" default=""""> + </member> + </members> +</class> diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index f271220989..6295724aa2 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -392,6 +392,10 @@ <members> <member name="animate_physical_bones" type="bool" setter="set_animate_physical_bones" getter="get_animate_physical_bones" default="true"> </member> + <member name="motion_scale" type="float" setter="set_motion_scale" getter="get_motion_scale" default="1.0"> + Multiplies the position 3D track animation. + [b]Note:[/b] Unless this value is [code]1.0[/code], the key value in animation will not match the actual position value. + </member> <member name="show_rest_only" type="bool" setter="set_show_rest_only" getter="is_show_rest_only" default="false"> </member> </members> diff --git a/doc/classes/SkeletonProfile.xml b/doc/classes/SkeletonProfile.xml index a7f5f7a0a6..5c2d0eefb4 100644 --- a/doc/classes/SkeletonProfile.xml +++ b/doc/classes/SkeletonProfile.xml @@ -162,12 +162,20 @@ </member> <member name="group_size" type="int" setter="set_group_size" getter="get_group_size" default="0"> </member> + <member name="root_bone" type="StringName" setter="set_root_bone" getter="get_root_bone" default="&"""> + A name of bone that will be used as the root bone in [AnimationTree]. + [b]Note:[/b] In most cases, it is the bone of the parent of the hips that exists at the world origin in the humanoid model. + </member> + <member name="scale_base_bone" type="StringName" setter="set_scale_base_bone" getter="get_scale_base_bone" default="&"""> + A name of bone which height will be used as the coefficient for normalization. + [b]Note:[/b] In most cases, it is hips in the humanoid model. + </member> </members> <signals> <signal name="profile_updated"> <description> This signal is emitted when change the value in profile. This is used to update key name in the [BoneMap] and to redraw the [BoneMap] editor. - [b]Note[/b]: This signal is not connected directly to editor to simplify the reference, instead it is passed on to editor through the [BoneMap]. + [b]Note:[/b] This signal is not connected directly to editor to simplify the reference, instead it is passed on to editor through the [BoneMap]. </description> </signal> </signals> diff --git a/doc/classes/SkeletonProfileHumanoid.xml b/doc/classes/SkeletonProfileHumanoid.xml index 065184244e..11f0521718 100644 --- a/doc/classes/SkeletonProfileHumanoid.xml +++ b/doc/classes/SkeletonProfileHumanoid.xml @@ -10,5 +10,7 @@ <members> <member name="bone_size" type="int" setter="set_bone_size" getter="get_bone_size" overrides="SkeletonProfile" default="56" /> <member name="group_size" type="int" setter="set_group_size" getter="get_group_size" overrides="SkeletonProfile" default="4" /> + <member name="root_bone" type="StringName" setter="set_root_bone" getter="get_root_bone" overrides="SkeletonProfile" default="&"Root"" /> + <member name="scale_base_bone" type="StringName" setter="set_scale_base_bone" getter="get_scale_base_bone" overrides="SkeletonProfile" default="&"Hips"" /> </members> </class> diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index 41b02b6dc9..bc381578d9 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -77,7 +77,7 @@ </member> <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority" default="0"> Sets the render priority for the sprite. Higher priority objects will be sorted in front of lower priority objects. - [b]Node:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). + [b]Note:[/b] This only applies if [member alpha_cut] is set to [constant ALPHA_CUT_DISABLED] (default value). [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). </member> <member name="shaded" type="bool" setter="set_draw_flag" getter="get_draw_flag" default="false"> diff --git a/doc/classes/SystemFont.xml b/doc/classes/SystemFont.xml new file mode 100644 index 0000000000..b1b78f1705 --- /dev/null +++ b/doc/classes/SystemFont.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SystemFont" inherits="Font" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Font loaded from a system font. + [b]Note:[/b] This class is implemented on iOS, Linux, macOS and Windows, on other platforms it will fallback to default theme font. + </brief_description> + <description> + [SystemFont] loads a font from a system font with the first matching name from [member font_names]. + It will attempt to match font style, but it's not guaranteed. + The returned font might be part of a font collection or be a variable font with OpenType "weight" and/or "italic" features set. + You can create [FontVariation] of the system font for fine control over its features. + </description> + <tutorials> + </tutorials> + <members> + <member name="antialiased" type="bool" setter="set_antialiased" getter="is_antialiased" default="true"> + If set to [code]true[/code], font 8-bit anitialiased glyph rendering is supported and enabled. + </member> + <member name="fallbacks" type="Font[]" setter="set_fallbacks" getter="get_fallbacks" default="[]"> + Array of fallback [Font]s. + </member> + <member name="font_names" type="PackedStringArray" setter="set_font_names" getter="get_font_names" default="PackedStringArray()"> + Array of font family names to search, first matching font found is used. + </member> + <member name="font_style" type="int" setter="set_font_style" getter="get_font_style" enum="TextServer.FontStyle" default="0"> + Font style flags, see [enum TextServer.FontStyle]. + </member> + <member name="force_autohinter" type="bool" setter="set_force_autohinter" getter="is_force_autohinter" default="false"> + If set to [code]true[/code], auto-hinting is supported and preferred over font built-in hinting. + </member> + <member name="generate_mipmaps" type="bool" setter="set_generate_mipmaps" getter="get_generate_mipmaps" default="false"> + If set to [code]true[/code], generate mipmaps for the font textures. + </member> + <member name="hinting" type="int" setter="set_hinting" getter="get_hinting" enum="TextServer.Hinting" default="1"> + Font hinting mode. + </member> + <member name="oversampling" type="float" setter="set_oversampling" getter="get_oversampling" default="0.0"> + Font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. + </member> + <member name="subpixel_positioning" type="int" setter="set_subpixel_positioning" getter="get_subpixel_positioning" enum="TextServer.SubpixelPositioning" default="1"> + Font glyph sub-pixel positioning mode. Subpixel positioning provides shaper text and better kerning for smaller font sizes, at the cost of memory usage and font rasterization speed. Use [constant TextServer.SUBPIXEL_POSITIONING_AUTO] to automatically enable it based on the font size. + </member> + </members> +</class> diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 10ccad973f..ad52b2f2f1 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -591,7 +591,7 @@ Tile coordinates layout where both axis stay consistent with their respective local horizontal and vertical axis. </constant> <constant name="TILE_LAYOUT_STACKED_OFFSET" value="1" enum="TileLayout"> - Same as [code]TILE_LAYOUT_STAKED[/code], but the first half-offset is negative instead of positive. + Same as [constant TILE_LAYOUT_STACKED], but the first half-offset is negative instead of positive. </constant> <constant name="TILE_LAYOUT_STAIRS_RIGHT" value="2" enum="TileLayout"> Tile coordinates layout where the horizontal axis stay horizontal, and the vertical one goes down-right. diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index e1f7ff21d0..924b4cd8e4 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -173,7 +173,7 @@ Sets the transform's skew (in radians). </description> </method> - <method name="translated" qualifiers="const"> + <method name="translated_local" qualifiers="const"> <return type="Transform2D" /> <argument index="0" name="offset" type="Vector2" /> <description> diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml index afd11b6c77..de1db718c2 100644 --- a/doc/classes/Transform3D.xml +++ b/doc/classes/Transform3D.xml @@ -39,6 +39,12 @@ </constructor> <constructor name="Transform3D"> <return type="Transform3D" /> + <argument index="0" name="from" type="Projection" /> + <description> + </description> + </constructor> + <constructor name="Transform3D"> + <return type="Transform3D" /> <argument index="0" name="x_axis" type="Vector3" /> <argument index="1" name="y_axis" type="Vector3" /> <argument index="2" name="z_axis" type="Vector3" /> @@ -106,7 +112,7 @@ Returns a copy of the transform with its basis and origin scaled by the given [code]scale[/code] factor, using matrix multiplication. </description> </method> - <method name="sphere_interpolate_with" qualifiers="const"> + <method name="spherical_interpolate_with" qualifiers="const"> <return type="Transform3D" /> <argument index="0" name="xform" type="Transform3D" /> <argument index="1" name="weight" type="float" /> @@ -114,7 +120,7 @@ Returns a transform spherically interpolated between this transform and another by a given [code]weight[/code] (on the range of 0.0 to 1.0). </description> </method> - <method name="translated" qualifiers="const"> + <method name="translated_local" qualifiers="const"> <return type="Transform3D" /> <argument index="0" name="offset" type="Vector3" /> <description> diff --git a/doc/classes/Vector4.xml b/doc/classes/Vector4.xml new file mode 100644 index 0000000000..4df3bbb80e --- /dev/null +++ b/doc/classes/Vector4.xml @@ -0,0 +1,332 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Vector4" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Vector used for 4D math using floating point coordinates. + </brief_description> + <description> + 4-element structure that can be used to represent any quadruplet of numeric values. + It uses floating-point coordinates. See [Vector4i] for its integer counterpart. + [b]Note:[/b] In a boolean context, a Vector4 will evaluate to [code]false[/code] if it's equal to [code]Vector4(0, 0, 0, 0)[/code]. Otherwise, a Vector4 will always evaluate to [code]true[/code]. + </description> + <tutorials> + </tutorials> + <constructors> + <constructor name="Vector4"> + <return type="Vector4" /> + <description> + Constructs a default-initialized [Vector4] with all components set to [code]0[/code]. + </description> + </constructor> + <constructor name="Vector4"> + <return type="Vector4" /> + <argument index="0" name="from" type="Vector4" /> + <description> + Constructs a [Vector4] as a copy of the given [Vector4]. + </description> + </constructor> + <constructor name="Vector4"> + <return type="Vector4" /> + <argument index="0" name="from" type="Vector4i" /> + <description> + Constructs a new [Vector4] from [Vector4i]. + </description> + </constructor> + <constructor name="Vector4"> + <return type="Vector4" /> + <argument index="0" name="x" type="float" /> + <argument index="1" name="y" type="float" /> + <argument index="2" name="z" type="float" /> + <argument index="3" name="w" type="float" /> + <description> + Returns a [Vector4] with the given components. + </description> + </constructor> + </constructors> + <methods> + <method name="abs" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns a new vector with all components in absolute values (i.e. positive). + </description> + </method> + <method name="ceil" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns a new vector with all components rounded up (towards positive infinity). + </description> + </method> + <method name="clamp" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="min" type="Vector4" /> + <argument index="1" name="max" type="Vector4" /> + <description> + Returns a new vector with all components clamped between the components of [code]min[/code] and [code]max[/code], by running [method @GlobalScope.clamp] on each component. + </description> + </method> + <method name="dot" qualifiers="const"> + <return type="float" /> + <argument index="0" name="with" type="Vector4" /> + <description> + Returns the dot product of this vector and [code]with[/code]. + </description> + </method> + <method name="floor" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns a new vector with all components rounded down (towards negative infinity). + </description> + </method> + <method name="inverse" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns the inverse of the vector. This is the same as [code]Vector4(1.0 / v.x, 1.0 / v.y, 1.0 / v.z, 1.0 / v.w)[/code]. + </description> + </method> + <method name="is_equal_approx" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="with" type="Vector4" /> + <description> + Returns [code]true[/code] if this vector and [code]v[/code] are approximately equal, by running [method @GlobalScope.is_equal_approx] on each component. + </description> + </method> + <method name="is_normalized" qualifiers="const"> + <return type="bool" /> + <description> + Returns [code]true[/code] if the vector is normalized, i.e. its length is equal to 1. + </description> + </method> + <method name="length" qualifiers="const"> + <return type="float" /> + <description> + Returns the length (magnitude) of this vector. + </description> + </method> + <method name="length_squared" qualifiers="const"> + <return type="float" /> + <description> + Returns the squared length (squared magnitude) of this vector. This method runs faster than [method length]. + </description> + </method> + <method name="lerp" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="to" type="Vector4" /> + <argument index="1" name="weight" type="float" /> + <description> + Returns the result of the linear interpolation between this vector and [code]to[/code] by amount [code]weight[/code]. [code]weight[/code] is on the range of [code]0.0[/code] to [code]1.0[/code], representing the amount of interpolation. + </description> + </method> + <method name="max_axis_index" qualifiers="const"> + <return type="int" /> + <description> + Returns the axis of the vector's highest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_X]. + </description> + </method> + <method name="min_axis_index" qualifiers="const"> + <return type="int" /> + <description> + Returns the axis of the vector's lowest value. See [code]AXIS_*[/code] constants. If all components are equal, this method returns [constant AXIS_W]. + </description> + </method> + <method name="normalized" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns the vector scaled to unit length. Equivalent to [code]v / v.length()[/code]. + </description> + </method> + <method name="round" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns a new vector with all components rounded to the nearest integer, with halfway cases rounded away from zero. + </description> + </method> + <method name="sign" qualifiers="const"> + <return type="Vector4" /> + <description> + Returns a new vector with each component set to one or negative one, depending on the signs of the components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component. + </description> + </method> + </methods> + <members> + <member name="w" type="float" setter="" getter="" default="0.0"> + The vector's W component. Also accessible by using the index position [code][3][/code]. + </member> + <member name="x" type="float" setter="" getter="" default="0.0"> + The vector's X component. Also accessible by using the index position [code][0][/code]. + </member> + <member name="y" type="float" setter="" getter="" default="0.0"> + The vector's Y component. Also accessible by using the index position [code][1][/code]. + </member> + <member name="z" type="float" setter="" getter="" default="0.0"> + The vector's Z component. Also accessible by using the index position [code][2][/code]. + </member> + </members> + <constants> + <constant name="AXIS_X" value="0"> + Enumerated value for the X axis. Returned by [method max_axis_index] and [method min_axis_index]. + </constant> + <constant name="AXIS_Y" value="1"> + Enumerated value for the Y axis. Returned by [method max_axis_index] and [method min_axis_index]. + </constant> + <constant name="AXIS_Z" value="2"> + Enumerated value for the Z axis. Returned by [method max_axis_index] and [method min_axis_index]. + </constant> + <constant name="AXIS_W" value="3"> + Enumerated value for the W axis. Returned by [method max_axis_index] and [method min_axis_index]. + </constant> + <constant name="ZERO" value="Vector4(0, 0, 0)"> + Zero vector, a vector with all components set to [code]0[/code]. + </constant> + <constant name="ONE" value="Vector4(1, 1, 1)"> + One vector, a vector with all components set to [code]1[/code]. + </constant> + <constant name="INF" value="Vector4(inf, inf, inf)"> + Infinity vector, a vector with all components set to [constant @GDScript.INF]. + </constant> + </constants> + <operators> + <operator name="operator !="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Returns [code]true[/code] if the vectors are not equal. + [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Projection" /> + <description> + Inversely transforms (multiplies) the [Vector4] by the given [Projection] matrix. + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Multiplies each component of the [Vector4] by the components of the given [Vector4]. + [codeblock] + print(Vector4(10, 20, 30, 40) * Vector4(3, 4, 5, 6)) # Prints "(30, 80, 150, 240)" + [/codeblock] + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="float" /> + <description> + Multiplies each component of the [Vector4] by the given [float]. + [codeblock] + print(Vector4(10, 20, 30, 40) * 2) # Prints "(20, 40, 60, 80)" + [/codeblock] + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="int" /> + <description> + Multiplies each component of the [Vector4] by the given [int]. + </description> + </operator> + <operator name="operator +"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Adds each component of the [Vector4] by the components of the given [Vector4]. + [codeblock] + print(Vector4(10, 20, 30, 40) + Vector4(3, 4, 5, 6)) # Prints "(13, 24, 35, 46)" + [/codeblock] + </description> + </operator> + <operator name="operator -"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Subtracts each component of the [Vector4] by the components of the given [Vector4]. + [codeblock] + print(Vector4(10, 20, 30, 40) - Vector4(3, 4, 5, 6)) # Prints "(7, 16, 25, 34)" + [/codeblock] + </description> + </operator> + <operator name="operator /"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Divides each component of the [Vector4] by the components of the given [Vector4]. + [codeblock] + print(Vector4(10, 20, 30, 40) / Vector4(2, 5, 3, 4)) # Prints "(5, 4, 10, 10)" + [/codeblock] + </description> + </operator> + <operator name="operator /"> + <return type="Vector4" /> + <argument index="0" name="right" type="float" /> + <description> + Divides each component of the [Vector4] by the given [float]. + [codeblock] + print(Vector4(10, 20, 30, 40) / 2 # Prints "(5, 10, 15, 20)" + [/codeblock] + </description> + </operator> + <operator name="operator /"> + <return type="Vector4" /> + <argument index="0" name="right" type="int" /> + <description> + Divides each component of the [Vector4] by the given [int]. + </description> + </operator> + <operator name="operator <"> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Compares two [Vector4] vectors by first checking if the X value of the left vector is less than the X value of the [code]right[/code] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. + </description> + </operator> + <operator name="operator <="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Compares two [Vector4] vectors by first checking if the X value of the left vector is less than or equal to the X value of the [code]right[/code] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. + </description> + </operator> + <operator name="operator =="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Returns [code]true[/code] if the vectors are exactly equal. + [b]Note:[/b] Due to floating-point precision errors, consider using [method is_equal_approx] instead, which is more reliable. + </description> + </operator> + <operator name="operator >"> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Compares two [Vector4] vectors by first checking if the X value of the left vector is greater than the X value of the [code]right[/code] vector. If the X values are exactly equal, then it repeats this check with the Y values of the two vectors, Z values of the two vectors, and then with the W values. This operator is useful for sorting vectors. + </description> + </operator> + <operator name="operator >="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + Access vector components using their index. [code]v[0][/code] is equivalent to [code]v.x[/code], [code]v[1][/code] is equivalent to [code]v.y[/code], and [code]v[2][/code] is equivalent to [code]v.z[/code]. + </description> + </operator> + <operator name="operator []"> + <return type="float" /> + <argument index="0" name="index" type="int" /> + <description> + Access vector components using their index. [code]v[0][/code] is equivalent to [code]v.x[/code], [code]v[1][/code] is equivalent to [code]v.y[/code], [code]v[2][/code] is equivalent to [code]v.z[/code], and [code]v[3][/code] is equivalent to [code]v.w[/code]. + </description> + </operator> + <operator name="operator unary+"> + <return type="Vector4" /> + <description> + Returns the same value as if the [code]+[/code] was not there. Unary [code]+[/code] does nothing, but sometimes it can make your code more readable. + </description> + </operator> + <operator name="operator unary-"> + <return type="Vector4" /> + <description> + Returns the negative value of the [Vector4]. This is the same as writing [code]Vector4(-v.x, -v.y, -v.z, -v.w)[/code]. This operation flips the direction of the vector while keeping the same magnitude. With floats, the number zero can be either positive or negative. + </description> + </operator> + </operators> +</class> diff --git a/doc/classes/Vector4i.xml b/doc/classes/Vector4i.xml new file mode 100644 index 0000000000..3611b17757 --- /dev/null +++ b/doc/classes/Vector4i.xml @@ -0,0 +1,214 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Vector4i" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <constructors> + <constructor name="Vector4i"> + <return type="Vector4i" /> + <description> + </description> + </constructor> + <constructor name="Vector4i"> + <return type="Vector4i" /> + <argument index="0" name="from" type="Vector4i" /> + <description> + </description> + </constructor> + <constructor name="Vector4i"> + <return type="Vector4i" /> + <argument index="0" name="from" type="Vector4" /> + <description> + </description> + </constructor> + <constructor name="Vector4i"> + <return type="Vector4i" /> + <argument index="0" name="x" type="int" /> + <argument index="1" name="y" type="int" /> + <argument index="2" name="z" type="int" /> + <argument index="3" name="w" type="int" /> + <description> + </description> + </constructor> + </constructors> + <methods> + <method name="abs" qualifiers="const"> + <return type="Vector4i" /> + <description> + </description> + </method> + <method name="clamp" qualifiers="const"> + <return type="Vector4i" /> + <argument index="0" name="min" type="Vector4i" /> + <argument index="1" name="max" type="Vector4i" /> + <description> + </description> + </method> + <method name="length" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="length_squared" qualifiers="const"> + <return type="int" /> + <description> + </description> + </method> + <method name="max_axis_index" qualifiers="const"> + <return type="int" /> + <description> + </description> + </method> + <method name="min_axis_index" qualifiers="const"> + <return type="int" /> + <description> + </description> + </method> + <method name="sign" qualifiers="const"> + <return type="Vector4i" /> + <description> + </description> + </method> + </methods> + <members> + <member name="w" type="int" setter="" getter="" default="0"> + </member> + <member name="x" type="int" setter="" getter="" default="0"> + </member> + <member name="y" type="int" setter="" getter="" default="0"> + </member> + <member name="z" type="int" setter="" getter="" default="0"> + </member> + </members> + <constants> + <constant name="AXIS_X" value="0"> + </constant> + <constant name="AXIS_Y" value="1"> + </constant> + <constant name="AXIS_Z" value="2"> + </constant> + <constant name="AXIS_W" value="3"> + </constant> + <constant name="ZERO" value="Vector4i(0, 0, 0)"> + </constant> + <constant name="ONE" value="Vector4i(1, 1, 1)"> + </constant> + </constants> + <operators> + <operator name="operator !="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator %"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator %"> + <return type="Vector4i" /> + <argument index="0" name="right" type="int" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="float" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4i" /> + <argument index="0" name="right" type="int" /> + <description> + </description> + </operator> + <operator name="operator +"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator -"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4" /> + <argument index="0" name="right" type="float" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4i" /> + <argument index="0" name="right" type="int" /> + <description> + </description> + </operator> + <operator name="operator <"> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator <="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator =="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator >"> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator >="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator []"> + <return type="int" /> + <argument index="0" name="index" type="int" /> + <description> + </description> + </operator> + <operator name="operator unary+"> + <return type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator unary-"> + <return type="Vector4i" /> + <description> + </description> + </operator> + </operators> +</class> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 53603b5356..0808a8f1cf 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -196,10 +196,6 @@ <member name="disable_3d" type="bool" setter="set_disable_3d" getter="is_3d_disabled" default="false"> Disable 3D rendering (but keep 2D rendering). </member> - <member name="fsr_mipmap_bias" type="float" setter="set_fsr_mipmap_bias" getter="get_fsr_mipmap_bias" default="0.0"> - Affects the final texture sharpness by reading from a lower or higher mipmap when using FSR. Mipmap bias does nothing when FSR is not being used. Negative values make textures sharper, while positive values make textures blurrier. This value is used to adjust the mipmap bias calculated internally which is based on the selected quality. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code]. This updates the rendering server's mipmap bias when called - To control this property on the root viewport, set the [member ProjectSettings.rendering/scaling_3d/fsr_mipmap_bias] project setting. - </member> <member name="fsr_sharpness" type="float" setter="set_fsr_sharpness" getter="get_fsr_sharpness" default="0.2"> Determines how sharp the upscaled image will be when using the FSR upscaling mode. Sharpness halves with every whole number. Values go from 0.0 (sharpest) to 2.0. Values above 2.0 won't make a visible difference. To control this property on the root viewport, set the [member ProjectSettings.rendering/scaling_3d/fsr_sharpness] project setting. @@ -270,6 +266,11 @@ </member> <member name="snap_2d_vertices_to_pixel" type="bool" setter="set_snap_2d_vertices_to_pixel" getter="is_snap_2d_vertices_to_pixel_enabled" default="false"> </member> + <member name="texture_mipmap_bias" type="float" setter="set_texture_mipmap_bias" getter="get_texture_mipmap_bias" default="0.0"> + Affects the final texture sharpness by reading from a lower or higher mipmap (also called "texture LOD bias"). Negative values make mipmapped textures sharper but grainier when viewed at a distance, while positive values make mipmapped textures blurrier (even when up close). To get sharper textures at a distance without introducing too much graininess, set this between [code]-0.75[/code] and [code]0.0[/code]. Enabling temporal antialiasing ([member ProjectSettings.rendering/anti_aliasing/quality/use_taa]) can help reduce the graininess visible when using negative mipmap bias. + [b]Note:[/b] When the 3D scaling mode is set to FSR 1.0, this value is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code]. + To control this property on the root viewport, set the [member ProjectSettings.rendering/textures/default_filters/texture_mipmap_bias] project setting. + </member> <member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" default="false"> If [code]true[/code], the viewport should render its background as transparent. </member> diff --git a/doc/classes/WorkerThreadPool.xml b/doc/classes/WorkerThreadPool.xml new file mode 100644 index 0000000000..4f614bdadb --- /dev/null +++ b/doc/classes/WorkerThreadPool.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="WorkerThreadPool" inherits="Object" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_group_task"> + <return type="int" /> + <argument index="0" name="action" type="Callable" /> + <argument index="1" name="elements" type="int" /> + <argument index="2" name="tasks_needed" type="int" default="-1" /> + <argument index="3" name="high_priority" type="bool" default="false" /> + <argument index="4" name="description" type="String" default="""" /> + <description> + </description> + </method> + <method name="add_task"> + <return type="int" /> + <argument index="0" name="action" type="Callable" /> + <argument index="1" name="high_priority" type="bool" default="false" /> + <argument index="2" name="description" type="String" default="""" /> + <description> + </description> + </method> + <method name="get_group_processed_element_count" qualifiers="const"> + <return type="int" /> + <argument index="0" name="group_id" type="int" /> + <description> + </description> + </method> + <method name="is_group_task_completed" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="group_id" type="int" /> + <description> + </description> + </method> + <method name="is_task_completed" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="task_id" type="int" /> + <description> + </description> + </method> + <method name="wait_for_group_task_completion"> + <return type="void" /> + <argument index="0" name="group_id" type="int" /> + <description> + </description> + </method> + <method name="wait_for_task_completion"> + <return type="void" /> + <argument index="0" name="task_id" type="int" /> + <description> + </description> + </method> + </methods> +</class> diff --git a/doc/classes/XRCamera3D.xml b/doc/classes/XRCamera3D.xml index e0fc016a7d..4d6baa327b 100644 --- a/doc/classes/XRCamera3D.xml +++ b/doc/classes/XRCamera3D.xml @@ -8,6 +8,6 @@ The position and orientation of this node is automatically updated by the XR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that, in contrast to the XR Controller, the render thread has access to the most up-to-date tracking data of the HMD and the location of the XRCamera3D can lag a few milliseconds behind what is used for rendering as a result. </description> <tutorials> - <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link> + <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link> </tutorials> </class> diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml index deea888b8f..ff4aec46e1 100644 --- a/doc/classes/XRController3D.xml +++ b/doc/classes/XRController3D.xml @@ -10,7 +10,7 @@ As many XR runtimes now use a configurable action map all inputs are named. </description> <tutorials> - <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link> + <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link> </tutorials> <methods> <method name="get_axis" qualifiers="const"> diff --git a/doc/classes/XRInterface.xml b/doc/classes/XRInterface.xml index 0f4159cbbf..26b7699af2 100644 --- a/doc/classes/XRInterface.xml +++ b/doc/classes/XRInterface.xml @@ -8,7 +8,7 @@ Interfaces should be written in such a way that simply enabling them will give us a working setup. You can query the available interfaces through [XRServer]. </description> <tutorials> - <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link> + <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link> </tutorials> <methods> <method name="get_camera_feed_id"> diff --git a/doc/classes/XROrigin3D.xml b/doc/classes/XROrigin3D.xml index b7811f4d53..7acee097e7 100644 --- a/doc/classes/XROrigin3D.xml +++ b/doc/classes/XROrigin3D.xml @@ -10,7 +10,7 @@ For example, if your character is driving a car, the XROrigin3D node should be a child node of this car. Or, if you're implementing a teleport system to move your character, you should change the position of this node. </description> <tutorials> - <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link> + <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link> </tutorials> <members> <member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" default="1.0"> diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml index d15558c9e8..c146b27fcb 100644 --- a/doc/classes/XRPositionalTracker.xml +++ b/doc/classes/XRPositionalTracker.xml @@ -9,7 +9,7 @@ The [XRController3D] and [XRAnchor3D] both consume objects of this type and should be used in your project. The positional trackers are just under-the-hood objects that make this all work. These are mostly exposed so that GDExtension-based interfaces can interact with them. </description> <tutorials> - <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link> + <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link> </tutorials> <methods> <method name="get_input" qualifiers="const"> diff --git a/doc/classes/XRServer.xml b/doc/classes/XRServer.xml index a322a3c5c9..d3cb958cbc 100644 --- a/doc/classes/XRServer.xml +++ b/doc/classes/XRServer.xml @@ -7,7 +7,7 @@ The AR/VR server is the heart of our Advanced and Virtual Reality solution and handles all the processing. </description> <tutorials> - <link title="VR documentation index">$DOCS_URL/tutorials/vr/index.html</link> + <link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link> </tutorials> <methods> <method name="add_interface"> diff --git a/doc/classes/float.xml b/doc/classes/float.xml index f36b1fddeb..a7c6533ef5 100644 --- a/doc/classes/float.xml +++ b/doc/classes/float.xml @@ -111,6 +111,18 @@ </description> </operator> <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator *"> <return type="float" /> <argument index="0" name="right" type="float" /> <description> diff --git a/doc/classes/int.xml b/doc/classes/int.xml index 2eceba40fa..6b492ca923 100644 --- a/doc/classes/int.xml +++ b/doc/classes/int.xml @@ -158,6 +158,18 @@ </description> </operator> <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator *"> <return type="float" /> <argument index="0" name="right" type="float" /> <description> diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py index 312dffc7ee..469bb4a310 100755 --- a/doc/tools/make_rst.py +++ b/doc/tools/make_rst.py @@ -10,6 +10,11 @@ import sys import xml.etree.ElementTree as ET from collections import OrderedDict +# Import hardcoded version information from version.py +root_directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../") +sys.path.append(root_directory) # Include the root directory +import version + # Uncomment to do type checks. I have it commented out so it works below Python 3.5 # from typing import List, Dict, TextIO, Tuple, Iterable, Optional, DefaultDict, Any, Union @@ -587,12 +592,26 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S else: f = open(os.path.join(output_dir, "class_" + class_name.lower() + ".rst"), "w", encoding="utf-8") - # Warn contributors not to edit this file directly + # Remove the "Edit on Github" button from the online docs page. f.write(":github_url: hide\n\n") - f.write(".. Generated automatically by doc/tools/make_rst.py in Godot's source tree.\n") - f.write(".. DO NOT EDIT THIS FILE, but the " + class_name + ".xml source instead.\n") - f.write(".. The source is found in doc/classes or modules/<name>/doc_classes.\n\n") + # Warn contributors not to edit this file directly. + # Also provide links to the source files for reference. + + git_branch = "master" + if hasattr(version, "docs") and version.docs != "latest": + git_branch = version.docs + + source_xml_path = os.path.relpath(class_def.filepath, root_directory).replace("\\", "/") + source_github_url = "https://github.com/godotengine/godot/tree/{}/{}".format(git_branch, source_xml_path) + generator_github_url = "https://github.com/godotengine/godot/tree/{}/doc/tools/make_rst.py".format(git_branch) + + f.write(".. DO NOT EDIT THIS FILE!!!\n") + f.write(".. Generated automatically from Godot engine sources.\n") + f.write(".. Generator: " + generator_github_url + ".\n") + f.write(".. XML source: " + source_github_url + ".\n\n") + + # Document reference id and header. f.write(".. _class_" + class_name + ":\n\n") f.write(make_heading(class_name, "=", False)) @@ -907,7 +926,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S f.write(make_footer()) -def escape_rst(text, until_pos=-1): # type: (str) -> str +def escape_rst(text, until_pos=-1): # type: (str, int) -> str # Escape \ character, otherwise it ends up as an escape character in rst pos = 0 while True: @@ -1301,7 +1320,7 @@ def rstize_text(text, state): # type: (str, State) -> str return text -def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterable[Tuple[str, ...]]) -> None +def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterable[Tuple[str, ...]], bool) -> None if len(data) == 0: return @@ -1382,7 +1401,7 @@ def make_method_signature( if ref_type != "": if ref_type == "operator": out += ":ref:`{0}<class_{1}_{2}_{3}_{4}>` ".format( - method_def.name, + method_def.name.replace("<", "\\<"), # So operator "<" gets correctly displayed. class_def.name, ref_type, sanitize_operator_name(method_def.name, state), diff --git a/doc/translations/ar.po b/doc/translations/ar.po index a4488f3339..43e62ecab2 100644 --- a/doc/translations/ar.po +++ b/doc/translations/ar.po @@ -19,12 +19,14 @@ # Hamza Kalash <mogo.gogo170@gmail.com>, 2022. # ywmaa <ywmaa.personal@gmail.com>, 2022. # TabbyDev <Mandomody25@gmail.com>, 2022. +# عبد الرØÙ…Ù† أبو سعدة ||Abd Alrahman abo saada <abdalrahmanabs2005@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-05-31 22:35+0000\n" -"Last-Translator: TabbyDev <Mandomody25@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" +"Last-Translator: عبد الرØÙ…Ù† أبو سعدة ||Abd Alrahman abo saada " +"<abdalrahmanabs2005@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/ar/>\n" "Language: ar\n" @@ -33,7 +35,7 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 4.13-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -1004,7 +1006,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7850,8 +7859,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11922,7 +11931,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20347,7 +20361,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23739,7 +23753,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25576,7 +25590,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32679,7 +32693,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32695,7 +32709,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32725,7 +32739,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36859,7 +36873,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37122,7 +37136,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37240,6 +37254,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -37794,7 +37854,7 @@ msgstr "" #: doc/classes/Node.xml msgid "Nodes and Scenes" -msgstr "" +msgstr "العقد Ùˆ المشاهد" #: doc/classes/Node.xml msgid "All Demos" @@ -39937,7 +39997,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39949,7 +40015,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57735,7 +57802,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60636,8 +60703,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64269,13 +64336,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64287,13 +64355,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71202,7 +71271,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71287,6 +71360,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ca.po b/doc/translations/ca.po index bd84c415cc..2fce9a4d08 100644 --- a/doc/translations/ca.po +++ b/doc/translations/ca.po @@ -960,7 +960,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7797,8 +7804,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11866,7 +11873,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20277,7 +20289,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23666,7 +23678,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25497,7 +25509,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32593,7 +32605,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32609,7 +32621,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32639,7 +32651,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36739,7 +36751,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37000,7 +37012,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37114,6 +37126,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39811,7 +39869,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39823,7 +39887,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57577,7 +57642,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60468,8 +60533,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64092,13 +64157,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64110,13 +64176,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71002,7 +71069,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71087,6 +71158,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot index 90ebdbf9f3..b8187d24d5 100644 --- a/doc/translations/classes.pot +++ b/doc/translations/classes.pot @@ -840,7 +840,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7677,8 +7684,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11746,7 +11753,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20157,7 +20169,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23543,7 +23555,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25374,7 +25386,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32470,7 +32482,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32486,7 +32498,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32516,7 +32528,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36616,7 +36628,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36877,7 +36889,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36991,6 +37003,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39688,7 +39746,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39700,7 +39764,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57454,7 +57519,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60345,8 +60410,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63969,13 +64034,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63987,13 +64053,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -65801,11 +65868,11 @@ msgstr "" #: doc/classes/VehicleBody.xml msgid "" "Accelerates the vehicle by applying an engine force. The vehicle is only " -"sped up if the wheels that have [member VehicleWheel.use_as_traction] set " -"to [code]true[/code] and are in contact with a surface. The [member " -"RigidBody.mass] of the vehicle has an effect on the acceleration of the " -"vehicle. For a vehicle with a mass set to 1000, try a value in the 25 - 50 " -"range for acceleration.\n" +"sped up if the wheels that have [member VehicleWheel.use_as_traction] set to " +"[code]true[/code] and are in contact with a surface. The [member RigidBody." +"mass] of the vehicle has an effect on the acceleration of the vehicle. For a " +"vehicle with a mass set to 1000, try a value in the 25 - 50 range for " +"acceleration.\n" "[b]Note:[/b] The simulation does not take the effect of gears into account, " "you will need to add logic for this if you wish to simulate gears.\n" "A negative value will result in the vehicle reversing." @@ -65885,8 +65952,8 @@ msgstr "" #: doc/classes/VehicleWheel.xml msgid "" -"Accelerates the wheel by applying an engine force. The wheel is only sped " -"up if it is in contact with a surface. The [member RigidBody.mass] of the " +"Accelerates the wheel by applying an engine force. The wheel is only sped up " +"if it is in contact with a surface. The [member RigidBody.mass] of the " "vehicle has an effect on the acceleration of the vehicle. For a vehicle with " "a mass set to 1000, try a value in the 25 - 50 range for acceleration.\n" "[b]Note:[/b] The simulation does not take the effect of gears into account, " @@ -70879,7 +70946,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70964,6 +71035,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/cs.po b/doc/translations/cs.po index 48a79d9ec3..878b7e9aae 100644 --- a/doc/translations/cs.po +++ b/doc/translations/cs.po @@ -1230,8 +1230,15 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "Jako [method print], ale tiskne pouze pokud je použita v debug módu." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8187,8 +8194,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12266,7 +12273,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20725,7 +20737,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24123,7 +24135,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25960,7 +25972,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33074,7 +33086,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33090,7 +33102,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33121,7 +33133,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37264,7 +37276,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37527,7 +37539,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37645,6 +37657,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40345,7 +40403,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40357,7 +40421,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58166,7 +58231,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61082,8 +61147,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64740,13 +64805,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64758,13 +64824,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71688,9 +71755,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Vrátà [code] true [/code], pokud je vektor normalizován, jinak false." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -71774,6 +71844,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/de.po b/doc/translations/de.po index ba4e24c02b..0cf8d9ae17 100644 --- a/doc/translations/de.po +++ b/doc/translations/de.po @@ -35,7 +35,7 @@ # spoadr <spoadr@gmx.ch>, 2021. # Tim <tim14speckenwirth@gmail.com>, 2021. # user <online141@gmx.de>, 2021. -# Jummit <jummit@web.de>, 2021. +# Jummit <jummit@web.de>, 2021, 2022. # Bastian <bastian.ike@gmail.com>, 2021. # KuhnChris <kuhnchris@kuhnchris.eu>, 2021. # Rémi Verschelde <remi@godotengine.org>, 2021. @@ -52,7 +52,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-06-22 23:17+0000\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" "Last-Translator: Hans Peter <figefi6308@runqx.com>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/de/>\n" @@ -61,7 +61,7 @@ msgstr "" "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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -534,7 +534,6 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Compares two values by checking their actual contents, recursing into any " "[Array] or [Dictionary] up to its deepest level.\n" @@ -566,9 +565,9 @@ msgstr "" "- Für [code]Array[/code]s, [code]==[/code] werden die Arrays elementweise " "mit [code]==[/code] verglichen. Der Elemente-Vergleich ist also wieder " "einfach, nicht tief.\n" -"Zusammengefasst, immer wenn ein [code]Dictionary[/code] potentiell " -"involviert ist, und du einen wahren Inhaltsvergleich brauchst, musst du " -"[code]deep_equal[/code] verwenden." +"Zusammengefasst, immer wenn möglicherweise ein [code]Dictionary[/code] " +"involviert ist und du einen echten Inhaltsvergleich brauchst, verwende " +"[code]deep_equal[/code]." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -969,7 +968,6 @@ msgstr "" "[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml -#, fuzzy msgid "" "Linearly interpolates between two values by the factor defined in " "[code]weight[/code]. To perform interpolation, [code]weight[/code] should be " @@ -989,17 +987,24 @@ msgid "" "To perform eased interpolation with [method lerp], combine it with [method " "ease] or [method smoothstep]." msgstr "" -"Interpoliert einen normalisierten Wert linear zwischen zwei Grenzwerten. " -"Dies entspricht der Umkehrfunktion von [method inverse_lerp].\n" -"Wenn die [code]from[/code] und [code]to[/code] Argumente vom Typ [int] oder " -"[float] sind, dann ist der Rückgabewert ein [float].\n" -"Sind beide Argumente vom gleichen Typ ([Vector2], [Vector3] oder [Color]), " -"dann ist der Rückgabewert auch von diesem Typ ([code]lerp[/code] ruft dann " -"die Methode [code]lerp[/code] dieses Vektortyps auf).\n" +"Interpoliert linear zwischen zwei Werten mit dem in [code]weight[/code] " +"definierten Faktor. Um eine Interpolation durchzuführen, sollte " +"[code]Gewicht[/code] zwischen [code]0.0[/code] und [code]1.0[/code] " +"(einschließlich) liegen. Werte außerhalb dieses Bereichs sind jedoch " +"zulässig und können verwendet werden, um [i]Extrapolation[/i] " +"durchzuführen.\n" +"Wenn die Argumente [code]von[/code] und [code]bis[/code] vom Typ [int] oder " +"[float] sind, ist der Rückgabewert ein [float].\n" +"Wenn beide vom gleichen Vektortyp sind ([Vector2], [Vector3] oder [Color]), " +"ist der Rückgabewert vom gleichen Typ ([code]lerp[/code] ruft dann die " +"Methode [code]linear_interpolate[/code] des Vektortyps auf).\n" "[codeblock]\n" -"lerp(0, 4, 0.75) # Returns 3.0\n" -"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Returns Vector2(2, 3.5)\n" -"[/codeblock]" +"lerp(0, 4, 0.75) # Gibt 3.0 zurück\n" +"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Liefert Vector2(2, 3.5)\n" +"[/codeblock]\n" +"Siehe auch [method inverse_lerp], die die Umkehrung dieser Operation " +"durchführt. Um eine Interpolation mit [method lerp] durchzuführen, " +"kombiniere sie mit [method ease] oder [method smoothstep]." #: modules/gdscript/doc_classes/@GDScript.xml #, fuzzy @@ -1398,9 +1403,22 @@ msgstr "" "Trace aus." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Funktioniert wie [method print], gibt jedoch nur im Debug Modues Text aus." +"Gibt einen Stacktrace zum Quelltextort aus, funktioniert nur wenn das " +"\"Ausführen mit Debugger\" aktiviert ist.\n" +"Die Ausgabe in der Konsole würde ungefähr so aussehen:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -1660,6 +1678,45 @@ msgid "" "3\n" "[/codeblock]" msgstr "" +"Gibt ein Array mit dem angegebenen Bereich zurück. Die [Methode range] kann " +"auf drei Arten aufgerufen werden:\n" +"[code]range(n: int)[/code]: Beginnt bei 0, erhöht sich in Schritten von 1 " +"und endet [i]vor[/i] [code]n[/code]. Das Argument [code]n[/code] ist " +"[b]exklusiv[/b].\n" +"[code]range(b: int, n: int)[/code]: Beginnt bei [code]b[/code], erhöht sich " +"in Schritten von 1 und endet [i]vor[/i] [code]n[/code]. Die Argumente " +"[code]b[/code] und [code]n[/code] sind [b]inklusive[/b] bzw. [b]exklusive[/" +"b].\n" +"[code]bereich(b: int, n: int, s: int)[/code]: Beginnt bei [code]b[/code], " +"erhöht/verringert sich um Schritte von [code]s[/code] und endet [i]vor[/i] " +"[code]n[/code]. Die Argumente [code]b[/code] und [code]n[/code] sind " +"[b]inklusive[/b] bzw. [b]exklusive[/b]. Das Argument [code]s[/code] [b]kann[/" +"b] negativ sein, aber nicht [code]0[/code]. Wenn [code]s[/code] [code]0[/" +"code] ist, wird eine Fehlermeldung ausgegeben.\n" +"Der [Methodenbereich] wandelt alle Argumente vor der Verarbeitung in [int] " +"um.\n" +"[b]Hinweis:[/b] Gibt ein leeres Array zurück, wenn kein Wert die " +"Werteinschränkung erfüllt (z. B. [code]range(2, 5, -1)[/code] oder " +"[code]range(5, 5, 1)[/code]).\n" +"Beispiele:\n" +"[codeblock]\n" +"print(bereich(4)) # Gibt [0, 1, 2, 3] aus\n" +"print(bereich(2, 5)) # Gibt [2, 3, 4] aus\n" +"print(range(0, 6, 2)) # Gibt [0, 2, 4] aus\n" +"print(range(4, 1, -1)) # Gibt [4, 3, 2] aus\n" +"[/codeblock]\n" +"Um rückwärts über ein [Array] zu iterieren, benutze:\n" +"[codeblock]\n" +"var array = [3, 6, 9]\n" +"for i in range(array.size(), 0, -1):\n" +" print(array[i - 1])\n" +"[/codeblock]\n" +"Ausgabe:\n" +"[codeblock]\n" +"9\n" +"6\n" +"3\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -2194,6 +2251,50 @@ msgid "" "[code]GDScriptFunctionState[/code]. Notice [code]yield(get_tree(), " "\"idle_frame\")[/code] from the above example." msgstr "" +"Stoppt die Ausführung der Funktion und gibt den aktuellen angehaltenen " +"Zustand an die aufrufende Funktion zurück.\n" +"Rufe vom Aufrufer [Methode GDScriptFunctionState.resume] von dem Zustand " +"auf, um die Ausführung wieder aufzunehmen. Dadurch wird der Zustand " +"ungültig. Innerhalb der wiederaufgenommenen Funktion gibt [code]yield()[/" +"code] das zurück, was an den Funktionsaufruf [code]resume()[/code] übergeben " +"wurde.\n" +"Wenn ein Objekt und ein Signal übergeben werden, wird die Ausführung " +"fortgesetzt, wenn das Objekt das angegebene Signal aussendet. In diesem Fall " +"gibt [code]yield()[/code] das an [code]emit_signal()[/code] übergebene " +"Argument zurück, wenn das Signal nur ein Argument benötigt, oder ein Array " +"mit allen an [code]emit_signal()[/code] übergebenen Argumenten, wenn das " +"Signal mehrere Argumente benötigt.\n" +"[code]yield[/code] kann auch verwendet werden um auf das Ende einer Funktion " +"zu warten:\n" +"[codeblock]\n" +"func _ready():\n" +" yield(countdown(), \"completed\") # Warten auf die Beendigung der " +"Funktion countdown()\n" +" print('Fertig')\n" +"\n" +"func countdown():\n" +" yield(get_tree(), \"idle_frame\") # gibt ein GDScriptFunctionState " +"Objekt an _ready() zurück\n" +" print(3)\n" +" yield(get_tree().create_timer(1.0), \"timeout\")\n" +" print(2)\n" +" yield(get_tree().create_timer(1.0), \"timeout\")\n" +" print(1)\n" +" yield(get_tree().create_timer(1.0), \"timeout\")\n" +"\n" +"# gibt aus:\n" +"# 3\n" +"# 2\n" +"# 1\n" +"# bereit\n" +"[/codeblock]\n" +"Beim Yielding einer Funktion wird das Signal [code]completed[/code] " +"automatisch ausgegeben, wenn die Funktion zurückkehrt. Es kann daher als " +"[code]signal[/code] Parameter der [code]yield[/code] Methode verwendet " +"werden, um fortzufahren.\n" +"Um eine Funktion zu beenden, sollte die resultierende Funktion auch einen " +"[code]GDScriptFunctionState[/code] zurückgeben. Beachte " +"[code]yield(get_tree(), \"idle_frame\")[/code] aus dem obigen Beispiel." #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -3946,6 +4047,8 @@ msgid "" "MIDI aftertouch message. This message is most often sent by pressing down on " "the key after it \"bottoms out\"." msgstr "" +"MIDI-Aftertouch-Meldung. Diese Meldung wird meistens durch Drücken der Taste " +"nachdem sie den Tiefpunkt erreicht hat gesendet." #: doc/classes/@GlobalScope.xml msgid "" @@ -3961,6 +4064,8 @@ msgid "" "MIDI program change message. This message sent when the program patch number " "changes." msgstr "" +"MIDI-Programmwechselmeldung. Diese Meldung wird gesendet, wenn sich die " +"Programm-Patch-Nummer ändert." #: doc/classes/@GlobalScope.xml msgid "" @@ -3968,12 +4073,18 @@ msgid "" "down on the key after it \"bottoms out\". This message is different from " "polyphonic after-touch as it indicates the highest pressure across all keys." msgstr "" +"MIDI-Kanal-Druckmeldung. Diese Meldung wird meistens durch Drücken der Taste " +"nachdem sie den Tiefpunkt erreicht hat gesendet.Diese Meldung unterscheidet " +"sich von der polyphonen Aftertouch-Meldung, da sie den höchsten Druck über " +"alle Tasten hinweg anzeigt." #: doc/classes/@GlobalScope.xml msgid "" "MIDI pitch bend message. This message is sent to indicate a change in the " "pitch bender (wheel or lever, typically)." msgstr "" +"MIDI-Pitch-Bend-Meldung. Diese Meldung wird gesendet, um eine Änderung des " +"Pitch-Benders (typischerweise Rad oder Hebel) anzuzeigen." #: doc/classes/@GlobalScope.xml msgid "" @@ -9731,8 +9842,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -13833,7 +13944,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -22443,7 +22559,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -25861,7 +25977,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -27703,7 +27819,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -31788,7 +31904,7 @@ msgstr "" #: doc/classes/Input.xml msgid "A singleton that deals with inputs." -msgstr "" +msgstr "Ein Singleton, der sich mit Inputs befasst." #: doc/classes/Input.xml msgid "" @@ -31797,6 +31913,11 @@ msgid "" "set in the [b]Input Map[/b] tab in the [b]Project > Project Settings[/b], or " "with the [InputMap] class." msgstr "" +"Ein Singleton, das sich mit Inputs befasst. Dazu gehören Tastendrucke, " +"Maustasten und -bewegungen, Joypads und Eingabeaktionen. Aktionen und ihre " +"Ereignisse können auf der Registerkarte [b]Eingabe-Zuordnung[/b] unter " +"[b]Projekt > Projekteinstellungen[/b] oder mit der Klasse [InputMap] " +"festgelegt werden." #: doc/classes/Input.xml msgid "Inputs tutorial index" @@ -32028,6 +32149,20 @@ msgid "" "[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " "examples[/url] in the documentation for more information." msgstr "" +"Gibt [code]true[/code] aus, wenn Sie das Aktionsereignis drücken. Beachten " +"Sie, dass, wenn einer Aktion mehrere Tasten zugewiesen sind und mehr als " +"eine von ihnen gedrückt wird, das Loslassen einer Taste die Aktion auslöst, " +"selbst wenn eine andere Taste, die dieser Aktion zugewiesen ist, noch " +"gedrückt ist.\n" +"Wenn [code]exact[/code] [code] false[/code] ist, werden zusätzliche " +"Eingabemodifikatoren für die Ereignisse [InputEventKey] und " +"[InputEventMouseButton] sowie die Richtung für die Ereignisse " +"[InputEventJoypadMotion] ignoriert.\n" +"[b]Hinweis:[/b] Aufgrund von Tastatur-Ghosting kann [method " +"is_action_pressed] [code]false[/code] zurückgeben, auch wenn eine der Tasten " +"der Aktion gedrückt ist. Siehe [url=$DOCS_URL/tutorials/inputs/" +"input_examples.html#keyboard-events]Eingabebeispiele[/url] in der " +"Dokumentation für weitere Informationen." #: doc/classes/Input.xml #, fuzzy @@ -34911,7 +35046,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -34927,7 +35062,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -34963,7 +35098,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -39140,7 +39275,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -39407,7 +39542,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -39528,6 +39663,53 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "Gibt das AnimationNode mit dem gegebenen Namen zurück." + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -42231,7 +42413,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -42243,7 +42431,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -60237,7 +60426,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -63197,8 +63386,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -66895,13 +67084,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -66913,13 +67103,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -74065,9 +74256,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Wenn [code]true[/code], wird die Textur zentriert." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -74151,6 +74345,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/el.po b/doc/translations/el.po index c7236b41df..87eee32604 100644 --- a/doc/translations/el.po +++ b/doc/translations/el.po @@ -855,7 +855,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7694,8 +7701,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11766,7 +11773,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20192,7 +20204,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23584,7 +23596,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25421,7 +25433,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32524,7 +32536,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32540,7 +32552,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32570,7 +32582,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36698,7 +36710,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36961,7 +36973,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37079,6 +37091,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39776,7 +39834,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39788,7 +39852,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57561,7 +57626,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60462,8 +60527,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64095,13 +64160,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64113,13 +64179,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71028,7 +71095,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71113,6 +71184,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/es.po b/doc/translations/es.po index 50425a97d9..f9d008c41a 100644 --- a/doc/translations/es.po +++ b/doc/translations/es.po @@ -1380,9 +1380,22 @@ msgstr "" "mientras muestra un trazo de cuando un error o advertencia se muestra." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Como [method print], pero imprime sólo cuando se usa en modo de depuración." +"Imprime una registro de la pila en la ubicación del código, sólo funciona " +"cuando se ejecuta con el depurador activado.\n" +"La salida en la consola se verÃa algo asÃ:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -10108,8 +10121,8 @@ msgstr "" #, fuzzy msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -15375,10 +15388,13 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" -"Si [code]true[/code], el ancestro [Viewport] está actualmente usando esta " -"cámara." #: doc/classes/Camera.xml msgid "" @@ -26618,10 +26634,11 @@ msgstr "" "save_to_file]." #: doc/classes/EditorFeatureProfile.xml +#, fuzzy msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" "Guarda el perfil de caracterÃsticas del editor en un archivo en formato " "JSON. Luego puede ser importado usando el botón [b]Import[/b] del " @@ -31150,9 +31167,10 @@ msgid "The default exposure used for tonemapping." msgstr "La exposición predeterminada que se utiliza para el mapeo de tonos." #: doc/classes/Environment.xml +#, fuzzy msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" "El modo de mapeo de tonos a utilizar. El \"tonemapping\" es el proceso que " @@ -33579,9 +33597,10 @@ msgstr "" "puntos finales." #: doc/classes/Geometry.xml +#, fuzzy msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -43052,7 +43071,7 @@ msgstr "La altura del cilindro." msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -43078,7 +43097,7 @@ msgstr "El tamaño del ancho de un pÃxel en el sprite para escalarlo en 3D." msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -43125,7 +43144,7 @@ msgstr "Si se ajusta, las luces del entorno afectan al sprite." #: doc/classes/Label3D.xml #, fuzzy msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" "Si se fija, la textura puede ser vista desde atrás también, si no, es " @@ -48253,7 +48272,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -48576,7 +48595,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -48702,6 +48721,54 @@ msgstr "" msgid "Control activation of this server." msgstr "Traducción local de este nodo." +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "Devuelve el estado actual de la conexión. Ver [enum ConnectionStatus]." + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "Establece la piel que se utilizará en esta instancia." + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -52624,8 +52691,14 @@ msgid "See [enum ShadowDetail]." msgstr "Ver [enum ShadowMode]." #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." -msgstr "Ver [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." +msgstr "" #: doc/classes/OmniLight.xml msgid "" @@ -52636,9 +52709,11 @@ msgstr "" "que [constant SHADOW_CUBE], pero de menor calidad." #: doc/classes/OmniLight.xml +#, fuzzy msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" "Las sombras se representan en un mapa de cubos. Más lento que [constant " "SHADOW_DUAL_PARABOLOID], pero de mayor calidad." @@ -75508,7 +75583,7 @@ msgstr "El tamaño del ancho de un pÃxel en el sprite para escalarlo en 3D." msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -79211,8 +79286,8 @@ msgstr "Establece el texto para una lÃnea especÃfica." #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -83834,15 +83909,18 @@ msgstr "" "elementos pueden establecerse utilizando [method set_item_metadata]." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" "Devuelve el siguiente TreeItem del árbol o un objeto nulo si no hay ninguno." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -83858,15 +83936,18 @@ msgid "Returns the parent TreeItem or a null object if there is none." msgstr "Devuelve el TreeItem padre o un objeto nulo si no hay ninguno." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" "Devuelve el TreeItem anterior del árbol o un objeto nulo si no hay ninguno." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -93040,9 +93121,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "Establece la matriz de transformación global del Viewport." #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Si [code]true[/code], el canvas del viewport no se renderiza." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -93150,6 +93234,15 @@ msgstr "" "ViewportUpdateMode] para las opciones." #: doc/classes/VisualServer.xml +msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml #, fuzzy msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " diff --git a/doc/translations/fa.po b/doc/translations/fa.po index 5f170b2b28..7416d80072 100644 --- a/doc/translations/fa.po +++ b/doc/translations/fa.po @@ -1269,8 +1269,15 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "شبیه متد چاپ، اما چاپ کردن تنها در ØØ§Ù„ت اشکال زدایی Ø§Ø³ØªÙØ§Ø¯Ù‡ میشود." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8118,8 +8125,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12187,7 +12194,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20598,7 +20610,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23987,7 +23999,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25818,7 +25830,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32914,7 +32926,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32930,7 +32942,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32960,7 +32972,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37066,7 +37078,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37327,7 +37339,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37441,6 +37453,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40138,7 +40196,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40150,7 +40214,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57920,7 +57985,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60811,8 +60876,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64435,13 +64500,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64453,13 +64519,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71345,7 +71412,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71430,6 +71501,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/fi.po b/doc/translations/fi.po index 0ab098fd33..b1d940aa14 100644 --- a/doc/translations/fi.po +++ b/doc/translations/fi.po @@ -922,7 +922,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7767,8 +7774,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11840,7 +11847,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20268,7 +20280,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23660,7 +23672,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25497,7 +25509,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32607,7 +32619,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32623,7 +32635,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32653,7 +32665,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36783,7 +36795,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37046,7 +37058,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37164,6 +37176,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39861,7 +39919,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39873,7 +39937,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57648,7 +57713,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60550,8 +60615,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64185,13 +64250,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64203,13 +64269,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71123,7 +71190,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71208,6 +71279,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/fil.po b/doc/translations/fil.po index 2dabe612e9..42ab5537f4 100644 --- a/doc/translations/fil.po +++ b/doc/translations/fil.po @@ -856,7 +856,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7693,8 +7700,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11762,7 +11769,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20173,7 +20185,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23562,7 +23574,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25393,7 +25405,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32489,7 +32501,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32505,7 +32517,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32535,7 +32547,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36635,7 +36647,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36896,7 +36908,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37010,6 +37022,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39707,7 +39765,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39719,7 +39783,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57473,7 +57538,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60364,8 +60429,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63988,13 +64053,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64006,13 +64072,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70898,7 +70965,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70983,6 +71054,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/fr.po b/doc/translations/fr.po index 9d5c5f4a01..2866dc9b70 100644 --- a/doc/translations/fr.po +++ b/doc/translations/fr.po @@ -61,7 +61,7 @@ msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-18 08:12+0000\n" +"PO-Revision-Date: 2022-07-27 05:24+0000\n" "Last-Translator: Maxime Leroy <lisacintosh@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/fr/>\n" @@ -1423,9 +1423,22 @@ msgstr "" "ou un avertissement est affiché." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Comme [method print], mais ne s'affiche que lorsqu'utilisé en mode débogage." +"Affiche la trace d'appels à l'emplacement du code, ne fonctionne que lorsque " +"le débogueur est activé.\n" +"La sortie dans la console ressemblerait à ceci :\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -10371,10 +10384,11 @@ msgstr "" "identifiant inférieur est éteint." #: doc/classes/ARVRController.xml +#, fuzzy msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -15718,9 +15732,13 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" -"Si [code]true[/code], l’ancêtre [Viewport] utilise actuellement cette caméra." #: doc/classes/Camera.xml msgid "" @@ -27361,10 +27379,11 @@ msgstr "" "[method save_to_file]." #: doc/classes/EditorFeatureProfile.xml +#, fuzzy msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" "Enregistre le profil de fonctionnalité de l'éditeur dans un fichier au " "format JSON. Il peut ensuite être importé en utilisant le bouton [b]Import[/" @@ -31942,7 +31961,7 @@ msgstr "L’exposition par défaut utilisée pour tonifier." #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -34020,9 +34039,10 @@ msgstr "" "fin." #: doc/classes/Geometry.xml +#, fuzzy msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -42492,6 +42512,8 @@ msgid "" "Controls the text's horizontal alignment. Supports left, center, right. Set " "it to one of the [enum Align] constants." msgstr "" +"Control l'alignement horizontal du texte. Supporte à gauche, au centre, ou à " +"droite. Réglez-le à l'une des constantes de [enum Align]." #: doc/classes/Label3D.xml #, fuzzy @@ -42509,6 +42531,8 @@ msgid "" "If [code]true[/code], depth testing is disabled and the object will be drawn " "in render order." msgstr "" +"Si [code]true[/code], les tests de profondeur sont désactivés et l'objet " +"sera dessiné suivant son ordre de rendu et non suivant sa distance." #: doc/classes/Label3D.xml #, fuzzy @@ -42521,16 +42545,26 @@ msgid "The tint of [Font]'s outline." msgstr "La hauteur du cylindre." #: doc/classes/Label3D.xml +#, fuzzy msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " "This is because opaque objects are not sorted, while transparent objects are " "sorted from back to front (subject to priority)." msgstr "" +"Définit la priorité de rendu pour la bordure du texte. Des objets plus " +"prioritaires seront affichés par-dessus des objets moins inférieurs.\n" +"[b]Note: [/b] Cela ne s'applique que si [member alpha_cut] est défini à " +"[constant ALPHA_CUT_DISABLED] (c'est la valeur par défaut).\n" +"[b]Note :[/b] Cela ne s'applique qu'au tri des objets transparents. Cela " +"n'affectera pas la façon dont les objets transparents sont triés par rapport " +"aux objets opaques. C'est parce que les objets opaques ne sont pas triés, " +"alors que les objets transparents sont triés de l'arrière à l'avant (et " +"suivant leur priorité)." #: doc/classes/Label3D.xml #, fuzzy @@ -42538,16 +42572,26 @@ msgid "The size of one pixel's width on the label to scale it in 3D." msgstr "La taille d'un des pixels de la sprite pour définir sa taille en 3D." #: doc/classes/Label3D.xml +#, fuzzy msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " "This is because opaque objects are not sorted, while transparent objects are " "sorted from back to front (subject to priority)." msgstr "" +"Définit la priorité de rendu pour le texte. Des objets plus prioritaires " +"seront affichés par-dessus des objets moins inférieurs.\n" +"[b]Note: [/b] Cela ne s'applique que si [member alpha_cut] est défini à " +"[constant ALPHA_CUT_DISABLED] (c'est la valeur par défaut).\n" +"[b]Note :[/b] Cela ne s'applique qu'au tri des objets transparents. Cela " +"n'affectera pas la façon dont les objets transparents sont triés par rapport " +"aux objets opaques. C'est parce que les objets opaques ne sont pas triés, " +"alors que les objets transparents sont triés de l'arrière à l'avant (et " +"suivant leur priorité)." #: doc/classes/Label3D.xml #, fuzzy @@ -42561,10 +42605,14 @@ msgid "" "Controls the text's vertical alignment. Supports top, center, bottom. Set it " "to one of the [enum VAlign] constants." msgstr "" +"Control l'alignement vertical du texte. Supports en haut, au centre, et en " +"bas. Réglez-le à l'une des constantes de [enum VAlign]." #: doc/classes/Label3D.xml msgid "Text width (in pixels), used for autowrap and fill alignment." msgstr "" +"La largeur de texte (en pixels), utilisée pour les retours à la ligne et " +"l'alignement de remplissage." #: doc/classes/Label3D.xml #, fuzzy @@ -42572,10 +42620,13 @@ msgid "If set, lights in the environment affect the label." msgstr "Si [code]true[/code], ce [HTTPClient] a une réponse disponible." #: doc/classes/Label3D.xml +#, fuzzy msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" +"Si défini, le texte sera aussi visible de derrière. Sinon, le texture n'est " +"invisible que de face." #: doc/classes/Label3D.xml doc/classes/SpatialMaterial.xml #: doc/classes/SpriteBase3D.xml @@ -42583,11 +42634,16 @@ msgid "" "Disables the depth test, so this object is drawn on top of all others. " "However, objects drawn after it in the draw order may cover it." msgstr "" +"Désactive le test de profondeur, de sorte que cet objet sera dessiné devant " +"tous les autres. Cependant, les objets dessinés après lui dans l'ordre " +"d'affichage peuvent être devant." #: doc/classes/Label3D.xml msgid "" "Label is scaled by depth so that it always appears the same size on screen." msgstr "" +"L'étiquette est mise à l'échelle suivant la distance pour qu'elle apparaisse " +"toujours à la même taille à l'écran." #: doc/classes/Label3D.xml doc/classes/SpriteBase3D.xml msgid "Represents the size of the [enum DrawFlags] enum." @@ -42599,6 +42655,9 @@ msgid "" "areas, but transparency sorting issues may be visible when multiple " "transparent materials are overlapping." msgstr "" +"Ce mode réalise un mélange l'opacité standard. Il peut afficher des zones " +"translucides, mais des problèmes de tri selon la transparence peuvent être " +"visibles lorsque plusieurs matériaux transparents se chevauchent." #: doc/classes/Label3D.xml msgid "" @@ -42610,6 +42669,15 @@ msgid "" "scripts), this mode might have transparency sorting issues between the main " "text and the outline." msgstr "" +"Ce mode ne permet que les pixels transparents ou alors entièrement opaques. " +"Ce mode est également connu sous le nom de [i]alpha testing[/i] ou " +"[i]transparence 1 bit[/i].\n" +"[b]Note :[/b] Ce mode peut avoir des problèmes avec des polices avec " +"anticrénelage et des contours, essayez d'ajuster [member " +"alpha_scisor_threshold] ou en utilisant la police avec SDF.\n" +"[b]Note :[/b] Lors de l'utilisation de texte avec des caractères superposés " +"(par exemple des cursives), ce mode pourrait avoir des problèmes de tri de " +"la transparence entre le texte principal et le contour." #: doc/classes/Label3D.xml msgid "" @@ -42621,6 +42689,13 @@ msgid "" "scripts), this mode might have transparency sorting issues between the main " "text and the outline." msgstr "" +"Ce mode dessine des pixels entièrement opaques lors de la pré-passe de " +"profondeur. Ceci est plus lent que [constant ALPHA_CUT_DISABLED] ou " +"[constant ALPHA_CUT_DISCARD], mais ça permet d'afficher des zones " +"translucides et des bords lisses tout en utilisant le tri approprié.\n" +"[b]Note :[/b] Lors de l'utilisation de texte avec des caractères superposés " +"(par exemple des cursives), ce mode pourrait avoir des problèmes de tri de " +"la transparence entre le texte principal et le contour." #: doc/classes/LargeTexture.xml msgid "" @@ -42637,6 +42712,10 @@ msgid "" "You can dynamically add pieces ([Texture]s) to this [LargeTexture] using " "different offsets." msgstr "" +"[i]Obsolète (elle sera retiré dans Godot 4.0).[/i] Une [Texture] capable de " +"stocker de nombreuses textures plus petites avec des décalages.\n" +"Vous pouvez ajouter dynamiquement des [Texture] à ce [LargeTexture] en " +"utilisant différents décalages." #: doc/classes/LargeTexture.xml msgid "" @@ -42694,6 +42773,11 @@ msgid "" "from it. Light contains the common variables and parameters used for " "lighting." msgstr "" +"Light est la classe de base [i]abstraite[/i] pour les lumières. Puisque ça " +"ne peut être instancié, ça ne devrait pas être utilisé directement. D'autres " +"types de nÅ“uds de lumière héritent de cette classe, qui contient les " +"variables communes aux sous-classes, et les paramètres utilisés pour " +"l'éclairage." #: doc/classes/Light.xml doc/classes/SpotLight.xml msgid "3D lights and shadows" @@ -42712,6 +42796,8 @@ msgid "" "If [code]true[/code], the light only appears in the editor and will not be " "visible at runtime." msgstr "" +"Si [code]true[/code], la lumière n'apparaît que dans l'éditeur et ne sera " +"pas visible au lancement du jeu." #: doc/classes/Light.xml msgid "The light's bake mode. See [enum BakeMode]." @@ -42722,6 +42808,9 @@ msgid "" "The light's color. An [i]overbright[/i] color can be used to achieve a " "result equivalent to increasing the light's [member light_energy]." msgstr "" +"La couleur de la lumière. Une couleur [i]sur-brillante[/i] peut être " +"utilisée pour un résultant équivalent à augmenter l'énergie [member " +"light_energy] de la lumière." #: doc/classes/Light.xml msgid "The light will affect objects in the selected layers." @@ -42733,18 +42822,26 @@ msgid "" "[OmniLight] and [SpotLight], changing this value will only change the light " "color's intensity, not the light's radius." msgstr "" +"Le multiplicateur de force de la lumière (ça n'a aucune unité physique). " +"Pour [OmniLight] et [SpotLight], changer cette valeur ne changera que " +"l'intensité de la constante de couleur de la lumière, et non le rayon de la " +"lumière." #: doc/classes/Light.xml msgid "" "Secondary multiplier used with indirect light (light bounces). This works on " "both [BakedLightmap] and [GIProbe]." msgstr "" +"Le multiplicateur secondaire utilisé pour la lumière indirecte (les rebonds " +"de lumière). Cela fonctionne avec [BakedLightmap] et aussi [GIProbe]." #: doc/classes/Light.xml msgid "" "If [code]true[/code], the light's effect is reversed, darkening areas and " "casting bright shadows." msgstr "" +"Si [code]true[/code], l'effet de la lumière est inversé, assombrissant les " +"zones et lançant des ombres lumineuses." #: doc/classes/Light.xml msgid "" @@ -42761,6 +42858,11 @@ msgid "" "emission, this can be used to avoid unrealistic reflections when placing " "lights above an emissive surface." msgstr "" +"L'intensité du reflet spéculaire dans les objets touchés par la lumière. " +"Avec [code]0[/code], la lumière devient une lumière purement diffuse. Si ça " +"n'est pas une émission pré-calculée, cela peut être utilisé pour éviter des " +"reflets irréalistes lorsqu'on place des lumières au-dessus d'une surface " +"émise." #: doc/classes/Light.xml msgid "" @@ -42768,6 +42870,10 @@ msgid "" "shadowing (\"shadow acne\"), while too large a value causes shadows to " "separate from casters (\"peter-panning\"). Adjust as needed." msgstr "" +"Utilisé pour ajuster l'apparence de l'ombre. Une valeur trop petite résulte " +"au auto-ombrage (« shadow acne »), et quqand trop grande, ça provoque des " +"ombres séparées de l'objet qui crée l'ombre (« peter-panning »). Réglez " +"selon les besoins." #: doc/classes/Light.xml msgid "The color of shadows cast by this light." @@ -42781,6 +42887,11 @@ msgid "" "[b]Note:[/b] Contact shadows can look broken, so leaving this property to " "[code]0.0[/code] is recommended." msgstr "" +"Tente de réduire l'écart [member shadow_bias] en rendant les ombres de " +"contact en fonction de l'espace-écran. Cela a un impact sur les " +"performances, surtout avec des valeurs élevées.\n" +"[b]Note :[/b] Les ombres de contact peuvent sembler brisées, donc laisser " +"cette propriété à [code]0.0[/code] est plutôt recommandé." #: doc/classes/Light.xml msgid "If [code]true[/code], the light will cast shadows." @@ -42793,6 +42904,11 @@ msgid "" "cast a shadow on both sides of the mesh, set the mesh to use double-sided " "shadows with [constant GeometryInstance.SHADOW_CASTING_SETTING_DOUBLE_SIDED]." msgstr "" +"Si [code]true[/code], inverse la face arrière du maillage. Cela peut être " +"utile lorsque vous avez un maillage plat qui a une lumière derrière elle. Si " +"vous avez besoin de lancer une ombre sur les deux côtés du maillage, " +"définissez le maillage pour utiliser les deux faces avec [constant " +"GeometryInstance.SHADOW_CASTING_SETTING_DOUBLE_SIDED]" #: doc/classes/Light.xml msgid "Constant for accessing [member light_energy]." @@ -42892,10 +43008,13 @@ msgid "" "Light is ignored when baking.\n" "[b]Note:[/b] Hiding a light does [i]not[/i] affect baking." msgstr "" +"La lumière est ignorée lors du pré-calcul.\n" +"[b]Note :[/b] L'enregistrement d'une lumière ne [i]n'affecte pas[/i] le pré-" +"calcul." #: doc/classes/Light.xml msgid "Only indirect lighting will be baked (default)." -msgstr "" +msgstr "Seul l'éclairage indirect sera pré-calculé (choix par défaut)." #: doc/classes/Light.xml msgid "" @@ -42903,6 +43022,9 @@ msgid "" "[b]Note:[/b] You should hide the light if you don't want it to appear twice " "(dynamic and baked)." msgstr "" +"La lumière directe et indirecte sera pré-calculée.\n" +"[b]Note :[/b] Vous devriez cacher la lumière si vous ne voulez pas qu'elle " +"apparaisse deux fois (une fois dynamique et une autre pour le pré-calcul)." #: doc/classes/Light2D.xml msgid "Casts light in a 2D environment." @@ -42915,6 +43037,11 @@ msgid "" "parameters (range and shadows-related).\n" "[b]Note:[/b] Light2D can also be used as a mask." msgstr "" +"Montre la lumière dans un environnement 2D. La lumière est définie par une " +"texture (généralement grise), une couleur, une valeur énergétique, un mode " +"(voir les constantes), et divers autres paramètres (relatifs à la portée et " +"aux ombres).\n" +"[b]Note :[/b] Light2D peut aussi être utilisée comme masque." #: doc/classes/Light2D.xml msgid "The Light2D's [Color]." @@ -42939,20 +43066,23 @@ msgstr "" #: doc/classes/Light2D.xml msgid "The Light2D's mode. See [enum Mode] constants for values." msgstr "" +"Le mode de la Light2D. Voir les constantes [enum Mode] pour les valeurs." #: doc/classes/Light2D.xml msgid "The offset of the Light2D's [code]texture[/code]." -msgstr "" +msgstr "Le décalage de la [code]texture[/code] de la Light2D." #: doc/classes/Light2D.xml msgid "The height of the Light2D. Used with 2D normal mapping." -msgstr "" +msgstr "La hauteur du Light2D. Utilisé avec une mapping de normale 2D." #: doc/classes/Light2D.xml msgid "" "The layer mask. Only objects with a matching mask will be affected by the " "Light2D." msgstr "" +"Le masque de calque. Seuls les objets avec un masque correspondant seront " +"sous l'influence de ce Light2D." #: doc/classes/Light2D.xml msgid "Maximum layer value of objects that are affected by the Light2D." @@ -43003,13 +43133,16 @@ msgstr "Valeur de lissage pour les ombres." #: doc/classes/Light2D.xml msgid "Smooth shadow gradient length." -msgstr "" +msgstr "Longeur de lissage du dégradé d'ombre." #: doc/classes/Light2D.xml msgid "" "The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders " "with a matching light mask will cast shadows." msgstr "" +"Le masque d'ombre. Utilisé avec [LightOccluder2D] pour lancer des ombres. " +"Seuls les occulteurs avec un masque de lumière correspondant lanceront des " +"ombres." #: doc/classes/Light2D.xml msgid "[Texture] used for the Light2D's appearance." @@ -43024,18 +43157,24 @@ msgid "" "Adds the value of pixels corresponding to the Light2D to the values of " "pixels under it. This is the common behavior of a light." msgstr "" +"Ajoute la valeur des pixels correspondant à la Light2D aux valeurs des " +"pixels sous elle. C'est le comportement classique des lumières." #: doc/classes/Light2D.xml msgid "" "Subtracts the value of pixels corresponding to the Light2D to the values of " "pixels under it, resulting in inversed light effect." msgstr "" +"Soustrait la valeur des pixels correspondant à la Light2D aux valeurs des " +"pixels sous elle, ce qui entraîne un effet de lumière inversé." #: doc/classes/Light2D.xml msgid "" "Mix the value of pixels corresponding to the Light2D to the values of pixels " "under it by linear interpolation." msgstr "" +"Mélange la valeur des pixels correspondant à la Light2D aux valeurs des " +"pixels sous elle, via une interpolation linéaire." #: doc/classes/Light2D.xml msgid "" @@ -43043,40 +43182,54 @@ msgid "" "parts of the screen underneath depending on the value of each pixel of the " "light (mask) texture." msgstr "" +"La texture de lumière de la Light2D est utilisée comme masque, cache ou " +"révèle des parties de l'écran sous la valeur de chaque pixel de la texture " +"de la lumière (masque)." #: doc/classes/Light2D.xml msgid "No filter applies to the shadow map. See [member shadow_filter]." msgstr "" +"Aucun filtre ne s'applique à la carte d'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (3 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (3 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (5 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (5 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (7 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (7 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (9 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (9 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/Light2D.xml msgid "" "Percentage closer filtering (13 samples) applies to the shadow map. See " "[member shadow_filter]." msgstr "" +"Le pourcentage de filtrage proche (13 échantillons) s'applique à la carte de " +"l'ombre. Voir [member Shadow_filter]." #: doc/classes/LightOccluder2D.xml msgid "Occludes light cast by a Light2D, casting shadows." @@ -43094,10 +43247,12 @@ msgid "" "The LightOccluder2D's light mask. The LightOccluder2D will cast shadows only " "from Light2D(s) that have the same light mask(s)." msgstr "" +"Le masque de lumière du LightOccluder2D. Le LightOccluder2D ne lancera que " +"des ombres que sur les Light2D qui ont le même masque de lumière." #: doc/classes/LightOccluder2D.xml msgid "The [OccluderPolygon2D] used to compute the shadow." -msgstr "" +msgstr "Le [OccluderPolygon2D] utilisé pour calculer l'ombre." #: doc/classes/Line2D.xml msgid "A 2D line." @@ -43113,6 +43268,14 @@ msgid "" "[member ProjectSettings.rendering/limits/buffers/" "canvas_polygon_index_buffer_size_kb]." msgstr "" +"Une ligne à travers plusieurs points dans l'espace 2D. Supporte une largeur " +"et une couleur différentes sur la longueur, la texture et plusieurs types " +"d'embout et de jointure.\n" +"[b]Note :[/b] Par défaut, Godot ne peut dessiner que 4 096 points de " +"polygone à la fois. Pour augmenter cette limite, ouvrez les paramètres du " +"projet et augmentez [member ProjectSettings.rendering/limits/buffers/" +"canvas_polygon_buffer_size_kb] et [member ProjectSettings.rendering/limits/" +"buffers/canvas_polygon_index_buffer_size_kb]" #: doc/classes/Line2D.xml msgid "" @@ -43125,10 +43288,18 @@ msgid "" "get_point_count][/code]), the point will be appended at the end of the point " "list." msgstr "" +"Ajoute un point au [code]position[/code]. Ajoute le point à la fin de la " +"ligne.\n" +"Si [code]at_position[/code] est donné, le point est inséré avant l'indice " +"[code]at_position[/code], en déplaçant ce point (et chaque point après) " +"après le point inséré. Si [code]at_position[/code] n'est pas donné, ou est " +"une valeur invalide ([code]at_position < 0[/code] ou [code]at_position >= " +"[method get_point_count][/code]), le point sera ajouté à la fin de la liste " +"des points." #: doc/classes/Line2D.xml msgid "Removes all points from the line." -msgstr "" +msgstr "Retire tous les points de la ligne." #: doc/classes/Line2D.xml msgid "Returns the Line2D's amount of points." @@ -43422,6 +43593,15 @@ msgid "" "select(2, 5) # Will select \"lco\".\n" "[/codeblock]" msgstr "" +"Sélectionne les caractères à l'intérieur du [LineEdit] entre [code]from[/" +"code] et [code]to[/code]. Par défaut, [code]from[/code] est au début et " +"[code]to[/code] à la fin.\n" +"[codeblock]\n" +"text = \"Bienvenue\"\n" +"select() # Will select \"Bienvenue\".\n" +"select(5) # Will select \"venue\".\n" +"select(2, 7) # Will select \"enven\".\n" +"[/codeblock]" #: doc/classes/LineEdit.xml msgid "Selects the whole [String]." @@ -43444,6 +43624,8 @@ msgid "" "The cursor's position inside the [LineEdit]. When set, the text may scroll " "to accommodate it." msgstr "" +"La position du curseur dans le [LineEdit]. Lorsqu'il est défini, le texte " +"peut défiler pour l'afficher." #: doc/classes/LineEdit.xml msgid "" @@ -44361,6 +44543,9 @@ msgid "" "text color of the button. Disabled, hovered, and pressed states take " "precedence over this color." msgstr "" +"Le texte [Color] utilisé quand le [MenuButton] a le focus. Il suffit de " +"remplacer la couleur de texte normale du bouton. Les états désactivés, " +"survolés et pressés sont prioritaires sur cette couleur." #: doc/classes/MenuButton.xml msgid "Text [Color] used when the [MenuButton] is being hovered." @@ -44388,6 +44573,9 @@ msgid "" "current [StyleBox], so using [StyleBoxEmpty] will just disable the focus " "visual effect." msgstr "" +"La [StyleBox] utilisée quand le [MenuButton] a le focus. Elle est affichée " +"par dessus l'actuelle [StyleBox], donc utiliser [StyleBoxEmpty] va tout " +"simplement désactiver l'effet visuel du focus." #: doc/classes/MenuButton.xml msgid "[StyleBox] used when the [MenuButton] is being hovered." @@ -44414,6 +44602,12 @@ msgid "" "surfaces is preferred to a single surface, because objects created in 3D " "editing software commonly contain multiple materials." msgstr "" +"Mesh est un type de [Resource] qui contient la géométrie à base de tableaux " +"de sommets, divisé en [i]surfaces[/i]. Chaque surface contient un tableau " +"complètement séparé et un matériau utilisé pour le dessiner. Au niveau du " +"design, un maillage avec plusieurs surfaces est préféré à une seule surface, " +"car les objets créés dans le logiciel d'édition 3D contiennent généralement " +"plusieurs matériaux." #: doc/classes/Mesh.xml msgid "" @@ -44424,6 +44618,13 @@ msgid "" "If [code]simplify[/code] is [code]true[/code], the geometry can be further " "simplified to reduce the amount of vertices. Disabled by default." msgstr "" +"Calcule la [ConvexPolygonShape] du maillage.\n" +"Si [code]clean[/code] est [code]true[/code] (par défaut), les sommets " +"intérieurs et en double sont automatiquement supprimés. Vous pouvez le " +"définir à [code]false[/code] pour rendre le processus plus rapide si " +"nécessaire.\n" +"Si [code]simplify[/code] est [code]true[/code], la géométrie peut être plus " +"simplifiée pour réduire la quantité de sommets. Désactivé par défaut." #: doc/classes/Mesh.xml msgid "" @@ -44432,6 +44633,10 @@ msgid "" "[b]Note:[/b] This method typically returns the vertices in reverse order (e." "g. clockwise to counterclockwise)." msgstr "" +"Calcule un maillage de contour avec un décalage défini (marge) du maillage " +"d'origine.\n" +"[b]Note :[/b] Cette méthode renvoie généralement les sommets en ordre " +"inverse (par ex., du sens horaire au sens anti-horaire)." #: doc/classes/Mesh.xml msgid "Calculate a [ConcavePolygonShape] from the mesh." @@ -44448,6 +44653,10 @@ msgid "" "get_transformed_aabb].\n" "[b]Note:[/b] This is only implemented for [ArrayMesh] and [PrimitiveMesh]." msgstr "" +"Retourne le plus petit [AABB] englobant ce maillage dans l'espace local. Non " +"affecté par [code]custom_aabb[/code]. Voir aussi [method VisualInstance." +"get_transformed_aabb]\n" +"[b]Note :[/b] Ceci n'est implémenté que pour [ArrayMesh] et [PrimitiveMesh]." #: doc/classes/Mesh.xml msgid "" @@ -45303,12 +45512,16 @@ msgid "" "The height at which the camera is placed in relation to the ground (i.e. " "[ARVROrigin] node)." msgstr "" +"La hauteur à laquelle la caméra est placée par rapport au sol (c'est-à -dire " +"au nÅ“ud [ARVROrigin])." #: modules/mobile_vr/doc_classes/MobileVRInterface.xml msgid "" "The interocular distance, also known as the interpupillary distance. The " "distance between the pupils of the left and right eye." msgstr "" +"La distance interoculaire, aussi appelée la distance interpupillaire. La " +"distance entre la pupille de l'Å“il gauche et celle du l'Å“il droit." #: modules/mobile_vr/doc_classes/MobileVRInterface.xml msgid "" @@ -45321,7 +45534,7 @@ msgstr "" #: modules/mobile_vr/doc_classes/MobileVRInterface.xml msgid "The k2 lens factor, see k1." -msgstr "" +msgstr "Le facteur k2 de lentille, voir k1." #: modules/mobile_vr/doc_classes/MobileVRInterface.xml msgid "" @@ -46322,6 +46535,20 @@ msgid "" "(which should be avoided in general) the result might not be what is " "expected." msgstr "" +"Retourne [code]true[/code] si la coordonnée [code]point[/code] global " +"appartient actuellement à la [code]region[/code] de la navigation. Dans ce " +"contexte, l'une des faces du polygone de maillages de navigation de la " +"région a une position possible à la distance la plus proche de ce point par " +"rapport à tous les autres maillages de navigation provenant d'autres régions " +"de navigation également enregistrées sur la carte de navigation de la région " +"donnée.\n" +"Si plusieurs maillages de navigation ont des positions à égale distance, la " +"région de navigation dont les polygones sont traités en premier sont " +"retournés. Les polygones sont traités dans l'ordre d'ajout des régions dans " +"le serveur de navigation.\n" +"[b]Note :[/b] Si les maillages de navigation provenant de différentes " +"régions de navigation se chevauchent (qui doivent être évités en général), " +"le résultat peut être inattendu." #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml #, fuzzy @@ -46340,6 +46567,9 @@ msgid "" "Set the region's navigation layers. This allows selecting regions from a " "path request (when using [method Navigation2DServer.map_get_path])." msgstr "" +"Définit les calques de navigation de la région. Cela permet de sélectionner " +"les régions à partir d'une requête de chemin (en utilisant [method " +"Navigation2DServer.map_get_path])" #: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml #, fuzzy @@ -46378,6 +46608,21 @@ msgid "" "position from this function should be used as the next movement position for " "the agent's parent Node." msgstr "" +"Agent 3D utilisé dans la navigation pour atteindre un emplacement tout en " +"évitant les obstacles statiques et dynamiques. Les obstacles dynamiques sont " +"évités en utilisant la méthode RVO (Reciprocal Velocity Obstacles). L'agent " +"a besoin de données de navigation pour fonctionner correctement. Par défaut " +"ce nÅ“ud s'enregistrera à la carte de navigation par défaut du [World]. Si ce " +"nÅ“ud est un enfant d'un nÅ“ud [Navigation] il s'inscrira à la carte de " +"navigation du nÅ“ud de navigation ou la fonction [method set_navigation] peut " +"être utilisée pour définir le nÅ“ud de navigation directement. " +"[NavigationAgent] est sûr lors du traitement physique.\n" +"[b]Note :[/b] Après que [method set_target_location] est utilisé, il est " +"nécessaire d'utiliser la fonction [method get_next_location] une fois par " +"trame physique pour mettre à jour la logique de chemin interne du " +"NavigationAgent. La position vectorielle retournée de cette fonction devrait " +"être utilisée comme position de mouvement suivante pour le Node parent de " +"l'agent principal." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46385,6 +46630,9 @@ msgid "" "position. The user must set the target location with [method " "set_target_location] in order for this to be accurate." msgstr "" +"Retourne la distance jusqu'à l'emplacement cible, en utilisant la position " +"globale de l'agent observé. L'utilisateur doit définir l'emplacement de la " +"cible avec [method set_target_location] afin d'être précis." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46392,6 +46640,9 @@ msgid "" "if the navigation path is altered in any way. Because of this, it would be " "best to check this each frame." msgstr "" +"Retourne l'emplacement final accessible dans les coordonnées globales. Cela " +"peut changer si le chemin de navigation est modifié de quelque manière que " +"ce soit. Pour cette raison, il serait préférable de vérifier chaque trame." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46404,6 +46655,15 @@ msgid "" "for the agents movement as this function also updates the internal path " "logic." msgstr "" +"Retourne le chemin actuel de l'agent du début jusqu'à la fin, dans les " +"coordonnées globales. Le chemin ne met à jour que lorsque l'emplacement de " +"la cible est modifié ou que l'agent demande un re-calcul du chemin. Le " +"réseau de chemin n'est pas destiné à être utilisé dans le mouvement de " +"chemin direct car l'agent a sa propre logique de chemin interne qui serait " +"corrompu en changeant le réseau de chemin manuellement. Utilisez la [method " +"get_next_location] voulue une fois chaque trame de physique pour recevoir le " +"point de chemin suivant pour le mouvement des agents car cette fonction met " +"également à jour la logique du chemin interne." #: doc/classes/NavigationAgent.xml msgid "" @@ -46416,6 +46676,8 @@ msgid "" "Returns the [Navigation] node that the agent is using for its navigation " "system." msgstr "" +"Retourne le nÅ“ud [Navigation] que l'agent utilise pour son système de " +"navigation." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46427,6 +46689,14 @@ msgid "" "the navigation map for the NavigationAgent and also update the agent on the " "NavigationServer." msgstr "" +"Retourne le [RID] de la carte de navigation pour ce nÅ“ud NavigationAgent. " +"Cette fonction retourne toujours la carte définie sur le nÅ“ud " +"NavigationAgent et non la carte de l'agent abstrait sur le serveur " +"Navigation. Si la carte de l'agent est changée directement avec l'API de " +"NavigationServer, le nÅ“ud NavigationAgent ne sera pas au courant du " +"changement de carte. Utilisez [method set_navigation_map] pour changer la " +"carte de navigation pour le NavigationAgent et mettre à jour l'agent sur le " +"NavigationServer." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46436,6 +46706,12 @@ msgid "" "use of this function once every physics frame is required to update the " "internal path logic of the NavigationAgent." msgstr "" +"Retourne l'emplacement suivant dans les coordonnées globales qui peuvent " +"être déplacées, en s'assurant qu'il n'y a pas d'objets statiques dans le " +"chemin. Si l'agent n'a pas de chemin de navigation, il retourne la position " +"du parent de l'agent. L'utilisation de cette fonction une fois chaque trame " +"physique est nécessaire pour mettre à jour la logique de chemin interne de " +"la NavigationAgent." #: doc/classes/NavigationAgent.xml #, fuzzy @@ -46477,18 +46753,25 @@ msgid "" "Sets the [Navigation] node used by the agent. Useful when you don't want to " "make the agent a child of a [Navigation] node." msgstr "" +"Définit le nÅ“ud [Navigation] utilisé par l'agent. Utile lorsque vous ne " +"voulez pas faire de l'agent un enfant d'un nÅ“ud [Navigation]." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Sets the [RID] of the navigation map this NavigationAgent node should use " "and also updates the [code]agent[/code] on the NavigationServer." msgstr "" +"Définit le [RID] de la carte de navigation que ce nÅ“ud NavigationAgent " +"devrait utiliser et met à jour le [code]agent[/code] sur le serveur de " +"navigation." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Sets the user desired final location. This will clear the current navigation " "path." msgstr "" +"Définit l'emplacement final souhaité de l'utilisateur. Cela permettra " +"d'effacer le chemin de navigation actuel." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46496,6 +46779,9 @@ msgid "" "adjust the velocity to avoid collisions. Once the adjustment to the velocity " "is complete, it will emit the [signal velocity_computed] signal." msgstr "" +"Envoie la vitesse spécifiée à l'algorithme d'évitement de collision. Celui-" +"ci ajustera la vitesse pour éviter les collisions. Une fois le réglage de la " +"vitesse terminée, il émettra le signal [signal velocity_computed]." #: doc/classes/NavigationAgent.xml msgid "" @@ -46506,6 +46792,14 @@ msgid "" "that the developer baked with appropriate agent radius or height values are " "required to support different-sized agents." msgstr "" +"La hauteur du NavigationAgent est soustraite de la valeur de l'axe Y de " +"toute position de chemin vectoriel pour ce NavigationAgent. Le décalage de " +"hauteur du NavigationAgent ne change pas ou n'influence pas le résultat de " +"la requête du maillage de navigation ou du cheminement. Des cartes de " +"navigation supplémentaires qui utilisent des régions avec des maillages de " +"navigation que le développeur a pré-calculé avec un rayon d'agent approprié " +"ou des valeurs de hauteur sont nécessaires pour supporter des agents de " +"taille différente." #: doc/classes/NavigationAgent.xml msgid "" @@ -46516,12 +46810,21 @@ msgid "" "with many registered agents has a significant performance cost and should " "only be enabled on agents that currently require it." msgstr "" +"Si [code]true[/code] l'agent est enregistré pour un rappel d'évitement RVO " +"sur le [NavigationServer]. Lorsque [method set_velocity] est utilisé et que " +"le traitement est terminé, un Vector3 [code]safe_velocity[/code] est reçu " +"avec une connexion du signal [signal velocity_computed]. Le traitement de " +"l'évitement avec de nombreux agents enregistrés a un coût de performance " +"important et ne devrait être activé que pour les agents qui en ont " +"actuellement besoin." #: doc/classes/NavigationAgent.xml msgid "" "Ignores collisions on the Y axis. Must be [code]true[/code] to move on a " "horizontal plane." msgstr "" +"Ignore les collisions sur l'axe Y. Doit être [code]true[/code] pour se " +"déplacer sur un plan horizontal." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml #, fuzzy @@ -46539,6 +46842,10 @@ msgid "" "belongs to. On path requests the agent will ignore navmeshes without at " "least one matching layer." msgstr "" +"Un masque de bit déterminant toutes les calque de carte de navigation " +"auxquels ce [NavigationAgent] appartient. Lors de requête de chemin, l'agent " +"va ignorer les maillages de navigation qui n'ont pas au moins un calque " +"correspondant." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml #, fuzzy @@ -46555,6 +46862,14 @@ msgid "" "it will constantly overshoot or undershoot the distance to the next point on " "each physics frame update." msgstr "" +"Le seuil de distance avant qu'un point de chemin soit considéré comme " +"atteint. Cela permettra à un agent de ne pas avoir à atteindre un point de " +"chemin exactement sur le chemin, mais uniquement un zone autour. Si cette " +"valeur est élevée, la NavigationAgent sautera des points sur le chemin qui " +"peut conduire à quitter le maillage de navigation. Si cette valeur est trop " +"faible, le NavigationAgent sera coincé dans une boucle de chemin parce qu'il " +"va constamment mal estimer la distance jusqu'au point suivant à chaque mise " +"à jour de la trame physique." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46562,6 +46877,9 @@ msgid "" "final location. This can happen due to trying to avoid collisions. When the " "maximum distance is exceeded, it recalculates the ideal path." msgstr "" +"La distance maximale de l'agent est permise loin du chemin idéal jusqu'à " +"l'emplacement final. Cela peut arriver en essayant d'éviter les collisions. " +"Lorsque la distance maximale est dépassée, cela recalcule le chemin idéal." #: doc/classes/NavigationAgent.xml msgid "" @@ -46572,6 +46890,13 @@ msgid "" "bake [NavigationMesh] resources with a different [member NavigationMesh." "agent_radius] property and use different navigation maps for each actor size." msgstr "" +"Le rayon d'évitement de l'agent. Il s'agit du « corps » de l'agent " +"d'évitement et non le rayon de la manÅ“uvre d'évitement (qui est contrôlé par " +"[member neighbor_dist)].\n" +"N'affecte pas le cheminement normal. Pour changer les ressources " +"[NavigationMesh] de rayon de pré-calcul de cheminement d'un acteur avec la " +"propriété [member NavigationMesh.agent_radius] différente et utiliser " +"différentes cartes de navigation pour chaque acteur." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46582,6 +46907,12 @@ msgid "" "overshoot or undershoot the distance to the final target point on each " "physics frame update." msgstr "" +"Le seuil de distance avant qu'un point de chemin soit considéré comme " +"atteint. Cela permettra à un agent de ne pas avoir à atteindre un point de " +"chemin exactement sur le chemin, mais uniquement un zone autour. Si cette " +"valeur est trop faible, le NavigationAgent sera coincé dans une boucle de " +"chemin parce qu'il va constamment mal estimer la distance jusqu'au point " +"suivant à chaque mise à jour de la trame physique." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" @@ -46591,6 +46922,11 @@ msgid "" "other agents, but the less freedom in choosing its velocities. Must be " "positive." msgstr "" +"La quantité minimale de temps pour laquelle les vitesses de cet agent, " +"calculées avec l'algorithme d'évitement de collision, sont sûres pour les " +"autres agents. Plus le nombre est élevé, plus tôt l'agent répondra à " +"d'autres agents, mais moins il aura la liberté de choisir sa vitesse. Ça " +"doit être positif." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml #, fuzzy @@ -46602,18 +46938,24 @@ msgid "" "Notifies when the navigation path changes. This can be triggered by the " "navigation system or by the user changing the path." msgstr "" +"Notifie quand le chemin de navigation change. Cela peut être déclenché par " +"le système de navigation ou par l'utilisateur qui change le chemin." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Notifies when the player-defined target, set with [method " "set_target_location], is reached." msgstr "" +"Notifie quand la cible définie par le joueur, définie avec [method " +"set_target_location], est atteinte." #: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml msgid "" "Notifies when the collision avoidance velocity is calculated after a call to " "[method set_velocity]." msgstr "" +"Notifie quand la vitesse d'évitement de collision est calculée après un " +"appel à [method set_velocity]." #: doc/classes/NavigationAgent2D.xml msgid "2D agent used in navigation for collision avoidance." @@ -46635,6 +46977,21 @@ msgid "" "position from this function should be used as the next movement position for " "the agent's parent Node." msgstr "" +"L'agent 2D utilisé dans la navigation pour atteindre un emplacement tout en " +"évitant les obstacles statiques et dynamiques. Les obstacles dynamiques sont " +"évités en utilisant l'évitement de collision RVO (Reciprocal Velocity " +"Obstacles). L'agent a besoin de données de navigation pour fonctionner " +"correctement. Par défaut ce nÅ“ud s'enregistrera à la carte de navigation par " +"défaut du [World2D]. Si ce nÅ“ud est un enfant d'un nÅ“ud [Navigation2D] il " +"s'inscrira à la carte de navigation du nÅ“ud de navigation ou la fonction " +"[method set_navigation] peut être utilisé pour définir le nÅ“ud de navigation " +"directement. [NavigationAgent2D] est sûr lors des trames physiques.\n" +"[b]Note :[/b] Après que [method set_target_location] est utilisé, il est " +"nécessaire d'utiliser la fonction [method get_next_location] une fois chaque " +"trame physique pour mettre à jour la logique interne de chemin du " +"NavigationAgent. La position vectorielle retournée de cette fonction devrait " +"être utilisée comme position de mouvement suivante pour le Node parent de " +"l'agent principal." #: doc/classes/NavigationAgent2D.xml msgid "" @@ -46647,6 +47004,8 @@ msgid "" "Returns the [Navigation2D] node that the agent is using for its navigation " "system." msgstr "" +"Retourne le nÅ“ud [Navigation2D] que l'agent utilise pour son système de " +"navigation." #: doc/classes/NavigationAgent2D.xml #, fuzzy @@ -46658,6 +47017,8 @@ msgid "" "Sets the [Navigation2D] node used by the agent. Useful when you don't want " "to make the agent a child of a [Navigation2D] node." msgstr "" +"Définit le nÅ“ud [Navigation2D] utilisé par l'agent. Utile lorsque vous ne " +"voulez pas faire de l'agent un enfant d'un nÅ“ud [Navigation2D]." #: doc/classes/NavigationAgent2D.xml msgid "" @@ -46668,6 +47029,13 @@ msgid "" "with many registered agents has a significant performance cost and should " "only be enabled on agents that currently require it." msgstr "" +"Si [code]true[/code] l'agent est enregistré pour un rappel d'évitement RVO " +"sur le [Navigation2DServer]. Lorsque [method set_velocity] est utilisé et " +"que le traitement est terminé, un Vector2 [code]safe_velocity[/code] est " +"reçu avec une connexion au signal [signal velocity_computed]. Le traitement " +"de l'évitement avec de nombreux agents enregistrés a un coût de performance " +"important et ne devrait être activé que pour les agents qui en ont " +"actuellement besoin." #: doc/classes/NavigationAgent2D.xml msgid "" @@ -46675,6 +47043,10 @@ msgid "" "belongs to. On path requests the agent will ignore navmeshes without at " "least one matching layer." msgstr "" +"Un masque de bit déterminant toutes les calque de carte de navigation " +"auxquels ce [NavigationAgent2D] appartient. Lors de requête de chemin, " +"l'agent va ignorer les maillages de navigation qui n'ont pas au moins un " +"calque correspondant." #: doc/classes/NavigationAgent2D.xml msgid "" @@ -46683,6 +47055,10 @@ msgid "" "[member neighbor_dist]).\n" "Does not affect normal pathfinding." msgstr "" +"Le rayon d'évitement de l'agent. Il s'agit du « corps » de l'agent " +"d'évitement et non le rayon de la manÅ“uvre d'évitement (qui est contrôlé par " +"[member neighbor_dist)].\n" +"N'affecte pas le cheminement normal." #: doc/classes/NavigationMesh.xml msgid "A mesh to approximate the walkable areas and obstacles." @@ -46852,12 +47228,17 @@ msgid "" "Only used when [member geometry_parsed_geometry_type] is [constant " "PARSED_GEOMETRY_STATIC_COLLIDERS] or [constant PARSED_GEOMETRY_BOTH]." msgstr "" +"Les calques de physique pour scanner les collisions statiques.\n" +"Seulement utilisé quand [member geometry_parsed_geometry_type] est [constant " +"PARSED_GEOMETRY_STATIC_COLLIDERS] ou [constant] PARSED_GEOMETRY_BOTH]." #: doc/classes/NavigationMesh.xml msgid "" "Determines which type of nodes will be parsed as geometry. See [enum " "ParsedGeometryType] for possible values." msgstr "" +"Détermine quel type de nÅ“uds seront interprétés comme géométrie. Voir [enum " +"ParsedGeometryType] pour les valeurs possibles." #: doc/classes/NavigationMesh.xml msgid "" @@ -46872,12 +47253,18 @@ msgid "" "SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN] or [constant " "SOURCE_GEOMETRY_GROUPS_EXPLICIT]." msgstr "" +"Le nom du groupe pour scanner la géométrie.\n" +"Seulement utilisé lorsque [member geometry_source_geometry_mode] est " +"[constant SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN] ou [constant] " +"SOURCE_GEOMETRY_GROUPS_EXPLICIT]." #: doc/classes/NavigationMesh.xml msgid "" "The maximum number of vertices allowed for polygons generated during the " "contour to polygon conversion process." msgstr "" +"Le nombre maximal de sommets permis pour les polygones générés pendant le " +"contour du processus de conversion en polygones." #: doc/classes/NavigationMesh.xml msgid "" @@ -46886,6 +47273,10 @@ msgid "" "[b]Note:[/b] This value will be squared to calculate the number of cells. " "For example, a value of 20 will set the number of cells to 400." msgstr "" +"Toutes les régions ayant une taille inférieure à celle-ci seront fusionnées " +"avec des régions plus grandes si possible.\n" +"[b]Note :[/b] Cette valeur sera carrée pour calculer le nombre de cellules. " +"Par exemple, une valeur de 20 définira le nombre de cellules à 400." #: doc/classes/NavigationMesh.xml msgid "" @@ -46894,12 +47285,18 @@ msgid "" "cells allowed to form isolated island areas. For example, a value of 8 will " "set the number of cells to 64." msgstr "" +"La taille minimale d'une région pour qu'elle soit créée.\n" +"[b]Note :[/b] Cette valeur sera fixée pour calculer le nombre minimum de " +"cellules autorisées à former des zones insulaires isolées. Par exemple, une " +"valeur de 8 définira le nombre de cellules à 64." #: doc/classes/NavigationMesh.xml msgid "" "Partitioning algorithm for creating the navigation mesh polys. See [enum " "SamplePartitionType] for possible values." msgstr "" +"Algorithme de partitionnement pour la création des polygones de maillage de " +"navigation. Voir [enum SamplePartitionType] pour les valeurs possibles." #: doc/classes/NavigationMesh.xml msgid "" @@ -46911,12 +47308,16 @@ msgstr "" msgid "" "Monotone partitioning. Use this if you want fast navigation mesh generation." msgstr "" +"Partage monotone. Utilisez ceci si vous voulez une génération de maillages " +"de navigation rapide." #: doc/classes/NavigationMesh.xml msgid "" "Layer partitioning. Good choice to use for tiled navigation mesh with medium " "and small sized tiles." msgstr "" +"Le partitionnement du calque. Un bon choix à utiliser pour la maillage de " +"navigation en carreaux de taille moyenne et petite." #: doc/classes/NavigationMesh.xml msgid "Represents the size of the [enum SamplePartitionType] enum." @@ -46935,6 +47336,9 @@ msgid "" "Parses [StaticBody] colliders as geometry. The collider should be in any of " "the layers specified by [member geometry_collision_mask]." msgstr "" +"Interprète l'élément de collision [StaticBody] comme géométrie. Cet élément " +"doit être dans l'un des calques spécifiés par [member " +"geometry_collision_mask]." #: doc/classes/NavigationMesh.xml msgid "" @@ -46952,18 +47356,24 @@ msgstr "Représente la taille de l’enum [enum ParsedGeometryType]." msgid "" "Scans the child nodes of [NavigationMeshInstance] recursively for geometry." msgstr "" +"Scanne les nÅ“uds d'enfants de [NavigationMeshInstance] récursivement pour la " +"géométrie." #: doc/classes/NavigationMesh.xml msgid "" "Scans nodes in a group and their child nodes recursively for geometry. The " "group is specified by [member geometry_source_group_name]." msgstr "" +"Scanne les nÅ“uds dans un groupe et leurs nÅ“uds enfants récursivement pour la " +"géométrie. Le groupe est spécifié par [member geometry_source_group_name]." #: doc/classes/NavigationMesh.xml msgid "" "Uses nodes in a group for geometry. The group is specified by [member " "geometry_source_group_name]." msgstr "" +"Utilise des nÅ“uds dans un groupe de géométrie. Le groupe est spécifié par " +"[member geometry_source_group_name]." #: doc/classes/NavigationMesh.xml msgid "Represents the size of the [enum SourceGeometryMode] enum." @@ -46972,6 +47382,7 @@ msgstr "Représente la taille de l'énumération [enum SourceGeometryMode]." #: doc/classes/NavigationMeshGenerator.xml msgid "Helper class for creating and clearing navigation meshes." msgstr "" +"Classe d'aide pour la création et la suppression des maillages de navigation." #: doc/classes/NavigationMeshGenerator.xml msgid "" @@ -47014,6 +47425,52 @@ msgid "" "inside, the baking will generate navigation mesh areas that are inside the " "obstructing source geometry mesh." msgstr "" +"Cette classe est responsable de la création et du la suppression des " +"maillages de navigation 3D utilisés comme [NavigationMesh] ressources à " +"l'intérieur des [NavigationMeshInstance]. Le [NavigationMeshGenerator] est " +"très limité voire n'a aucune utilisation pour 2D car le processus de " +"navigation de pré-calcule de maillages s'attend à des types de nÅ“uds 3D et " +"la géométrie source en 3D.\n" +"L'ensemble du pré-calcule de maillages de navigation est préférable dans un " +"autre fil d'exécution puisque les étapes de voxelisation, de collision et " +"d'optimisation de maillages impliquées sont des opérations, sont très " +"couteuses en temps processeur.\n" +"Le pré-calcule de maillage de navigation se produit en plusieurs étapes et " +"le résultat dépend de la géométrie source 3D et des propriétés de la " +"ressource [NavigationMesh]. Dans la première étape, à partir d'un nÅ“ud " +"racine et selon les propriétés [NavigationMesh], tous les nÅ“uds de géométrie " +"de source 3D valides sont collectés à partir du [SceneTree]. Deuxièmement, " +"tous les nÅ“uds collectés sont interprétés pour obtenir les données de " +"géométrie 3D pertinentes et un maillage 3D combiné est construit. En raison " +"des différents types d'objets à interpréter, des [MeshInstance] normaux aux " +"[CSGShape] ou divers [CollisionObject], certaines opérations de collecte de " +"données de géométrie peuvent déclencher des synchronisations du " +"[VisualServer] et du [PhysicsServer]. La synchronisation du serveur peut " +"avoir un effet négatif sur le temps de pré-calcule car elle implique souvent " +"le verrouillage de [Mutex] dans le fil d'exécution. De nombreux objets à " +"interpréter et de nombreuses synchronisations des serveurs peuvent augmenter " +"considérablement le temps de pré-calcule. D'un autre côté, seulement " +"quelques objets, mais très grands et complexes, prendront du temps de " +"préparation des serveurs ce qui peuvent bloquer le rendu suivant. De règle " +"générale, la quantité totale d'objets à interpréter, leur taille et leur " +"complexité individuelles devraient être équilibrées pour éviter les " +"problèmes de fluidité ou des temps de pré-calcule très longs. Le maillage " +"combiné est ensuite transmis à l'Object Recast Navigation pour tester la " +"géométrie source pour le terrain à parcourir adapté aux propriétés des " +"agents [NavigationMesh] en créant un monde de voxel autour de la zone de " +"maillage.\n" +"Le maillage de navigation finalisé est ensuite retourné et enregistré à " +"l'intérieur du [NavigationMesh] pour être utilisé comme ressource à " +"l'intérieur des nÅ“uds [NavigationMeshInstance].\n" +"[b]Note :[/b] L'utilisation de maillages ne définissen pas seulement les " +"surfaces à parcourir mais peut aussi empêcher le pré-calcul de fonctionner. " +"La navigation n'a pas de concept de ce qu'est une géométrie \"à " +"l'intérieur\" quand on traite de la géométrie de source de maillage et c'est " +"intentionnel. Selon les paramètres de pré-calcule actuels, dès que le " +"maillage obstructif est assez grande pour s'adapter à une zone de maillage " +"de navigation à l'intérieur, le pré-calcule générera des zones de maillage " +"de navigation qui sont à l'intérieur du maillage de géométrie de source " +"obstructif." #: doc/classes/NavigationMeshGenerator.xml msgid "" @@ -47024,6 +47481,12 @@ msgid "" "NavigationMesh.geometry_source_geometry_mode] properties on the " "[NavigationMesh] resource." msgstr "" +"Pré-calcule les données de navigation du [code]nav_mesh[/code] donné en " +"interprétant les nÅ“uds enfants dans le [code]root_node[/code] spécifié ou un " +"groupe spécifique de nÅ“uds pour la géométrie de source potentielle. Le " +"comportement d'interprétation peut être contrôlé avec les propriétés [member " +"NavigationMesh.geometry_parsed_geometry_type] et [member NavigationMesh." +"geometry_source_geometry_mode] de la ressource [NavigationMesh]." #: doc/classes/NavigationMeshGenerator.xml #, fuzzy @@ -47037,6 +47500,7 @@ msgid "An instance of a [NavigationMesh]." msgstr "Une instance de [NavigationMesh]." #: doc/classes/NavigationMeshInstance.xml +#, fuzzy msgid "" "An instance of a [NavigationMesh]. It tells the [Navigation] node what can " "be navigated and what cannot, based on the [NavigationMesh] resource.\n" @@ -47050,11 +47514,29 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." msgstr "" +"Une instance de [NavigationMesh]. Il signale au nÅ“ud [Navigation] ce qui " +"peut être navigué et ce qui ne peut pas, basé sur la ressource " +"[NavigationMesh].\n" +"Par défaut ce nÅ“ud s'enregistrera à la carte de navigation du [World] par " +"défaut. Si ce nÅ“ud est un enfant d'un nÅ“ud [Navigation], il s'inscrira à la " +"carte de navigation du nÅ“ud de navigation.\n" +"Deux régions peuvent être reliées l'une à l'autre si elles partagent un même " +"bord. Vous pouvez définir la distance minimale entre deux sommets " +"nécessaires pour connecter deux bords en utilisant [method NavigationServer." +"map_set_edge_connection_margin]\n" +"[b]Note :[/b] Le chevauchement de deux régions n'est pas suffisant pour " +"relier deux régions. Ils doivent partager un même bord.\n" +"Le coût d'entrée dans cette région d'une autre région peut être contrôlé " +"avec la valeur [member enter_cost].\n" +"[b]Note : [/b] Cette valeur n'est pas ajoutée au coût du chemin lorsque la " +"position de départ est déjà dans cette région.\n" +"Le coût des distances de voyage dans cette région peut être contrôlé avec le " +"multiplicateur [member travel_cost]." #: doc/classes/NavigationMeshInstance.xml msgid "" @@ -47300,6 +47782,7 @@ msgid "A region of the 2D navigation map." msgstr "Prépare le maillage de navigation." #: doc/classes/NavigationPolygonInstance.xml +#, fuzzy msgid "" "A region of the navigation map. It tells the [Navigation2DServer] what can " "be navigated and what cannot, based on its [NavigationPolygon] resource.\n" @@ -47313,11 +47796,29 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." msgstr "" +"Une instance de [NavigationMesh]. Il signale au nÅ“ud [Navigation] ce qui " +"peut être navigué et ce qui ne peut pas, basé sur la ressource " +"[NavigationMesh].\n" +"Par défaut ce nÅ“ud s'enregistrera à la carte de navigation du [World] par " +"défaut. Si ce nÅ“ud est un enfant d'un nÅ“ud [Navigation], il s'inscrira à la " +"carte de navigation du nÅ“ud de navigation.\n" +"Deux régions peuvent être reliées l'une à l'autre si elles partagent un même " +"bord. Vous pouvez définir la distance minimale entre deux sommets " +"nécessaires pour connecter deux bords en utilisant [method NavigationServer." +"map_set_edge_connection_margin]\n" +"[b]Note :[/b] Le chevauchement de deux régions n'est pas suffisant pour " +"relier deux régions. Ils doivent partager un même bord.\n" +"Le coût d'entrée dans cette région d'une autre région peut être contrôlé " +"avec la valeur [member enter_cost].\n" +"[b]Note : [/b] Cette valeur n'est pas ajoutée au coût du chemin lorsque la " +"position de départ est déjà dans cette région.\n" +"Le coût des distances de voyage dans cette région peut être contrôlé avec le " +"multiplicateur [member travel_cost]." #: doc/classes/NavigationPolygonInstance.xml msgid "" @@ -47456,6 +47957,54 @@ msgstr "" msgid "Control activation of this server." msgstr "Contrôle l'activation de ce serveur." +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "Retourne l'état actuel de la connexion. Voir [enum ConnexionStatus]." + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "Définit la texture de lumière à utiliser pour cette instance." + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -47476,6 +48025,18 @@ msgid "" "the server port in UDP. You can use the [UPNP] class to try to forward the " "server port automatically when starting the server." msgstr "" +"Une implémentation de PacketPeer qui devrait être passée au [member " +"SceneTree.network_peer] après avoir été initialisé en tant que client ou " +"serveur. Les événements peuvent ensuite être gérés en se connectant aux " +"signaux de [SceneTree].\n" +"L'intêret de ENet est de fournir un calque de communication à travers le " +"réseau relativement léger, simple et robuste par dessus UDP (User Datagram " +"Protocol).\n" +"[b]Note :[/b] ENet utilise seulement UDP, et non TCP. Lors du branchement du " +"port serveur pour rendre votre serveur accessible sur internet, vous n'avez " +"besoin que d'envoyer le port serveur en UDP. Vous pouvez utiliser la classe " +"[UPNP] pour essayer d'envoyer automatiquement le port serveur dès le " +"démarrage du serveur." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47484,6 +48045,10 @@ msgid "" "disconnecting them. If this is a client it simply closes the connection to " "the server." msgstr "" +"Ferme la connexion. Ignoré si aucune connexion n'est actuellement établie. " +"Si c'est un serveur, il essaie de notifier tous les clients avant de les " +"déconnecter de force. Si c'est un client, il ferme simplement la connexion " +"au serveur." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47506,6 +48071,25 @@ msgid "" "code] is specified, the client will also listen to the given port; this is " "useful for some NAT traversal techniques." msgstr "" +"Créer un client qui se connecte au serveur à [code]address[/code] donnée via " +"le [code]port[/code]. L'adresse donnée doit être soit un nom de domaine " +"entièrement qualifié (ex.: [code]\"www.example.com\"[/code]) ou une adresse " +"IP en format IPv4 ou IPv6 (par exemple [code]\"192.168.1.1\"[/code)]. Le " +"[code]port[/code] est le port que le serveur écoute. Les paramètres " +"[code]in_bandwidth[/code] et [code]out_bandwidth[/code] peuvent être " +"utilisés pour limiter la bande passante entrante et sortante, en octets par " +"seconde. Le défaut de 0 signifie que la bande passante ne sera pas limitée. " +"Notez que ENet ignorera stratégiquement des paquets d'une connexion entre " +"pairs pour s'assurer que la bande passante par les pairs n'est pas dépassée. " +"Les paramètres de bande passante déterminent également la taille de la " +"fenêtre d'une connexion qui limite la quantité de paquets fiables qui " +"peuvent être envoyés à tout moment donné. Retourne [constant OK] si un " +"client a été créé, [constant ERR_ALREADY_IN_USE] si ce " +"NetworkedMultiplayerENet a déjà une connexion ouverte (dans quel cas vous " +"devez appeler [method close_connection] d'abord) ou [constant " +"ERR_CANT_CREATE] si le client ne peut pas être créé. Si [code]client_port[/" +"code] est spécifié, le client écoutera également le port donné ; ceci est " +"utile pour certaines techniques NAT transversale." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47524,12 +48108,29 @@ msgid "" "case you need to call [method close_connection] first) or [constant " "ERR_CANT_CREATE] if the server could not be created." msgstr "" +"Créer un serveur qui écoute les connexions via [code]port[/code]. Le port " +"doit être un port disponible et inutilisé entre 0 et 65535. Notez que les " +"ports inférieurs à 1024 sont réservés et peuvent nécessiter des " +"autorisations élevées en fonction de la plateforme. Pour modifier " +"l'interface que le serveur écoute, utilisez [method set_bind_ip]. L'IP par " +"défaut est le joker [code]\"*\"[/code], qui écoute toutes les interfaces " +"disponibles. [code]max_clients[/code] est le nombre maximum de clients " +"autorisés en même temps, tout nombre jusqu'à 4095 peut être utilisé, même si " +"le nombre possible de clients simultanés peut être beaucoup plus faible et " +"dépend de l'application. Pour plus de détails sur les paramètres de bande " +"passante, voir [method create_client]. Retourne [constant OK] si un serveur " +"a été créé, [constant ERR_ALREADY_IN_USE] si ce NetworkedMultiplayerENet a " +"déjà une connexion ouverte (dans quel cas vous devez appeler [method " +"close_connection] d'abord) ou [constant ERR_CANT_CREATE] si le serveur ne " +"peut pas être créé." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "Disconnect the given peer. If \"now\" is set to [code]true[/code], the " "connection will be closed immediately without flushing queued messages." msgstr "" +"Déconnecte le pair donné. Si \"maintenant\" est [code]true[/code], la " +"connexion sera fermée immédiatement sans envoyer les messages en attente." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47544,6 +48145,8 @@ msgid "" "Returns the channel of the next packet that will be retrieved via [method " "PacketPeer.get_packet]." msgstr "" +"Retourne le canal du prochain paquet qui sera récupéré via [method " +"PacketPeer.get_packet]" #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml #: modules/websocket/doc_classes/WebSocketServer.xml @@ -47562,6 +48165,10 @@ msgid "" "needs to be in IPv4 or IPv6 address format, for example: " "[code]\"192.168.1.1\"[/code]." msgstr "" +"L'adresse IP utilisée lors de la création d'un serveur. Ceci est défini le " +"joker [code]\"*\"[/code] par défaut, qui se connecte à toutes les interfaces " +"disponibles. L'adresse donnée doit être au format IPv4 ou IPv6, par " +"exemple : [code]\"192.168.1.1\"[/code]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47569,6 +48176,9 @@ msgid "" "code]. For servers, you must also setup the [CryptoKey] via [method " "set_dtls_key]." msgstr "" +"Configure le [X509Certificate] à utiliser lorsque [member use_dtls] est " +"[code]true[/code]. Pour les serveurs, vous devez également configurer le " +"[CryptoKey] via [method set_dtls_key]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47576,6 +48186,9 @@ msgid "" "code]. Remember to also call [method set_dtls_certificate] to setup your " "[X509Certificate]." msgstr "" +"Configure la [CryptoKey] à utiliser lorsque [member use_dtls] est " +"[code]true[/code]. N'oubliez pas d'appeler [method set_dtls_certificate] " +"pour configurer votre [X509Certificate]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47590,6 +48203,17 @@ msgid "" "other hand, defines a fixed timeout for which any packet must be " "acknowledged or the peer will be dropped." msgstr "" +"Définit les paramètres de limite de temps pour un pair. Les paramètres de " +"limite de temps contrôlent comment et quand un pair estimera que le traffic " +"n'est pas assez fiable. Les valeurs de limite de temps sont exprimées en " +"millisecondes.\n" +"La [code]timeout_limit[/code] est un facteur qui, multiplié par une valeur " +"basée sur le temps d'envoi moyen, déterminera la limite de temps pour un " +"paquet fiable. Lorsque cette limite est atteinte, la limite de temps sera " +"doublée, et le pair sera déconnecté si cette limite atteint " +"[code]timeout_min[/code]. Le paramètre [code]timeout_max[/code], d'autre " +"part, définit une limite de temps fixe pour lequel tout paquet doit estimé " +"comme fiable, ou alors le pair sera supprimé." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47598,6 +48222,11 @@ msgid "" "NetworkedMultiplayerPeer.TRANSFER_MODE_UNRELIABLE_ORDERED]). This is the " "only way to use ordering with the RPC system." msgstr "" +"Force le tri des paquets lors de l'utilisation de [constant " +"NetworkedMultiplayerPeer.TRANSFER_MODE_UNRELIABLE] (ce qui se comporte de la " +"même manière [constant NetworkedMultiplayerPeer." +"TRANSFER_MODE_UNRELIABLE_ORDERED]). C'est le seul moyen d'utiliser le tri " +"avec un système RPC." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47608,6 +48237,12 @@ msgid "" "status of a packet in one channel won't stall the delivery of other packets " "in another channel." msgstr "" +"Le nombre de canaux à utiliser par ENet. Les canaux sont utilisés pour " +"séparer différents types de données. En mode fiable ou ordonné, par exemple, " +"l'ordre d'envoi des paquets est assuré sur une base par canal. Ceci est fait " +"pour lutter contre la latence et réduit les restrictions d'ordre sur les " +"paquets. L'état d'envoi d'un paquet d'un canal a été décalé dans l'envoi " +"d'autres paquets dans un autre canal." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47624,6 +48259,21 @@ msgid "" "COMPRESS_NONE]. Nonetheless, mixing engine versions between clients and " "server is not recommended and not officially supported." msgstr "" +"La méthode de compression utilisée pour les paquets réseau. Ceux-ci ont " +"différents compromis de vitesse de compression par rapport à la bande " +"passante, vous pouvez avoir besoin quelle méthode fonctionne le mieux pour " +"votre cas d'utilisation si vous utilisez la compression pour tout.\n" +"[b]Note :[/b] La conception réseau de la plupart des jeux nécessite l'envoi " +"de nombreux petits paquets fréquemment (moins de 4 KB chacun). Dans le " +"doute, il est recommandé de garder l'algorithme de compression par défaut " +"car il fonctionne le mieux avec ces petits paquets.\n" +"[b]Note :[/b] [member compression_mode] doit être défini à la même valeur " +"sur le serveur et sur tous ses clients. Les clients ne se connecteront pas " +"si le [member compression_mode] d'un client diffère de celui du serveur. " +"Avant Godot 3.4, la valeur par défaut de [member compression_mode] était " +"[constant COMPRESS_NONE]. Néanmoins, il n'est pas recommandé, ni " +"officiellement supporté, d'utiliser différentes versions du moteur entre les " +"clients et le serveur." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47632,6 +48282,10 @@ msgid "" "When set to an empty string, the [code]address[/code] parameter passed to " "[method create_client] is used instead." msgstr "" +"Le nom d'hôte utilisé pour la vérification DTLS, à comparer à la valeur « CN " +"» du certificat fourni par le serveur.\n" +"Si la chaîne est vide, le paramètre [code]address[/code] passé à [method " +"create_client] est utilisé à la place." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml #, fuzzy @@ -47649,6 +48303,11 @@ msgid "" "is [code]false[/code], clients won't be automatically notified of other " "peers and won't be able to send them packets through the server." msgstr "" +"Activer ou désactiver la fonction serveur qui notifie les clients de la " +"connexion/déconnection des autres pairs enregistrés, et relaye les messages " +"entre eux. Lorsque cette option est [code]false[/code], les clients ont " +"obtenu la notification automatique d'autres pairs et ont obtenu la " +"possibilité de les envoyer par le serveur." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47660,6 +48319,14 @@ msgid "" "that channel for sending data. See [member channel_count] for more " "information about ENet channels." msgstr "" +"Définit le canal par défaut à utiliser pour transférer les données. Par " +"défaut, cette valeur est [code]-1[/code] ce qui signifie que ENet " +"n'utilisera que 2 canaux : un pour les paquets fiables, et un pour les " +"paquets non fiables. Le canal [code]0[/code] est réservé et ne peut pas être " +"utilisé. Définit cette propriété à n'importe quelle valeur entre [code]0[/" +"code] et [member channel_count] (exclus) forcera ENet à utiliser ce canal " +"pour envoyer les données. Voir [member channel_count] pour plus " +"d'informations sur les canaux ENet." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47673,6 +48340,16 @@ msgid "" "dtls_verify] option, and configure the certificate accordingly via [method " "set_dtls_certificate]." msgstr "" +"Quand activé, le client ou le serveur créé par ce pair utilisera " +"[PacketPeerDTLS] au lieu des sockets UDP bruts pour communiquer avec le pair " +"distant. Cela permettra de chiffrer la communication avec DTLS avec une " +"utilisation plus importante des ressources mais aussi peut-être de la taille " +"des paquets.\n" +"[b]Note :[/b] Lors de la création d'un serveur DTLS, assurez-vous de " +"configurer à la fois la clé et le certificat avec [method set_dtls_key] et " +"[method set_dtls_certificate]. Pour les clients DTLS, regardez l'option " +"[member dtls_verify] et configurez le certificat en conséquence avec [method " +"set_dtls_certificate]." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47680,12 +48357,17 @@ msgid "" "requiring the fewest CPU resources. This option may also be used to make " "network debugging using tools like Wireshark easier." msgstr "" +"Aucune compression. Cela utilise le plus de bande passante, mais moins de " +"ressource du CPU. Cette option peut également être utilisée pour faciliter " +"le débogage du réseau en utilisant des outils comme Wireshark." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "ENet's built-in range encoding. Works well on small packets, but is not the " "most efficient algorithm on packets larger than 4 KB." msgstr "" +"L'encodage intégré d'ENet. Fonctionne bien sur les petits paquets, mais " +"n'est pas l'algorithme le plus efficace pour les paquets de plus de 4 KB." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47693,6 +48375,9 @@ msgid "" "resources compared to [constant COMPRESS_ZLIB], at the expense of using more " "bandwidth." msgstr "" +"L'algorithme de compression [url=http://fastlz.org/]FastLZ[/url]. Cette " +"option utilise moins de ressources CPU par rapport à [constant " +"COMPRESS_ZLIB] mais utilise plus de bande passante." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" @@ -47702,6 +48387,11 @@ msgid "" "packets smaller than 4 KB. Therefore, it's recommended to use other " "compression algorithms in most cases." msgstr "" +"L'algorithme de compression [url=https://www.zlib.net/]Zlib[/url]. Cette " +"option utilise moins de bande passante par rapport à [constant " +"COMPRESS_FASTLZ] mais utilise plus le CPU. Notez que cet algorithme n'est " +"pas très efficace pour les paquets de moins de 4 KB. Il est donc souvent " +"recommandé d'utiliser d'autres algorithmes de compression." #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "[url=https://facebook.github.io/zstd/]Zstandard[/url] compression." @@ -47721,6 +48411,11 @@ msgid "" "detail and isn't meant to be used by non-Godot servers. It may change " "without notice." msgstr "" +"Gère la connexion aux pairs du réseau. Attribue des identifiants uniques à " +"chaque client connecté au serveur. Voir aussi [MultiplayerAPI].\n" +"[b]Note :[/b] Le protocole de l'API multijoueur de haut niveau dépend de son " +"implémentation et n'est pas destiné à être utilisé par des serveurs en " +"dehors de Godot. Ce protocole peut changer dans une future version." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "High-level multiplayer" @@ -47728,7 +48423,7 @@ msgstr "API multijoueur de haut niveau" #: doc/classes/NetworkedMultiplayerPeer.xml msgid "WebRTC Signaling Demo" -msgstr "" +msgstr "Démo des signaux WebRTC" #: doc/classes/NetworkedMultiplayerPeer.xml msgid "" @@ -47760,6 +48455,13 @@ msgid "" "peer ID to send to all peers except that one. By default, the target peer is " "[constant TARGET_PEER_BROADCAST]." msgstr "" +"Définit le pair auquel les paquets seront envoyés.\n" +"L'identifiant [code]id[/code] peut être : [constant TARGET_PEER_BROADCAST] " +"pour envoyer à tous les pairs connectés, [constant TARGET_PEER_SERVER] pour " +"envoyer au pair agissant en tant que serveur, un identifiant de pairs valide " +"pour envoyer à ce pair spécifique, ou un identifiant négatif pour envoyer à " +"tous les pairs sauf celui-ci. Par défaut, le pair cible est [constant " +"TARGET_PEER_BROADCAST]." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "" @@ -47774,6 +48476,8 @@ msgid "" "The manner in which to send packets to the [code]target_peer[/code]. See " "[enum TransferMode]." msgstr "" +"La manière d'envoyer des paquets au [code]target_peer[/code]. Voir [enum " +"TransferMode]." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "Emitted when a connection attempt fails." @@ -47802,6 +48506,11 @@ msgid "" "TRANSFER_MODE_UNRELIABLE_ORDERED]. Use for non-critical data, and always " "consider whether the order matters." msgstr "" +"Les paquets ne sont pas reconnus, aucune tentative de ré-envoi n'est faite " +"pour les paquets perdus. Les paquets peuvent arriver dans n'importe quelle " +"commande. Peut être plus rapide que [constant " +"TRANSFER_MODE_UNRELIABLE_ORDERED]. À utiliser pour des données non " +"critiques, et toujours à considérer si l'ordre compte." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "" @@ -47811,6 +48520,12 @@ msgid "" "would be outdated if received late due to resend attempt(s) anyway, for " "example movement and positional data." msgstr "" +"Les paquets ne sont pas reconnus, aucune tentative de ré-envoi n'est faite " +"pour les paquets perdus. Les paquets sont reçus dans l'ordre où ils ont été " +"envoyés. Peut être plus rapide que [constant TRANSFER_MODE_RELIABLE]. À " +"utiliser pour les données non critiques ou qui seraient périmées si elles " +"étaient reçues tardivement à cause du ré-envoi, par exemple pour les données " +"de mouvement et de positionnement." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "" @@ -47821,6 +48536,14 @@ msgid "" "order, for example an ability being triggered or a chat message. Consider " "carefully if the information really is critical, and use sparingly." msgstr "" +"Les paquets doivent être reçus et les tentatives de ré-envoi doivent être " +"faites jusqu'à ce que les paquets soient reconnus. Les paquets doivent être " +"reçus dans l'ordre où ils ont été envoyés. C'est le mode de transfert le " +"plus fiable, mais potentiellement le plus lent en cause de la surcharge. À " +"utiliser pour les données critiques qui doivent être transmises et arriver " +"en ordre, par exemple un élément activé ou un message de discussion. À " +"considérez soigneusement si l'information est vraiment critique, et à " +"utiliser avec parcimonie." #: doc/classes/NetworkedMultiplayerPeer.xml msgid "The ongoing connection disconnected." @@ -47862,30 +48585,40 @@ msgid "" "Returns the size of the margin identified by the given [enum Margin] " "constant." msgstr "" +"Retourne la taille de la marge identifiée par la constante [enum Margin] " +"donnée." #: doc/classes/NinePatchRect.xml msgid "" "Sets the size of the margin identified by the given [enum Margin] constant " "to [code]value[/code] in pixels." msgstr "" +"Définit la taille de la marge identifiée par la constante [enum Margin] " +"donnée à [code]value[/code] en pixels." #: doc/classes/NinePatchRect.xml msgid "" "The stretch mode to use for horizontal stretching/tiling. See [enum " "NinePatchRect.AxisStretchMode] for possible values." msgstr "" +"Le mode d'étirement à utiliser pour l'étirement horizontal. Voir [enum " +"NinePatchRect.AxisStretchMode] pour les valeurs possibles." #: doc/classes/NinePatchRect.xml msgid "" "The stretch mode to use for vertical stretching/tiling. See [enum " "NinePatchRect.AxisStretchMode] for possible values." msgstr "" +"Le mode d'étirement à utiliser pour l'étirement vertical. Voir [enum " +"NinePatchRect.AxisStretchMode] pour les valeurs possibles." #: doc/classes/NinePatchRect.xml msgid "" "If [code]true[/code], draw the panel's center. Else, only draw the 9-slice's " "borders." msgstr "" +"Si [code]true[/code], dessine le centre du panneau. Sinon, ne dessine que " +"les bordures des 9 parties." #: doc/classes/NinePatchRect.xml msgid "" @@ -47893,6 +48626,10 @@ msgid "" "bottom corners and side will have a height of 16 pixels. You can set all 4 " "margin values individually to create panels with non-uniform borders." msgstr "" +"La hauteur de la ligne du bas des 9 parties. Une marge de 16 signifie que " +"les angles du bas des 9 parties et les côtés auront une hauteur de 16 " +"pixels. Vous pouvez définir les 4 valeurs de marge individuellement pour " +"créer des panneaux avec des bordures non uniformes." #: doc/classes/NinePatchRect.xml msgid "" @@ -47900,6 +48637,10 @@ msgid "" "left corners and side will have a width of 16 pixels. You can set all 4 " "margin values individually to create panels with non-uniform borders." msgstr "" +"La largeur de la colonne gauche des 9 parties. Une marge de 16 signifie que " +"les angles de gauche des 9 parties et les côtés auront une largeur de 16 " +"pixels. Vous pouvez définir les 4 valeurs de marge individuellement pour " +"créer des panneaux avec des bordures non uniformes." #: doc/classes/NinePatchRect.xml msgid "" @@ -47907,6 +48648,10 @@ msgid "" "right corners and side will have a width of 16 pixels. You can set all 4 " "margin values individually to create panels with non-uniform borders." msgstr "" +"La largeur de la colonne droite de 9 parties. Une marge de 16 signifie que " +"les angles de droite des 9 parties et le côté auront une largeur de 16 " +"pixels. Vous pouvez définir les 4 valeurs de marge individuellement pour " +"créer des panneaux avec des bordures non uniformes." #: doc/classes/NinePatchRect.xml msgid "" @@ -47914,6 +48659,10 @@ msgid "" "corners and side will have a height of 16 pixels. You can set all 4 margin " "values individually to create panels with non-uniform borders." msgstr "" +"La hauteur de la ligne du haut de 9 parties. Une marge de 16 signifie que " +"les angles du haut des 9 parties et le côté auront une hauteur de 16 pixels. " +"Vous pouvez définir les 4 valeurs de marge individuellement pour créer des " +"panneaux avec des bordures non uniformes." #: doc/classes/NinePatchRect.xml msgid "" @@ -47922,6 +48671,10 @@ msgid "" "other properties are relative to this one. If the rect is empty, " "NinePatchRect will use the whole texture." msgstr "" +"La région rectangulaire de la texture à utiliser. Si vous travaillez avec un " +"atlas, utilisez cette propriété pour définir la zone à utiliser. Toutes les " +"autres propriétés sont par rapport à celle-ci. Si le rectangle est vide, le " +"NinePatchRect utilisera la texture dans son entièreté." #: doc/classes/NinePatchRect.xml msgid "The node's texture resource." @@ -47936,6 +48689,8 @@ msgid "" "Stretches the center texture across the NinePatchRect. This may cause the " "texture to be distorted." msgstr "" +"Étire la texture du centre sur tout le NinePatchRect. Cela peut entraîner " +"une distorsion de cette texture." #: doc/classes/NinePatchRect.xml msgid "" @@ -47945,6 +48700,11 @@ msgid "" "[b]Note:[/b] Only supported when using the GLES3 renderer. When using the " "GLES2 renderer, this will behave like [constant AXIS_STRETCH_MODE_STRETCH]." msgstr "" +"Répète la texture centrale sur tout le NinePatchRect. Cela ne provoque " +"aucune distorsion visible. La texture doit être transparente pour que cela " +"fonctionne sans afficher d'artefacts entre les bords.\n" +"[b]Note :[/b] Seulement pris en charge avec GLES3. Avec GLES2, cela se " +"comportera comme [constant AXIS_STRETCH_MODE_STRETCH]." #: doc/classes/NinePatchRect.xml msgid "" @@ -47956,6 +48716,13 @@ msgid "" "[b]Note:[/b] Only supported when using the GLES3 renderer. When using the " "GLES2 renderer, this will behave like [constant AXIS_STRETCH_MODE_STRETCH]." msgstr "" +"Répète la texture centrale sur tout le NinePatchRect, mais étirera également " +"la texture pour s'assurer que chaque tuile est visible entièrement. Cela " +"peut causer une distorsion de la texture, mais moins que [constant " +"AXIS_STRETCH_MODE_STRETCH]. La texture doit être transparente pour que cela " +"fonctionne sans afficher d'artefacts entre les bords.\n" +"[b]Note :[/b] Seulement pris en charge avec GLES3. Avec GLES2, cela se " +"comportera comme [constant AXIS_STRETCH_MODE_STRETCH]." #: doc/classes/Node.xml msgid "Base class for all [i]scene[/i] objects." @@ -48021,6 +48788,69 @@ msgid "" "(make sure node names are the same on all peers). Also, take a look at the " "high-level networking tutorial and corresponding demos." msgstr "" +"Les nÅ“uds sont les blocs de construction de Godot. Ils peuvent être assignés " +"comme enfant d'un autre nÅ“ud, ce qui entraîne définit l'arborescence. Un " +"nÅ“ud donné peut contenir n'importe quel nombre de nÅ“uds enfants mais tous " +"ces enfants doivent avoir des noms différents.\n" +"Une arborescence de nÅ“uds est appelé une [i]scène[/i]. Les scènes peuvent " +"être sauvegardées sur le disque et ensuite instanciées dans d'autres scènes. " +"Cela permet une très grande flexibilité dans l'architecture et le modèle de " +"données des projets Godot.\n" +"[b]Arbre de scène :[/b] Le [SceneTree] contient l'arborescence des nÅ“uds. " +"Lorsqu'un nÅ“ud est ajouté à l'arborescence de scène, il reçoit la " +"notification [constant NOTIFICATION_ENTER_TREE] et sa méthode [method " +"enter_tree] est appelée. Les nÅ“uds d'enfants sont toujours ajoutés [i]après[/" +"i] leur nÅ“ud parent, c'est-à -dire la méthode [method enter_tree] d'un nÅ“ud " +"parent sera appelée avant celle de son enfant.\n" +"Une fois que tous les nÅ“uds ont été ajoutés dans l'arborescence de la scène, " +"ils reçoivent la notification [constante NOTIFICATION_READY] et leurs " +"méthodes respectives [method _ready] sont appelées. Pour les groupes de " +"nÅ“uds, la méthode [method _ready] est appelée avec un ordre inversé, en " +"commençant par les enfants et en allant jusqu'aux nÅ“uds parent.\n" +"Cela signifie qu'en ajoutant un nÅ“ud à l'arborescence de la scène, l'ordre " +"suivant sera utilisé pour les appels des méthodes: [method enter_tree] du " +"parent, [method enter_tree] des enfants, [method _ready] des enfants et " +"enfin [method _ready] du parent (recursivement pour l'arborescence complète " +"de la scène).\n" +"[b]Processus :[/b] Les nÅ“uds peuvent surcharger l'état du processus, de " +"sorte qu'ils reçoivent un appel à chaque trame demandant un traitement (de " +"faire quelque chose). Le traitement normal (la méthode [method _process], " +"activée avec [method set_process]) se produit aussi vite que possible et " +"dépend du nombre de trames par seconde, de sorte que le temps de traitement " +"[i]delta[/i] (en secondes) est passé en argument. Le traitement physique (la " +"méthode [method physical_process], activée avec [method " +"set_physics_process]) est appelée un nombre fixe de fois par seconde (60 " +"fois par défaut) et est utile pour le code lié au moteur physique.\n" +"Les nÅ“uds peuvent également traiter les événements d'entrée. À l'heure " +"actuelle, la fonction [method _input] sera appelée pour chaque entrée que le " +"programme reçoit. Dans de nombreux cas, cela peut faire trop d'informations " +"(sauf pour des projets simples), et la fonction [method unhandled_input] " +"peut être préférée ; elle est appelée lorsque l'événement d'entrée n'a été " +"traité par aucun élément (généralement, des nÅ“uds d'interface [Control]), " +"pour s'assurer que le nÅ“ud ne reçoit que les événements qui lui sont " +"destinés.\n" +"Pour garder la trace de l'arborescence de la scène (surtout lorsque vous " +"instanciez des scènes dans d'autres scènes), un \"propriétaire\" peut être " +"défini pour le nÅ“ud avec la propriété [member owner]. Cela garde une trace " +"de quel élément a instancié quel autre élément. Cela est surtout utile " +"lorsque vous écrivez des éditeurs et des outils.\n" +"Enfin, quand un nÅ“ud est libéré avec [method Object.free] ou [method " +"queue_free], il va également libérer tous ses enfants.\n" +"[b]Les groupes : [/b] Les nÅ“uds peuvent être ajoutés à autant de groupes que " +"vous voulez, vous pouvez créer des groupes comme « ennemis » ou « " +"récupérables » par exemple, selon votre jeu. Voir [method add_to_group], " +"[method is_in_group] et [method remove_from_group]. Vous pouvez ensuite " +"récupérer tous les nÅ“uds d'un groupe, lister les groupes et même appeler des " +"méthodes sur les groupes via des méthodes de [SceneTree].\n" +"[b]Faire communiquer les nÅ“ud via le réseau :[/b] Après s'être connecté à un " +"serveur (ou en faire un, voir [NetworkedMultiplayerENet]), il est possible " +"d'utiliser le système RPC intégré (\"Remote Procedure Call\") pour " +"communiquer sur le réseau. En appelant [method rpc] avec un nom de méthode, " +"il sera appelé localement et pour tous les pairs connectés (un pair = un " +"client et le serveur qui accepte les connexions). Pour identifier quel nÅ“ud " +"reçoit l'appel RPC, Godot utilisera son [NodePath] (s'assurant que les noms " +"de nÅ“uds sont les mêmes sur tous les pairs). Consultez également le tutoriel " +"pour les réseaux à haut niveau et les démos correspondantes." #: doc/classes/Node.xml msgid "Nodes and Scenes" @@ -48039,6 +48869,12 @@ msgid "" "Corresponds to the [constant NOTIFICATION_ENTER_TREE] notification in " "[method Object._notification]." msgstr "" +"Appelé lorsque le nÅ“ud entre dans la [SceneTree] (par exemple en étant " +"instancié, au changement de scène, ou après avoir appelé [method add_child] " +"dans un script). Si le nÅ“ud a des enfants, sa méthode [méthod enter_tree] " +"sera appelée d'abord, puis ensuite celle de ses enfants.\n" +"Correspond à la notification [constant NOTIFICATION_ENTER_TREE] dans [method " +"Object._notification]" #: doc/classes/Node.xml msgid "" @@ -48051,6 +48887,15 @@ msgid "" "the node has already left the active tree, connect to the [signal " "tree_exited]." msgstr "" +"Appelé lorsque le nÅ“ud va quitter la [SceneTree] (par exemple sur la " +"suppression, au changement de scène, ou après avoir appelé [method " +"remove_child] dans un script). Si le nÅ“ud a des enfants, sa méthode [method " +"exit_tree] sera appelée en dernier, quand tous ses enfants auront quitté " +"l'arborescence.\n" +"Correspond à la notification [constant NOTIFICATION_EXIT_TREE] dans [method " +"Object._notification] et signal [signal tree_exiting]. Pour être notifié " +"lorsque le nÅ“ud a déjà quitté l'arborescence active, connectez-vous à " +"[signal tree_exited]." #: doc/classes/Node.xml msgid "" @@ -48060,6 +48905,12 @@ msgid "" "Call [method update_configuration_warning] when the warning needs to be " "updated for this node." msgstr "" +"La chaîne retournée de cette méthode est affichée comme un avertissement " +"dans la barre d'outil Scène si le script qui la modifie est un script " +"[code]tool[/code].\n" +"Retourner une chaîne vide ne produit aucun avertissement.\n" +"Appelez [method update_configuration_warning] lorsque l'avertissement doit " +"être mis à jour pour ce nÅ“ud." #: doc/classes/Node.xml msgid "" @@ -48158,6 +49009,21 @@ msgid "" "call with [method request_ready], which may be called anywhere before adding " "the node again." msgstr "" +"Appelé lorsque le nÅ“ud est « prêt », c'est-à -dire lorsque le nÅ“ud et ses " +"enfants sont entrés dans l'arborescence de la scène. Si le nÅ“ud a des " +"enfants, leur méthode [method _ready] sera appelée en premier, et le nÅ“ud " +"parent recevra la notification après.\n" +"Correspond à la notification [constant NOTIFICATION_READY] dans [method " +"Object._notification]. Voir aussi le mot-clé [code]onready[/code] pour les " +"variables.\n" +"Habituellement utilisé pour l'initialisation. Pour encore avant cela, " +"[method Object._init] peut être utilisé. Voir aussi [méthod enter_tree].\n" +"[b]Note :[/b] [method _ready] ne peut être appelée qu'une seule fois pour " +"chaque nÅ“ud. Après avoir retiré un nÅ“ud de l'arborescence de scène et " +"l'ajouter à nouveau, [code]_ready[/code] ne sera pas appelé une deuxième " +"fois. Cela peut être changé en demandant un autre appel avec [method " +"request_ready], qui peut être appelé n'importe où avant d'ajouter le nÅ“ud à " +"nouveau." #: doc/classes/Node.xml msgid "" @@ -48247,6 +49113,30 @@ msgid "" "will not be visible in the scene tree, though it will be visible in the " "2D/3D view." msgstr "" +"Ajoute un nÅ“ud enfant. Les nÅ“uds peuvent avoir autant d'enfants que voulu, " +"mais chaque enfant doit avoir un nom unique. Les nÅ“uds d'enfants sont " +"automatiquement supprimés lorsque le nÅ“ud parent est supprimé, de sorte " +"qu'une scène entière peut être supprimée en supprimant juste son nÅ“ud le " +"plus haut.\n" +"Si [code]legible_unique_name[/code] est [code]true[/code], le nÅ“ud d'enfant " +"aura un nom clairement lisible basé sur le nom du nÅ“ud étant analysé au lieu " +"de son type.\n" +"[b]Note :[/b] Si le nÅ“ud enfant a déjà un parent, la fonction échouera. " +"Utilisez [method remove_child] d'abord pour retirer le nÅ“ud de son parent " +"actuel. Par exemple :\n" +"[codeblock]\n" +"if child_node.get_parent():\n" +" child_node.get_parent().remove_child(child_node)\n" +"add_child(child_node)\n" +"[/codeblock]\n" +"[b]Note :[/b] Si vous voulez qu'un enfant soit persiste dans un " +"[PackedScene], vous devez définir [member owner] après avoir appelé [method " +"add_child]. Ceci est généralement pertinent pour [url=$DOCS_URL/tutorials/" +"plugins/running_code_in_the_editor.html]scripts d'outil[/url] et " +"[url=$DOCS_URL/tutorials/plugins/editor/index.html]greffons d'éditeur[/url]. " +"Si [method add_child] est appelé sans définir [member owner], le nouveau " +"[Node] ajouté ne sera pas visible dans l'arborescence de la scène, bien " +"qu'il sera visible dans la vue 2D/3D." #: doc/classes/Node.xml msgid "" @@ -48256,6 +49146,10 @@ msgid "" "will have a human-readable name based on the name of the node being " "instanced instead of its type." msgstr "" +"Ajoute [code]child_nÅ“ud[/code] en tant qu'enfant. L'enfant est placé sous le " +"[code]nÅ“ud[/code] donné dans la liste des enfants.\n" +"Si [code]legible_unique_name[/code] est [code]true[/code], le nÅ“ud d'enfant " +"aura un nom lisible humainement basé sur le nom du nÅ“ud plutôt que son type." #: doc/classes/Node.xml msgid "" @@ -48278,6 +49172,10 @@ msgid "" "scene tree is not paused, and [code]false[/code] if the node is not in the " "tree." msgstr "" +"Retourne [code]true[/code] si le nÅ“ud peut traiter pendant que " +"l'arborescence de scène est interrompue (voir [member pause_mode)]. Retourne " +"toujours [code]true[/code] si l'arborescence de scène n'est pas interrompue, " +"et [code]false[/code] si le nÅ“ud n'est pas dans l'arborescence." #: doc/classes/Node.xml msgid "" @@ -48287,6 +49185,10 @@ msgid "" "get_tree().create_tween().bind_node(self)\n" "[/codeblock]" msgstr "" +"Crée un nouveau [SceneTreeTween] et le lie à ce nÅ“ud. Cela équivaut à :\n" +"[codeblock]\n" +"get_tree().create_tween().bind_node(self)\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" @@ -48297,6 +49199,13 @@ msgid "" "constructor arguments (i.e. needs to supply arguments to [method Object." "_init] method). In that case, the node will be duplicated without a script." msgstr "" +"Duplique le nÅ“ud, retournant un nouveau nÅ“ud.\n" +"Vous pouvez affiner le comportement en utilisant des drapeaux dans " +"[code]flags[/code] (voir [enum DuplicateFlags)].\n" +"[b]Note :[/b] Ça ne fonctionnera pas correctement si le nÅ“ud contient un " +"script avec des arguments de constructeur (c'est-à -dire qu'on doit fournir " +"des arguments à la méthode [method Object._init]). Dans ce cas, le nÅ“ud sera " +"dupliqué sans script." #: doc/classes/Node.xml msgid "" @@ -48315,6 +49224,23 @@ msgid "" "consider using [method get_node] instead. To avoid using [method find_node] " "too often, consider caching the node reference into a variable." msgstr "" +"Trouve un descendant de ce nÅ“ud dont le nom correspond à [code]mask[/code] " +"suivant le même fonctionnement que pour [method String.match] (c'est-à -dire " +"sensible à la casse, que [code]\"*\"[/code] correspond à un zéro au un seul " +"caractère, et que [code]\"?\"[/code] correspond à n'importe quel unique " +"caractère sauf [code]\".\"[/code]). Retourne [code]null[/code] si aucun " +"[Node] correspondant n'est trouvée.\n" +"[b]Note :[/b] La correspondance ne se fait pas sur le chemin complet mais " +"juste les noms des nÅ“uds.\n" +"Si [code]owned[/code] est [code]true[/code], cette méthode ne trouve que des " +"nÅ“uds dont le propriétaire est ce nÅ“ud. Ceci est particulièrement important " +"pour les scènes instanciée par un script, parce que ces scènes n'ont pas de " +"propriétaire.\n" +"[b]Note :[/b] Comme cette méthode liste tous les descendants d'un nÅ“ud, " +"c'est le moyen le plus lent d'obtenir une référence à un autre nÅ“ud. Dans la " +"mesure du possible, essayez plutôt d'utiliser [method get_node]. Pour éviter " +"d'utiliser [method find_node] trop souvent, essayez de mettre en chache la " +"référence de ce nÅ“ud dans une variable." #: doc/classes/Node.xml msgid "" @@ -48329,6 +49255,23 @@ msgid "" "[method get_node] instead. To avoid using [method find_parent] too often, " "consider caching the node reference into a variable." msgstr "" +"Trouve un parent de ce nÅ“ud dont le nom correspond à [code]mask[/code] " +"suivant le même fonctionnement que pour [method String.match] (c'est-à -dire " +"sensible à la casse, que [code]\"*\"[/code] correspond à un zéro au un seul " +"caractère, et que [code]\"?\"[/code] correspond à n'importe quel unique " +"caractère sauf [code]\".\"[/code]). Retourne [code]null[/code] si aucun " +"[Node] correspondant n'est trouvée.\n" +"[b]Note :[/b] La correspondance ne se fait pas sur le chemin complet mais " +"juste les noms des nÅ“uds.\n" +"Si [code]owned[/code] est [code]true[/code], cette méthode ne trouve que des " +"nÅ“uds dont le propriétaire est ce nÅ“ud. Ceci est particulièrement important " +"pour les scènes instanciée par un script, parce que ces scènes n'ont pas de " +"propriétaire.\n" +"[b]Note :[/b] Comme cette méthode liste tous les parents d'un nÅ“ud, c'est le " +"moyen le plus lent d'obtenir une référence à un autre nÅ“ud. Dans la mesure " +"du possible, essayez plutôt d'utiliser [method get_node]. Pour éviter " +"d'utiliser [method find_node] trop souvent, essayez de mettre en chache la " +"référence de ce nÅ“ud dans une variable." #: doc/classes/Node.xml msgid "" @@ -48336,6 +49279,9 @@ msgid "" "method is often used for iterating all children of a node.\n" "To access a child node via its name, use [method get_node]." msgstr "" +"Retourne un nÅ“ud enfant par son index (voir [method get_child_count)]. Cette " +"méthode est souvent utilisée pour itérer tous les enfants d'un nÅ“ud.\n" +"Pour accéder à un nÅ“ud enfant par son nom, utilisez [method get_node]." #: doc/classes/Node.xml msgid "Returns the number of child nodes." @@ -48363,17 +49309,38 @@ msgid "" " non_internal_groups.push_back(group)\n" "[/codeblock]" msgstr "" +"Retourne un tableau énumérant les groupes dont ce nÅ“ud est membre.\n" +"[b]Note :[/b] Pour des raisons de performance, l'ordre des groupes de nÅ“uds " +"n'est [i]pas[/i] garanti. cet ordre des groupes de nÅ“uds ne devrait pas être " +"utilisé car il peut varier entre les différents projets.\n" +"[b]Note :[/b] Le moteur utilise des noms de groupe en l'interne (tous " +"commençent par \"_\"). Pour éviter les conflits avec des groupes internes, " +"n'ajoutez pas de groupes personnalisés dont le nom commence par \"_\". Pour " +"exclure les groupes internes en boucle sur [method get_groups], utiliser le " +"code suivant:\n" +"[codeblock]\n" +"# Enregistre tous les nÅ“uds des groupes non internes au moteur (dans un " +"tableau de String).\n" +"var non_internal_groups = []\n" +"for group in get_groups():\n" +" if not group.begins_with(\"_\"):\n" +" non_internal_groups.push_back(group)\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" "Returns the node's index, i.e. its position among the siblings of its parent." msgstr "" +"Retourne l'indice du nÅ“ud, c'est-à -dire sa position parmi les enfants de son " +"parent." #: doc/classes/Node.xml msgid "" "Returns the peer ID of the network master for this node. See [method " "set_network_master]." msgstr "" +"Retourne l'identifiant du pair du maître du réseau pour ce nÅ“ud. Voir " +"[method set_network_master]." #: doc/classes/Node.xml msgid "" @@ -48452,12 +49419,33 @@ msgid "" "[[CollisionShape2D:1161], [RectangleShape2D:1156], :extents]\n" "[/codeblock]" msgstr "" +"Récupère un nÅ“ud et une de ses ressources comme spécifié par le sous-nom de " +"son [NodePath] (ex.: [code]Area2D/CollisionShape2D:shape[/code)]. Si " +"plusieurs ressources imbriquées sont spécifiées dans le [NodePath], seul le " +"dernier sera récupéré.\n" +"La valeur de retour est un tableau de 3 éléments : le premier élément est le " +"[Node] (ou [code]null[/code] s'il n'est pas trouvé), le deuxième élément est " +"la [Resource] (ou [code]null[/code] si elle n'est pas trouvée), et le " +"troisième élément est le reste du [NodePath], le cas échéant.\n" +"Par exemple, en supposant que [code]Area2D/CollisionShape2D[/code] est un " +"nÅ“ud valide et que sa propriété [code]shape[/code] a été assignée à une " +"ressource [RectangleShape2D], on pourrait avoir ce type de sortie:\n" +"[codeblock]\n" +"print(get_node_and_resource(\"Area2D/CollisionShape2D\")) # " +"[[CollisionShape2D:1161], Null, ]\n" +"print(get_node_and_resource(\"Area2D/CollisionShape2D:shape\")) # " +"[[CollisionShape2D:1161], [RectangleShape2D:1156], ]\n" +"print(get_node_and_resource(\"Area2D/CollisionShape2D:shape:extents\")) # " +"[[CollisionShape2D:1161], [RectangleShape2D:1156], :extents]\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" "Similar to [method get_node], but does not log an error if [code]path[/code] " "does not point to a valid [Node]." msgstr "" +"Semblable à [method get_node], mais n'affiche pas d'erreur si [code]path[/" +"code] ne pointe pas vers une valeur valide [Node]." #: doc/classes/Node.xml msgid "" @@ -48472,12 +49460,18 @@ msgid "" "Returns the absolute path of the current node. This only works if the " "current node is inside the scene tree (see [method is_inside_tree])." msgstr "" +"Retourne le chemin absolu du nÅ“ud actuel. Cela ne fonctionne que si le nÅ“ud " +"actuel est à l'intérieur de l'arborescence de la scène (voir [method " +"is_inside_tree)]." #: doc/classes/Node.xml msgid "" "Returns the relative [NodePath] from this node to the specified [code]node[/" "code]. Both nodes must be in the same scene or the function will fail." msgstr "" +"Retourne le chemin [NodePath] relatif de ce nÅ“ud par rapport au nÅ“ud " +"[code]nÅ“ud[/code] spécifié. Les deux nÅ“uds doivent être dans la même scène " +"sinon la fonction échouera." #: doc/classes/Node.xml msgid "" @@ -48486,18 +49480,26 @@ msgid "" "processing unless the frames per second is changed via [member Engine." "iterations_per_second]." msgstr "" +"Retourne le temps écoulé (en secondes) depuis la dernière trame physique " +"(voir [method _physics_process]). C'est toujours une valeur constante dans " +"le traitement de la physique à moins que les trames par seconde ne soient " +"changés via [member Engine.iterations_per_second]" #: doc/classes/Node.xml msgid "" "Returns the node's order in the scene tree branch. For example, if called on " "the first child node the position is [code]0[/code]." msgstr "" +"Retourne l'ordre du nÅ“ud dans la branche de la scène. Par exemple, si on " +"l'appelle sur le premier nÅ“ud enfant, la position est [code]0[/code]." #: doc/classes/Node.xml msgid "" "Returns the time elapsed (in seconds) since the last process callback. This " "value may vary from frame to frame." msgstr "" +"Retourne le temps écoulé (en secondes) depuis le dernier rappel de process. " +"Cette valeur peut varier d'une trame à l'autre." #: doc/classes/Node.xml msgid "" @@ -48528,12 +49530,19 @@ msgid "" "shape[/code]. Properties with a non-[Resource] type (e.g. nodes or primitive " "math types) are not considered resources." msgstr "" +"Retourne [code]true[/code] si le [NodePath] désigne un nÅ“ud valide et son " +"sous-nom désigne une ressource valide, par exemple [code]Area2D/" +"CollisionShape2D:shape[/code]. Les propriétés avec un type qui n'est pas une " +"[Resource] (par exemple les nÅ“uds ou les types mathématiques primitifs) ne " +"sont pas considérées comme des ressources." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if the given node is a direct or indirect child of " "the current node." msgstr "" +"Retourne [code]true[/code] si le nÅ“ud donné est un enfant direct ou indirect " +"du nÅ“ud actuel." #: doc/classes/Node.xml msgid "" @@ -48554,6 +49563,8 @@ msgid "" "Returns [code]true[/code] if this node is in the specified group. See notes " "in the description, and the group methods in [SceneTree]." msgstr "" +"Retourne [code]true[/code] si ce nÅ“ud est dans le groupe spécifié. Voir les " +"notes dans la description, et les méthodes de groupe dans [SceneTree]." #: doc/classes/Node.xml msgid "" @@ -48565,6 +49576,7 @@ msgstr "" msgid "" "Returns [code]true[/code] if the local system is the master of this node." msgstr "" +"Retourne [code]true[/code] si le système local est le maître de ce nÅ“ud." #: doc/classes/Node.xml msgid "" @@ -48574,6 +49586,11 @@ msgid "" "[b]and[/b] physics interpolation is enabled within the [SceneTree]. This can " "be tested using [method is_physics_interpolated_and_enabled]." msgstr "" +"Retourne [code]true[/code] si le drapeau interpolé de la physique est défini " +"pour ce nÅ“ud (voir [member physics_interpolation_mode)].\n" +"[b]Note :[/b] L'interpolation ne sera active que si le drapeau est défini " +"[b]et[/b] que l'interpolation physique est activée dans [SceneTree]. Ceci " +"peut être testé en utilisant [method is_physics_interpolated_and_enabled]." #: doc/classes/Node.xml msgid "" @@ -48584,36 +49601,52 @@ msgid "" "See [member SceneTree.physics_interpolation] and [member ProjectSettings." "physics/common/physics_interpolation]." msgstr "" +"Retourne [code]true[/code] si l'interpolation physique est activée (voir " +"[member physics_interpolation_mode]) [b]et[/b] activée dans [SceneTree].\n" +"Il s'agit d'une version pratique de [method is_physics_interpolated] qui " +"vérifie également si l'interpolation physique est activée globalement.\n" +"Voir [member SceneTree.physics_interpolation] et [member ProjectSettings." +"physics/common/physics_interpolation]" #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if physics processing is enabled (see [method " "set_physics_process])." msgstr "" +"Retourne [code]true[/code] si le traitement physique est activé (voir " +"[method set_physics_process)]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if internal physics processing is enabled (see " "[method set_physics_process_internal])." msgstr "" +"Retourne [code]true[/code] si le traitement physique interne est activé " +"(voir [method set_physics_process_internal)]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if processing is enabled (see [method " "set_process])." msgstr "" +"Retourne [code]true[/code] si le traitement est activé (voir [method " +"set_process)]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if the node is processing input (see [method " "set_process_input])." msgstr "" +"Retourne [code]true[/code] si le nÅ“ud gère l'entrée (voir [method " +"set_process_input)]." #: doc/classes/Node.xml msgid "" "Returns [code]true[/code] if internal processing is enabled (see [method " "set_process_internal])." msgstr "" +"Retourne [code]true[/code] si le traitement interne est activé (voir [method " +"set_process_internal)]." #: doc/classes/Node.xml msgid "" @@ -48628,6 +49661,8 @@ msgid "" "Returns [code]true[/code] if the node is processing unhandled key input (see " "[method set_process_unhandled_key_input])." msgstr "" +"Retourne [code]true[/code] si le nÅ“ud gère l'entrée de touche non traitée " +"(voir [method set_process_unhandled_key_input)]." #: doc/classes/Node.xml msgid "" @@ -48635,12 +49670,17 @@ msgid "" "Since calls, signals, etc are performed by tree order, changing the order of " "children nodes may be useful." msgstr "" +"Déplace un nÅ“ud enfant à une position différente (ordre) parmi les autres " +"enfants. Comme les appels, les signaux, etc. sont effectués par l'ordre des " +"arborescences, changer l'ordre des nÅ“uds d'enfants peut être utile." #: doc/classes/Node.xml msgid "" "Prints all stray nodes (nodes outside the [SceneTree]). Used for debugging. " "Works only in debug builds." msgstr "" +"Imprime tous les nÅ“uds égarés (sauf le [SceneTree)]. Utilisé pour le " +"débogage. Fonctionne seulement dans les versions de débogage." #: doc/classes/Node.xml msgid "" @@ -48657,6 +49697,18 @@ msgid "" "TheGame/SplashScreen/Camera2D\n" "[/codeblock]" msgstr "" +"Imprime l'arborescence dans la console. Utilisé principalement à des fins de " +"débogage. Cette version affiche le chemin par rapport au nÅ“ud actuel, ce qui " +"est utile pour le copier/coller dans la fonction [method get_node].\n" +"[ b]Exemple de sortie:[/b]\n" +"[codeblock]\n" +"TheGame\n" +"TheGame/Menu\n" +"TheGame/Menu/Label\n" +"TheGame/Menu/Camera2D\n" +"TheGame/SplashScreen\n" +"TheGame/SplashScreen/Camera2D\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" @@ -48673,6 +49725,19 @@ msgid "" " â”–â•´Camera2D\n" "[/codeblock]" msgstr "" +"Comme [method print_tree], cela imprime l'arborescence dans la console. " +"Cette version affiche une représentation plus graphique semblable à ce qui " +"est affiché dans l'inspecteur de scène. C'est utile pour inspecter les " +"grands arborescences.\n" +"[ b]Exemple de sortie:[/b]\n" +"[codeblock]\n" +" â”–â•´TheGame\n" +" â” â•´Menu\n" +" ┃ â” â•´Label\n" +" ┃ â”–â•´Camera2D\n" +" â”–â•´SplashScreen\n" +" â”–â•´Camera2D\n" +"[/codeblock]" #: doc/classes/Node.xml msgid "" @@ -48683,12 +49748,20 @@ msgid "" "[code]parent_first[/code] is [code]false[/code], the children will be called " "first." msgstr "" +"Appelle la méthode donnée (si présente) avec les arguments spécifiés dans " +"[code]args[/code] sur ce nÅ“ud et récursivement sur tous ses enfants. Si " +"l'argument [code]parent_first[/code] est [code]true[/code], la méthode sera " +"appelée d'abord sur le nÅ“ud courant, puis sur tous ses enfants. Si " +"[code]parent_first[/code] est [code]false[/code], les enfants seront appelés " +"en premier." #: doc/classes/Node.xml msgid "" "Notifies the current node and all its children recursively by calling " "[method Object.notification] on all of them." msgstr "" +"Notifie le nÅ“ud actuel et tous ses enfants de façon récursive en les " +"appelant [method Object.notification] sur tous." #: doc/classes/Node.xml msgid "" @@ -48703,6 +49776,17 @@ msgid "" "[method @GDScript.is_instance_valid] before attempting to call its methods " "or access its properties." msgstr "" +"Place le nÅ“ud dans une file d'attente pour la suppression à la fin de la " +"trame actuel. Lorsque supprimé, tous ses nÅ“uds d'enfants seront supprimés " +"aussi. Cette méthode s'assure qu'il est sûr de supprimer le nÅ“ud, " +"contrairement [method Object.free]. Utilisez [method Object." +"is_queued_for_deletion] pour vérifier si un nÅ“ud sera supprimé à la fin de " +"la trame.\n" +"[b]Important:[/b] Si vous avez une variable pointant vers un nÅ“ud, il ne " +"sera [i]pas[/i] attribué à [code]null[/code] une fois le nÅ“ud libéré. Au " +"lieu de cela, il va pointer vers [i]l'instance précédemment libérée[/i] et " +"vous devez le valider avec [method @GDScript.is_instance_valid] avant de " +"risquer d'appeler des méthodes dessus ou d'accéder à ses propriétés." #: doc/classes/Node.xml msgid "" @@ -48713,6 +49797,12 @@ msgid "" "of it. After using [code]raise[/code], a Control will be drawn on top of its " "siblings." msgstr "" +"Déplace ce nÅ“ud vers le bas de la hiérarchie des enfants. Cela est souvent " +"utile dans les nÅ“uds d'interface ([Control]), parce que leur ordre de dessin " +"dépend de leur ordre dans l'arborescence. Le Node en haut est dessiné " +"d'abord, puis les nÅ“uds en dessous dans la hiérarchie qui sont " +"successivement dessinés. Après avoir utilisé [code]raise[/code], un contrôle " +"sera affiché par dessus les autres enfants." #: doc/classes/Node.xml msgid "" @@ -48720,6 +49810,9 @@ msgid "" "it exists). All event subscriptions that pass by the removed node will be " "unsubscribed." msgstr "" +"Retire un nÅ“ud et fixe tous ses enfants comme enfants du nÅ“ud parent (s'il " +"existe). Tous les souscriptions d'événement qui passent par le nÅ“ud retiré " +"seront aussi retirées." #: doc/classes/Node.xml msgid "" @@ -48728,12 +49821,19 @@ msgid "" "(or its descendants) to be [code]null[/code], if that [member owner] is no " "longer a parent or ancestor." msgstr "" +"Retire un nÅ“ud d'enfant. Le nÅ“ud n'est PAS supprimé et doit être supprimé " +"manuellement.\n" +"[b]Note :[/b] Cette fonction peut définir le [member owner] du nÅ“ud enlevé " +"(ou ses descendants) comme [code]null[/code], si ce [member owner] n'est " +"plus un parent." #: doc/classes/Node.xml msgid "" "Removes a node from a group. See notes in the description, and the group " "methods in [SceneTree]." msgstr "" +"Retire un nÅ“ud d'un groupe. Voir les notes dans la description, et les " +"méthodes de groupe dans [SceneTree]." #: doc/classes/Node.xml msgid "" @@ -48745,6 +49845,13 @@ msgid "" "need to keep it in a variable for later use or free it using [method Object." "free]." msgstr "" +"Remplace un nÅ“ud dans une scène par celui donné. Les souscriptions qui " +"passent par ce nÅ“ud seront perdus.\n" +"[b]Note :[/b] Le nÅ“ud donné deviendra le nouveau parent de tous les nÅ“uds " +"d'enfants que le nÅ“ud remplacé avait.\n" +"[b]Note :[/b] Le nÅ“ud remplacé n'est pas automatiquement libéré, donc vous " +"devez le garder dans une variable pour une utilisation ultérieure ou le " +"libérer en utilisant [method Object.free]" #: doc/classes/Node.xml msgid "" @@ -48756,6 +49863,13 @@ msgid "" "which case, [code]_ready[/code] will be called in the same order as it would " "normally)." msgstr "" +"Demande que [code]_ready[/code] soit de nouveau appelé. Notez que la méthode " +"va s'appeler immédiatement, mais qu'elle est prévue lorsque le nÅ“ud est " +"ajouté à l'arborescence de scène à nouveau (voir [method _ready)]. " +"[code]_ready[/code] est appelé seulement pour le nÅ“ud qui l'a demandé, ce " +"qui signifie que vous devez le demander pour chaque enfant si vous voulez " +"qu'ils appellent [code]_ready[/code] aussi (dans quel cas, [code]_ready[/" +"code] sera appelé dans le même ordre que normalement)." #: doc/classes/Node.xml msgid "" @@ -48771,6 +49885,17 @@ msgid "" "[b]Note:[/b] This function should be called [b]after[/b] moving the node, " "rather than before." msgstr "" +"Lorsque l'interpolation de la physique est active, déplacer un nÅ“ud vers une " +"transformation radicalement différente (comme le placement dans un niveau) " +"peut entraîner un glissement visible car l'objet est rendu lors de son " +"déplacement lors de la trame physique.\n" +"Ce glitch peut être évité en appelant [code]reset_physics_interpolation[/" +"code], qui annule temporairement l'interpolation jusqu'à ce que la trame " +"physique soit complète.\n" +"[constant NOTIFICATION_RESET_PHYSICS_INTERPOLATION] sera reçu par le nÅ“ud et " +"tous les enfants de façon récursive.\n" +"[b]Note :[/b] Cette fonction doit être appelée [b]après[/b] le déplacement " +"du nÅ“ud, plutôt qu'avant." #: doc/classes/Node.xml msgid "" @@ -48788,6 +49913,20 @@ msgid "" "like [code]server_disconnected[/code] or by checking [code]SceneTree." "network_peer.get_connection_status() == CONNECTION_CONNECTED[/code]." msgstr "" +"Envoie une requête d'appel de procédure à distance pour la [code]method[/" +"code] donnée aux pairs sur le réseau (et localement), en option en envoyant " +"tous les arguments supplémentaires comme arguments à la méthode appelée par " +"le RPC. La requête d'appel ne sera reçue que par des nÅ“uds ayant le même " +"[NodePath], y compris le même nom de nÅ“ud. Le comportement dépend de la " +"configuration RPC pour la méthode donnée, voir [method rpc_config]. Les " +"méthodes ne sont pas exposées aux RPC par défaut. Voir aussi [method rset] " +"et [method rset_config] pour les propriétés. Retourne [code]null[/code].\n" +"[b]Note :[/b] Vous pouvez seulement utiliser RPC en toute sécurité sur les " +"clients après avoir reçu le signal [code]connected_to_server[/code] du " +"[SceneTree]. Vous devez également suivre l'état de connexion, soit par les " +"signaux [SceneTree] comme [code]server_disconnected[/code] ou en vérifiant " +"[code]SceneTree.network_peer.get_connection_status() == " +"CONNECTION_CONNECTED[/code]." #: doc/classes/Node.xml msgid "" @@ -48799,6 +49938,13 @@ msgid "" "By default, methods are not exposed to networking (and RPCs). See also " "[method rset] and [method rset_config] for properties." msgstr "" +"Change le mode RPC pour la [code]method[/code] donné pour le [code]mode[/" +"code] spécifié. Voir [enum MultiplayerAPI.RPCMode]. Une alternative est " +"d'annoter les méthodes et les propriétés avec les mots-clés correspondants " +"([code]remote[/code], [code]master[/code], [code]puppet[/code], " +"[code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/code)]. " +"Par défaut, les méthodes ne sont pas exposées au réseaut (et aux RPC). Voir " +"aussi [method rset] et [method rset_config] pour les propriétés." #: doc/classes/Node.xml msgid "" @@ -48806,6 +49952,9 @@ msgid "" "(see [method NetworkedMultiplayerPeer.set_target_peer]). Returns [code]null[/" "code]." msgstr "" +"Envoie un [method rpc] à un pair spécifique identifié par [code]peer_id[/" +"code] (voir [method NetworkedMultiplayerPeer.set_target_peer]). Retourne " +"[code]null[/code]." #: doc/classes/Node.xml msgid "" @@ -48820,6 +49969,9 @@ msgid "" "using an unreliable protocol (see [method NetworkedMultiplayerPeer." "set_target_peer]). Returns [code]null[/code]." msgstr "" +"Envoie un [method rpc] à un pair spécifique identifié par [code]peer_id[/" +"code] en utilisant un protocole non fiable (voir [method " +"NetworkedMultiplayerPeer.set_target_peer]). Retourne [code]null[/code]." #: doc/classes/Node.xml msgid "" @@ -48828,6 +49980,10 @@ msgid "" "rset_config]. See also [method rpc] for RPCs for methods, most information " "applies to this method as well." msgstr "" +"Change une propriété distante sur d'autres pairs (et localement). Le " +"comportement dépend de la configuration du RPC pour la propriété donnée, " +"voir [method rset_config]. Voir aussi [method rpc] pour les RPC sur les " +"méthodes, la plupart des informations s'appliquent aussi à cette méthode." #: doc/classes/Node.xml msgid "" @@ -48839,6 +49995,13 @@ msgid "" "By default, properties are not exposed to networking (and RPCs). See also " "[method rpc] and [method rpc_config] for methods." msgstr "" +"Change le mode RPC pour la [code]property[/code] donnée au [code]mode[/code] " +"spécifié. Voir [enum MultiplayerAPI.RPCMode]. Une alternative est " +"l'annotation des méthodes et des propriétés avec les mots-clés " +"correspondants ([code]remote[/code], [code]master[/code], [code]puppet[/" +"code], [code]remotesync[/code], [code]mastersync[/code], [code]puppetsync[/" +"code)]. Par défaut, les propriétés ne sont pas exposées au réseau (et au " +"RPC). Voir aussi [method rpc] et [method rpc_config] pour les méthodes." #: doc/classes/Node.xml msgid "" @@ -50503,8 +51666,14 @@ msgid "See [enum ShadowDetail]." msgstr "Voir [enum ShadowDetail]." #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." -msgstr "Voir [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." +msgstr "" #: doc/classes/OmniLight.xml msgid "" @@ -50515,7 +51684,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -69876,16 +71046,26 @@ msgid "The size of one pixel's width on the sprite to scale it in 3D." msgstr "La taille d'un des pixels de la sprite pour définir sa taille en 3D." #: doc/classes/SpriteBase3D.xml +#, fuzzy msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " "This is because opaque objects are not sorted, while transparent objects are " "sorted from back to front (subject to priority)." msgstr "" +"Définit la priorité de rendu pour le texte. Des objets plus prioritaires " +"seront affichés par-dessus des objets moins inférieurs.\n" +"[b]Note: [/b] Cela ne s'applique que si [member alpha_cut] est défini à " +"[constant ALPHA_CUT_DISABLED] (c'est la valeur par défaut).\n" +"[b]Note :[/b] Cela ne s'applique qu'au tri des objets transparents. Cela " +"n'affectera pas la façon dont les objets transparents sont triés par rapport " +"aux objets opaques. C'est parce que les objets opaques ne sont pas triés, " +"alors que les objets transparents sont triés de l'arrière à l'avant (et " +"suivant leur priorité)." #: doc/classes/SpriteBase3D.xml #, fuzzy @@ -73232,9 +74412,10 @@ msgid "Sets the text for a specific line." msgstr "Définit le texte pour la ligne spécifiée." #: doc/classes/TextEdit.xml +#, fuzzy msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" "Ajoute un marque-page pour la ligne [code]line[/code] si [code]bookmark[/" @@ -77233,14 +78414,19 @@ msgid "" msgstr "" #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" +"Retourne le TreeItem précédent dans l'arbre ou un objet nul s'il n'y en a " +"pas." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -77255,16 +78441,19 @@ msgid "Returns the parent TreeItem or a null object if there is none." msgstr "Renvoie le TreeItem parent ou un objet nul s’il n’y en a pas." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" "Retourne le TreeItem précédent dans l'arbre ou un objet nul s'il n'y en a " "pas." #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -84934,9 +86123,12 @@ msgstr "" "Définit la matrice de transformation globale de la fenêtre d'affichage." #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Si [code]true[/code], l'interpolation fait une boucle." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -85028,6 +86220,15 @@ msgstr "Convertit le format de l’image. Voir les constantes [enum Format]." #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/gl.po b/doc/translations/gl.po index 17fb042ad7..207a818761 100644 --- a/doc/translations/gl.po +++ b/doc/translations/gl.po @@ -848,7 +848,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7685,8 +7692,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11754,7 +11761,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20165,7 +20177,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23551,7 +23563,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25382,7 +25394,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32478,7 +32490,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32494,7 +32506,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32524,7 +32536,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36624,7 +36636,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36885,7 +36897,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36999,6 +37011,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39696,7 +39754,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39708,7 +39772,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57462,7 +57527,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60353,8 +60418,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63977,13 +64042,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63995,13 +64061,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70887,7 +70954,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70972,6 +71043,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/hi.po b/doc/translations/hi.po index 98778940cf..2df4b9bbe4 100644 --- a/doc/translations/hi.po +++ b/doc/translations/hi.po @@ -847,7 +847,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7684,8 +7691,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11753,7 +11760,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20164,7 +20176,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23550,7 +23562,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25381,7 +25393,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32477,7 +32489,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32493,7 +32505,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32523,7 +32535,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36623,7 +36635,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36884,7 +36896,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36998,6 +37010,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39695,7 +39753,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39707,7 +39771,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57461,7 +57526,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60352,8 +60417,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63976,13 +64041,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63994,13 +64060,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70886,7 +70953,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70971,6 +71042,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/hu.po b/doc/translations/hu.po index 325d7d0f52..221206451a 100644 --- a/doc/translations/hu.po +++ b/doc/translations/hu.po @@ -866,7 +866,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7703,8 +7710,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11772,7 +11779,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20183,7 +20195,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23569,7 +23581,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25400,7 +25412,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32496,7 +32508,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32512,7 +32524,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32542,7 +32554,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36642,7 +36654,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36903,7 +36915,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37017,6 +37029,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39714,7 +39772,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39726,7 +39790,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57480,7 +57545,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60371,8 +60436,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63995,13 +64060,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64013,13 +64079,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70905,7 +70972,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70990,6 +71061,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/id.po b/doc/translations/id.po index eb95a98f22..39310a6160 100644 --- a/doc/translations/id.po +++ b/doc/translations/id.po @@ -1199,10 +1199,22 @@ msgstr "" "atau peringatan dicetak." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Seperti [metode cetak], tetapi hanya mencetak saat digunakan dalam mode " -"debug." +"Mencetak trek tumpukan di lokasi kode, hanya berfungsi saat dijalankan " +"dengan debugger dihidupkan.\n" +"Output di konsol akan terlihat seperti ini:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 dalam fungsi '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml #, fuzzy @@ -8097,8 +8109,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12166,7 +12178,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20579,7 +20596,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23969,7 +23986,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25806,7 +25823,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32903,7 +32920,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32919,7 +32936,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32949,7 +32966,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37070,7 +37087,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37331,7 +37348,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37447,6 +37464,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40144,7 +40207,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40156,7 +40225,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57931,7 +58001,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60828,8 +60898,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64453,13 +64523,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64471,13 +64542,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71368,7 +71440,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71453,6 +71529,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/is.po b/doc/translations/is.po index c68a096dfa..e3080abf39 100644 --- a/doc/translations/is.po +++ b/doc/translations/is.po @@ -847,7 +847,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7684,8 +7691,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11753,7 +11760,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20164,7 +20176,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23550,7 +23562,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25381,7 +25393,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32477,7 +32489,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32493,7 +32505,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32523,7 +32535,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36623,7 +36635,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36884,7 +36896,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36998,6 +37010,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39695,7 +39753,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39707,7 +39771,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57461,7 +57526,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60352,8 +60417,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63976,13 +64041,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63994,13 +64060,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70886,7 +70953,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70971,6 +71042,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/it.po b/doc/translations/it.po index fd78bc8f1c..3acfabc091 100644 --- a/doc/translations/it.po +++ b/doc/translations/it.po @@ -25,12 +25,13 @@ # Andrea Leganza <neogene@gmail.com>, 2021. # Federico Caprini <caprinifede@gmail.com>, 2022. # Alessandro Casalino <alessandro.casalino93@gmail.com>, 2022. +# AndreWharn <andrewharnofficial@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-04-25 15:12+0000\n" -"Last-Translator: Micila Micillotto <micillotto@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" +"Last-Translator: AndreWharn <andrewharnofficial@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/it/>\n" "Language: it\n" @@ -38,7 +39,7 @@ msgstr "" "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.12.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -101,18 +102,16 @@ msgid "Default" msgstr "Predefinito" #: doc/tools/make_rst.py -#, fuzzy msgid "Setter" -msgstr "Impostatore" +msgstr "Setter" #: doc/tools/make_rst.py msgid "value" msgstr "valore" #: doc/tools/make_rst.py -#, fuzzy msgid "Getter" -msgstr "Acchiappatore" +msgstr "Getter" #: doc/tools/make_rst.py msgid "" @@ -137,9 +136,8 @@ msgstr "" "qui." #: doc/tools/make_rst.py -#, fuzzy msgid "This method is used to construct a type." -msgstr "Questo metodo viene utilizzato per creare un tipo di variabile." +msgstr "Questo metodo viene utilizzato per creare un tipo." #: doc/tools/make_rst.py msgid "" @@ -1372,10 +1370,22 @@ msgstr "" "messaggi di debug ed errore che vengono mostrati con la stack trace." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Come [method print], ma stampa solo quando viene utilizzato in modalità " -"debug." +"Stampa un stack trace nella posizione del codice, funziona solo quando il " +"debugger è attivato.\n" +"L'output nella console apparirà come:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8702,8 +8712,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12783,7 +12793,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -21303,7 +21318,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24703,7 +24718,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -26543,7 +26558,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33683,7 +33698,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33699,7 +33714,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33732,7 +33747,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37884,7 +37899,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -38148,7 +38163,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -38267,6 +38282,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40972,7 +41033,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40984,7 +41051,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58807,7 +58875,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61723,8 +61791,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -65387,13 +65455,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -65405,13 +65474,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -72367,11 +72437,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"Se [code] vero [/code], i nodi figli sono ordinati, altrimenti l'ordinamento " -"è disabilitato." #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -72455,6 +72526,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ja.po b/doc/translations/ja.po index 324df4d9ae..fe76c741d0 100644 --- a/doc/translations/ja.po +++ b/doc/translations/ja.po @@ -1333,8 +1333,22 @@ msgstr "" "ãŸã¨ãã«ã‚¹ã‚¿ãƒƒã‚¯ãƒˆãƒ¬ãƒ¼ã‚¹ã‚’表示ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "[method print] ã¨åŒæ§˜ã§ã™ãŒã€ã—ã‹ã—デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰æ™‚ã«ã®ã¿è¡¨ç¤ºã—ã¾ã™ã€‚" +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" +"コードä½ç½®ã®ã‚¹ã‚¿ãƒƒã‚¯ãƒˆãƒ©ãƒƒã‚¯ã‚’表示ã—ã¾ã™ã€‚デãƒãƒƒã‚¬ã‚’有効ã«ã—ã¦å®Ÿè¡Œã—ãŸæ™‚ã«ã®" +"ã¿å‹•作ã—ã¾ã™ã€‚\n" +"コンソール内ã§ã®å‡ºåŠ›ã¯ã“ã®ã‚ˆã†ã«ãªã‚Šã¾ã™:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -9918,8 +9932,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -14717,7 +14731,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -23302,7 +23321,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -26725,7 +26744,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -28567,7 +28586,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -35779,7 +35798,7 @@ msgstr "円柱ã®é«˜ã•。" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -35795,7 +35814,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -35831,7 +35850,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -40028,7 +40047,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -40295,7 +40314,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -40416,6 +40435,53 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "指定ã•れãŸåå‰ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãƒŽãƒ¼ãƒ‰ã‚’è¿”ã—ã¾ã™ã€‚" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -43124,7 +43190,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -43136,7 +43208,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -61336,7 +61409,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -64289,8 +64362,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -67983,13 +68056,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -68001,13 +68075,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -75036,9 +75111,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "[code]true[/code]ã®å ´åˆã€é ‚点色をアルベド色ã¨ã—ã¦ä½¿ç”¨ã—ã¾ã™ã€‚" +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -75122,6 +75200,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ko.po b/doc/translations/ko.po index 2f6879593c..ac9274cee6 100644 --- a/doc/translations/ko.po +++ b/doc/translations/ko.po @@ -1004,7 +1004,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7859,8 +7866,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11931,7 +11938,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20452,7 +20464,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23844,7 +23856,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25682,7 +25694,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32792,7 +32804,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32808,7 +32820,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32838,7 +32850,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36972,7 +36984,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37235,7 +37247,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37353,6 +37365,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40176,7 +40234,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40188,7 +40252,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57973,7 +58038,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60874,8 +60939,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64507,13 +64572,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64525,13 +64591,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71452,7 +71519,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71537,6 +71608,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/lt.po b/doc/translations/lt.po index 2468d389d3..79790f5e70 100644 --- a/doc/translations/lt.po +++ b/doc/translations/lt.po @@ -857,7 +857,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7694,8 +7701,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11763,7 +11770,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20174,7 +20186,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23560,7 +23572,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25391,7 +25403,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32487,7 +32499,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32503,7 +32515,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32533,7 +32545,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36633,7 +36645,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36894,7 +36906,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37008,6 +37020,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39705,7 +39763,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39717,7 +39781,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57471,7 +57536,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60362,8 +60427,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63986,13 +64051,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64004,13 +64070,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70896,7 +70963,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70981,6 +71052,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/lv.po b/doc/translations/lv.po index 9faf7fd017..1f63bf69bb 100644 --- a/doc/translations/lv.po +++ b/doc/translations/lv.po @@ -862,7 +862,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7699,8 +7706,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11768,7 +11775,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20179,7 +20191,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23568,7 +23580,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25399,7 +25411,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32495,7 +32507,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32511,7 +32523,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32541,7 +32553,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36641,7 +36653,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36902,7 +36914,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37016,6 +37028,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39713,7 +39771,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39725,7 +39789,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57479,7 +57544,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60370,8 +60435,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63994,13 +64059,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64012,13 +64078,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70904,7 +70971,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70989,6 +71060,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/mr.po b/doc/translations/mr.po index c989fcc549..32832a4d8f 100644 --- a/doc/translations/mr.po +++ b/doc/translations/mr.po @@ -845,7 +845,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7682,8 +7689,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11751,7 +11758,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20162,7 +20174,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23548,7 +23560,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25379,7 +25391,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32475,7 +32487,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32491,7 +32503,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32521,7 +32533,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36621,7 +36633,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36882,7 +36894,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36996,6 +37008,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39693,7 +39751,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39705,7 +39769,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57459,7 +57524,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60350,8 +60415,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63974,13 +64039,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63992,13 +64058,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70884,7 +70951,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70969,6 +71040,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/nb.po b/doc/translations/nb.po index 8017f4006b..42dca83c45 100644 --- a/doc/translations/nb.po +++ b/doc/translations/nb.po @@ -857,7 +857,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7694,8 +7701,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11763,7 +11770,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20174,7 +20186,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23560,7 +23572,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25391,7 +25403,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32487,7 +32499,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32503,7 +32515,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32533,7 +32545,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36633,7 +36645,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36894,7 +36906,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37008,6 +37020,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39705,7 +39763,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39717,7 +39781,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57471,7 +57536,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60362,8 +60427,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63986,13 +64051,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64004,13 +64070,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70896,7 +70963,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70981,6 +71052,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ne.po b/doc/translations/ne.po index 9a17a51fb6..0ba02ba939 100644 --- a/doc/translations/ne.po +++ b/doc/translations/ne.po @@ -845,7 +845,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7682,8 +7689,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11751,7 +11758,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20162,7 +20174,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23548,7 +23560,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25379,7 +25391,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32475,7 +32487,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32491,7 +32503,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32521,7 +32533,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36621,7 +36633,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36882,7 +36894,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36996,6 +37008,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39693,7 +39751,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39705,7 +39769,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57459,7 +57524,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60350,8 +60415,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63974,13 +64039,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63992,13 +64058,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70884,7 +70951,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70969,6 +71040,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/nl.po b/doc/translations/nl.po index d36175b6c2..3053cadb2b 100644 --- a/doc/translations/nl.po +++ b/doc/translations/nl.po @@ -906,7 +906,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7751,8 +7758,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11820,7 +11827,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20231,7 +20243,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23620,7 +23632,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25451,7 +25463,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32547,7 +32559,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32563,7 +32575,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32593,7 +32605,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36693,7 +36705,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36954,7 +36966,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37068,6 +37080,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39765,7 +39823,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39777,7 +39841,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57532,7 +57597,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60423,8 +60488,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64047,13 +64112,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64065,13 +64131,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70957,7 +71024,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71042,6 +71113,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/pl.po b/doc/translations/pl.po index 343dfb0050..729b6a654c 100644 --- a/doc/translations/pl.po +++ b/doc/translations/pl.po @@ -1279,8 +1279,22 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "Jak [method print], ale wypisuje tylko w trybie debugowania." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" +"Wypisuje zrzut stosu w miejscu kodu, dziaÅ‚a tylko przy uruchamianiu z " +"włączonym debuggerem.\n" +"Wynik w konsoli wyglÄ…dać może tak:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8189,8 +8203,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12262,7 +12276,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20703,7 +20722,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24102,7 +24121,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25939,7 +25958,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33076,7 +33095,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33092,7 +33111,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33125,7 +33144,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37281,7 +37300,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37545,7 +37564,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37664,6 +37683,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40361,7 +40426,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40373,7 +40444,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58195,7 +58267,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61097,8 +61169,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64744,13 +64816,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64762,13 +64835,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71696,11 +71770,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"JeÅ›li [code]true[/code], potomne wÄ™zÅ‚y sÄ… sortowane. W innym przypadku jest " -"wyłączone." #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -71784,6 +71859,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/pt.po b/doc/translations/pt.po index fdb01b1579..c99a8e1cd6 100644 --- a/doc/translations/pt.po +++ b/doc/translations/pt.po @@ -1340,9 +1340,22 @@ msgstr "" "rastreamento de pilha quando um erro ou aviso é impresso ." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Igual [method print], mas só imprime quando usado em modo de depuração." +"Imprime a pilha de chamadas no local do código, só funciona com o depurador " +"ativado.\n" +"SaÃda no console vai parecer assim:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8506,8 +8519,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12580,7 +12593,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -21038,7 +21056,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24434,7 +24452,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -26271,7 +26289,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33383,7 +33401,7 @@ msgstr "A altura do cilindro." msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33399,7 +33417,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33430,7 +33448,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37559,7 +37577,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37824,7 +37842,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37942,6 +37960,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40639,7 +40703,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40651,7 +40721,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58499,7 +58570,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61396,8 +61467,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -65035,13 +65106,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -65053,13 +65125,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71954,7 +72027,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -72039,6 +72116,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/pt_BR.po b/doc/translations/pt_BR.po index 50d4359c46..74758850c7 100644 --- a/doc/translations/pt_BR.po +++ b/doc/translations/pt_BR.po @@ -1368,9 +1368,22 @@ msgstr "" "rastreamento de pilha quando um erro ou aviso é impresso ." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"Igual [method print], mas só imprime quando usado em modo de depuração." +"Imprime a pilha de chamadas no local do código, só funciona com o depurador " +"habilitado.\n" +"SaÃda no console vai parecer assim:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8742,8 +8755,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12820,7 +12833,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -21332,7 +21350,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24735,7 +24753,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -26574,7 +26592,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33720,7 +33738,7 @@ msgstr "A altura do cilindro." msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33736,7 +33754,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33769,7 +33787,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37925,7 +37943,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -38191,7 +38209,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -38310,6 +38328,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -41007,7 +41071,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -41019,7 +41089,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58868,7 +58939,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61780,8 +61851,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -65433,13 +65504,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -65451,13 +65523,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -72389,11 +72462,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"Se [code]true[/code], os nós filhos são organizados, do contrário, a " -"organização é desabilitada." #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -72477,6 +72551,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ro.po b/doc/translations/ro.po index 8c7112f102..332dbd0801 100644 --- a/doc/translations/ro.po +++ b/doc/translations/ro.po @@ -873,7 +873,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7714,8 +7721,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11783,7 +11790,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20194,7 +20206,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23583,7 +23595,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25414,7 +25426,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32510,7 +32522,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32526,7 +32538,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32556,7 +32568,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36656,7 +36668,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36917,7 +36929,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37032,6 +37044,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39729,7 +39787,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39741,7 +39805,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57495,7 +57560,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60386,8 +60451,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64010,13 +64075,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64028,13 +64094,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70920,7 +70987,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71005,6 +71076,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/ru.po b/doc/translations/ru.po index 1596ca8553..985198198a 100644 --- a/doc/translations/ru.po +++ b/doc/translations/ru.po @@ -1402,8 +1402,21 @@ msgstr "" "траÑÑировка Ñтека при печати ошибки или предупреждениÑ." #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "Как [method print], но печатает только в режиме отладки." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" +"Печатает трек Ñтека вызовов, работает только еÑли включён отладчик.\n" +"Вывод в конÑоли будет выглÑдеть примерно так:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -9352,8 +9365,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -13447,7 +13460,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -22008,7 +22026,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -25419,7 +25437,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -27259,7 +27277,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -34416,7 +34434,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -34432,7 +34450,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -34465,7 +34483,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -38625,7 +38643,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -38890,7 +38908,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -39022,6 +39040,53 @@ msgstr "" msgid "Control activation of this server." msgstr "Управление активацией данного Ñервера." +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "Возвращает длину вектора." + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml #, fuzzy msgid "" @@ -41794,7 +41859,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -41806,7 +41877,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -59734,7 +59806,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -62675,8 +62747,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -66352,15 +66424,16 @@ msgstr "" #: doc/classes/TreeItem.xml #, fuzzy msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" "Возвращает поÑледний Ñлемент маÑÑива, или[code]null[/code] еÑли маÑÑив " "пуÑтой." #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -66373,15 +66446,16 @@ msgstr "" #: doc/classes/TreeItem.xml #, fuzzy msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" "Возвращает первый Ñлемент в маÑÑиве, или [code]null[/code] еÑли маÑÑив " "пуÑтой." #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -73453,9 +73527,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "ЕÑли [code]true[/code], текÑтура будет центрирована." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -73539,6 +73616,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/sk.po b/doc/translations/sk.po index 38e701eef9..ddcdeb10f1 100644 --- a/doc/translations/sk.po +++ b/doc/translations/sk.po @@ -848,7 +848,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7685,8 +7692,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11754,7 +11761,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20165,7 +20177,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23554,7 +23566,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25385,7 +25397,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32481,7 +32493,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32497,7 +32509,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32527,7 +32539,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36627,7 +36639,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36888,7 +36900,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37002,6 +37014,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39699,7 +39757,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39711,7 +39775,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57465,7 +57530,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60356,8 +60421,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63980,13 +64045,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63998,13 +64064,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70890,7 +70957,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70975,6 +71046,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/sr_Cyrl.po b/doc/translations/sr_Cyrl.po index 3984d209f4..6a336f195b 100644 --- a/doc/translations/sr_Cyrl.po +++ b/doc/translations/sr_Cyrl.po @@ -859,7 +859,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7696,8 +7703,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11765,7 +11772,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20176,7 +20188,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23565,7 +23577,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25396,7 +25408,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32492,7 +32504,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32508,7 +32520,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32538,7 +32550,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36638,7 +36650,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36899,7 +36911,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37013,6 +37025,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39710,7 +39768,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39722,7 +39786,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57476,7 +57541,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60367,8 +60432,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63991,13 +64056,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64009,13 +64075,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70901,7 +70968,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70986,6 +71057,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/sv.po b/doc/translations/sv.po index 9be24493d7..b582952401 100644 --- a/doc/translations/sv.po +++ b/doc/translations/sv.po @@ -6,12 +6,13 @@ # Christoffer Sundbom <christoffer_karlsson@live.se>, 2021. # Kent Jofur <kent.jofur@gmail.com>, 2021. # Alex25820 <alexs25820@gmail.com>, 2021. +# Björn Ã…kesson <bjorn.akesson@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-12-19 17:31+0000\n" -"Last-Translator: Alex25820 <alexs25820@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" +"Last-Translator: Björn Ã…kesson <bjorn.akesson@gmail.com>\n" "Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/sv/>\n" "Language: sv\n" @@ -19,7 +20,7 @@ msgstr "" "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.10\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -92,7 +93,7 @@ msgstr "" #: doc/tools/make_rst.py msgid "Getter" -msgstr "" +msgstr "Getter" #: doc/tools/make_rst.py msgid "" @@ -848,7 +849,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7685,8 +7693,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11754,7 +11762,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20165,7 +20178,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23551,7 +23564,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25382,7 +25395,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32478,7 +32491,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32494,7 +32507,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32524,7 +32537,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36624,7 +36637,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36885,7 +36898,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -36999,6 +37012,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -37553,7 +37612,7 @@ msgstr "" #: doc/classes/Node.xml msgid "Nodes and Scenes" -msgstr "" +msgstr "Noder och scener" #: doc/classes/Node.xml msgid "All Demos" @@ -39696,7 +39755,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39708,7 +39773,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57462,7 +57528,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60353,8 +60419,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -63977,13 +64043,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -63995,13 +64062,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -70887,7 +70955,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -70972,6 +71044,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/th.po b/doc/translations/th.po index dabf3c09f3..3b8c2afd36 100644 --- a/doc/translations/th.po +++ b/doc/translations/th.po @@ -933,7 +933,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7790,8 +7797,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11860,7 +11867,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20275,7 +20287,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23665,7 +23677,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25500,7 +25512,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32650,7 +32662,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32666,7 +32678,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32696,7 +32708,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36813,7 +36825,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37074,7 +37086,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37191,6 +37203,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39938,7 +39996,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39950,7 +40014,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57724,7 +57789,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60621,8 +60686,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64246,13 +64311,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64264,13 +64330,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71172,7 +71239,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71257,6 +71328,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/tl.po b/doc/translations/tl.po index b100d0e612..6fe51a2de6 100644 --- a/doc/translations/tl.po +++ b/doc/translations/tl.po @@ -924,7 +924,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7761,8 +7768,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11834,7 +11841,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20248,7 +20260,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23640,7 +23652,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25471,7 +25483,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32573,7 +32585,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32589,7 +32601,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32622,7 +32634,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36737,7 +36749,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -36998,7 +37010,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37112,6 +37124,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39809,7 +39867,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39821,7 +39885,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57578,7 +57643,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60469,8 +60534,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64102,13 +64167,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64120,13 +64186,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71015,7 +71082,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71100,6 +71171,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/tr.po b/doc/translations/tr.po index dc9d2524b7..ffa15621df 100644 --- a/doc/translations/tr.po +++ b/doc/translations/tr.po @@ -20,12 +20,13 @@ # Ramazan Aslan <legendraslan@gmail.com>, 2022. # paledega <paledega@yandex.ru>, 2022. # Yekez <yasintonge@gmail.com>, 2022. +# Deleted User <noreply+46858@weblate.org>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-07-03 00:45+0000\n" -"Last-Translator: Yekez <yasintonge@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:56+0000\n" +"Last-Translator: Deleted User <noreply+46858@weblate.org>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot-class-reference/tr/>\n" "Language: tr\n" @@ -33,7 +34,7 @@ msgstr "" "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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: doc/tools/make_rst.py msgid "Description" @@ -96,7 +97,6 @@ msgid "Default" msgstr "Varsayılan" #: doc/tools/make_rst.py -#, fuzzy msgid "Setter" msgstr "Ayarlayıcı" @@ -105,7 +105,6 @@ msgid "value" msgstr "deÄŸer" #: doc/tools/make_rst.py -#, fuzzy msgid "Getter" msgstr "Alıcı" @@ -1315,10 +1314,22 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" -"[method print] yöntemi gibidir fakat yanlız hata ayıklama (debug) modunda " -"kullanılır." +"Kod içindeki istiflenme konumunu yazdırır ve yanlızca hata ayıklayıcı " +"(debugger) açıkken çalışır.\n" +"Konsoldaki çıktı aÅŸağıdaki gibi bir ÅŸey olacaktır.\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8471,8 +8482,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12543,7 +12554,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20978,7 +20994,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24374,7 +24390,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -26215,7 +26231,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -33330,7 +33346,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33346,7 +33362,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33378,7 +33394,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37520,7 +37536,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37784,7 +37800,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37903,6 +37919,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40600,7 +40662,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40612,7 +40680,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58417,7 +58486,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -61318,8 +61387,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64955,13 +65024,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64973,13 +65043,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71895,10 +71966,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" -"EÄŸer [code]true[/code] ise düğümler sıraya sokulur, yoksa sıraya sokulmaz." #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -71982,6 +72055,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/uk.po b/doc/translations/uk.po index afedf189b4..b1272c6b3e 100644 --- a/doc/translations/uk.po +++ b/doc/translations/uk.po @@ -991,7 +991,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7843,8 +7850,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11916,7 +11923,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20344,7 +20356,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23733,7 +23745,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25570,7 +25582,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32680,7 +32692,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32696,7 +32708,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32726,7 +32738,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36863,7 +36875,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37126,7 +37138,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37244,6 +37256,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39941,7 +39999,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39953,7 +40017,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57742,7 +57807,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60644,8 +60709,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64279,13 +64344,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64297,13 +64363,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71215,7 +71282,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71300,6 +71371,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/vi.po b/doc/translations/vi.po index ab16aa1782..60ab8769ab 100644 --- a/doc/translations/vi.po +++ b/doc/translations/vi.po @@ -1202,8 +1202,15 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "Giống [method print], nhưng chỉ in khi sá» dụng trong chế độ gỡ lá»—i." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -8138,8 +8145,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12211,7 +12218,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20643,7 +20655,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -24035,7 +24047,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25872,7 +25884,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32980,7 +32992,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32996,7 +33008,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -33027,7 +33039,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -37165,7 +37177,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37429,7 +37441,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37548,6 +37560,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -40245,7 +40303,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -40257,7 +40321,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -58065,7 +58130,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60966,8 +61031,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64603,13 +64668,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64621,13 +64687,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71550,9 +71617,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -#, fuzzy -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "Nếu [code]true[/code], há»a tiết sẽ được căn ở trung tâm." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -71636,6 +71706,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/doc/translations/zh_CN.po b/doc/translations/zh_CN.po index d2179a01f2..76ea804df5 100644 --- a/doc/translations/zh_CN.po +++ b/doc/translations/zh_CN.po @@ -62,7 +62,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-07-17 07:14+0000\n" +"PO-Revision-Date: 2022-07-26 01:54+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot-class-reference/zh_Hans/>\n" @@ -645,7 +645,7 @@ msgstr "" "a = floor(2.99) # a = 2.0\n" "a = floor(-2.99) # a = -3.0\n" "[/codeblock]\n" -"请å‚阅 [method ceil]ã€[method round]ã€[method stepify] å’Œ [int]。\n" +"å¦è¯·å‚阅 [method ceil]ã€[method round]ã€[method stepify] å’Œ [int]。\n" "[b]注æ„:[/b]è¯¥æ–¹æ³•è¿”å›žä¸€ä¸ªæµ®ç‚¹æ•°ã€‚å¦‚æžœä½ éœ€è¦æ•´æ•°ï¼Œè€Œ [code]s[/code] 是éžè´Ÿ" "æ•°ï¼Œä½ å¯ä»¥ç›´æŽ¥ä½¿ç”¨ [code]int(s)[/code]。" @@ -1322,8 +1322,21 @@ msgstr "" "在打å°é”™è¯¯æˆ–è¦å‘Šæ—¶è¿˜ä¼šæ˜¾ç¤ºå †æ ˆè·Ÿè¸ªã€‚" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." -msgstr "与 [method print] 类似,但仅在调试模å¼ä¸‹ä½¿ç”¨æ—¶æ‰æ‰“å°ã€‚" +#, fuzzy +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" +msgstr "" +"在代ç ä½ç½®æ‰“å°å †æ ˆè½¨è¿¹ï¼Œä»…在打开调试器的情况下è¿è¡Œã€‚\n" +"控制å°ä¸çš„输出如下所示:\n" +"[codeblock]\n" +"Frame 0 - res://test.gd:16 in function '_process'\n" +"[/codeblock]" #: modules/gdscript/doc_classes/@GDScript.xml msgid "" @@ -9568,10 +9581,11 @@ msgstr "" "åˆ¶å™¨ä¹Ÿå°†ä¿æŒç›¸åŒçš„ ID。" #: doc/classes/ARVRController.xml +#, fuzzy msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -12380,6 +12394,10 @@ msgid "" "name can't be resolved at runtime, it will fall back to [code]\"Master\"[/" "code]." msgstr "" +"è¿™ä¸ªéŸ³é¢‘åœ¨å“ªä¸ªæ€»çº¿ä¸Šæ’æ”¾ã€‚\n" +"[b]注æ„:[/b]设置这个属性时,请记ä½å®ƒå¹¶ä¸ä¼šå¯¹ç»™å®šçš„å称是å¦ä¸ŽçŽ°æœ‰æ€»çº¿åŒ¹é…进行" +"æ ¡éªŒã€‚è¿™æ˜¯å› ä¸ºéŸ³é¢‘æ€»çº¿å¸ƒå±€å¯ä»¥åœ¨è®¾ç½®è¿™ä¸ªå±žæ€§åŽå†åŠ è½½ã€‚å¦‚æžœè¿™ä¸ªç»™å®šçš„å称在è¿" +"è¡Œæ—¶æ— æ³•è§£æžï¼Œå°±ä¼šå›žé€€åˆ° [code]\"Master\"[/code]。" #: doc/classes/AudioStreamPlayer.xml msgid "" @@ -12580,6 +12598,10 @@ msgid "" "name can't be resolved at runtime, it will fall back to [code]\"Master\"[/" "code]." msgstr "" +"æ’æ”¾éŸ³é¢‘的总线。\n" +"[b]注æ„:[/b]设置这个属性时,请记ä½å®ƒå¹¶ä¸ä¼šå¯¹ç»™å®šçš„å称是å¦ä¸ŽçŽ°æœ‰æ€»çº¿åŒ¹é…进行" +"æ ¡éªŒã€‚è¿™æ˜¯å› ä¸ºéŸ³é¢‘æ€»çº¿å¸ƒå±€å¯ä»¥åœ¨è®¾ç½®è¿™ä¸ªå±žæ€§åŽå†åŠ è½½ã€‚å¦‚æžœè¿™ä¸ªç»™å®šçš„å称在è¿" +"è¡Œæ—¶æ— æ³•è§£æžï¼Œå°±ä¼šå›žé€€åˆ° [code]\"Master\"[/code]。" #: doc/classes/AudioStreamPlayer3D.xml msgid "" @@ -14560,9 +14582,13 @@ msgstr "æè¿°æ¤ç›¸æœºæ¸²æŸ“哪些 3D 渲染层的剔除掩ç 。" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" -"如果为 [code]true[/code],则说明祖级的 [Viewport] 当剿£åœ¨ä½¿ç”¨è¿™ä¸ªæ‘„åƒå¤´ã€‚" #: doc/classes/Camera.xml msgid "" @@ -25230,10 +25256,11 @@ msgstr "" "文件管ç†å™¨çš„[b]Export[/b]按钮或[method save_to_file]方法获得。" #: doc/classes/EditorFeatureProfile.xml +#, fuzzy msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" "将编辑器的功能é…ç½®ä¿å˜åˆ°JSONæ ¼å¼çš„æ–‡ä»¶ä¸ã€‚ç„¶åŽå¯ä»¥ä½¿ç”¨ç‰¹å¾é…置文件管ç†å™¨çš„[b]" "导入[/b]按钮或[method load_from_file]按钮导入它。" @@ -29651,9 +29678,10 @@ msgid "The default exposure used for tonemapping." msgstr "ç”¨äºŽè‰²è°ƒæ˜ å°„çš„é»˜è®¤æ›å…‰ã€‚" #: doc/classes/Environment.xml +#, fuzzy msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" "è¦ä½¿ç”¨çš„è‰²è°ƒæ˜ å°„æ¨¡å¼ã€‚è‰²è°ƒæ˜ å°„æ˜¯â€œè½¬æ¢â€HDR 值以适åˆåœ¨ LDR 显示器上呈现的过程。" @@ -31930,9 +31958,10 @@ msgstr "" "[b]注æ„:[/b]直线是使用方å‘å‘é‡è€Œä¸æ˜¯ç»ˆç‚¹æŒ‡å®šçš„。" #: doc/classes/Geometry.xml +#, fuzzy msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -35784,7 +35813,6 @@ msgid "" msgstr "å…许的最大é‡å®šå‘æ•°ã€‚ç”¨äºŽé˜²æ¢æ— é™é‡å®šå‘循环。" #: doc/classes/HTTPRequest.xml -#, fuzzy msgid "" "If set to a value greater than [code]0.0[/code] before the request starts, " "the HTTP request will time out after [code]timeout[/code] seconds have " @@ -35795,11 +35823,11 @@ msgid "" "leave this to [code]0.0[/code] to prevent the download from failing if it " "takes too much time." msgstr "" -"如果设为大于 [code]0.0[/code] 的值,在ç»è¿‡ [code]timeout[/code] ç§’ä»æœª[i]完æˆ" -"[/i]请求时,该 HTTP 请求就会超时。对于 REST API ç‰è¾ƒå°çš„ HTTP 请求,将 " -"[member timeout] 设为大于 [code]0.0[/code] 的值å¯ä»¥å®šæ—¶é˜²æ¢åº”用程åºåœ¨å¤±è´¥æ—¶é™·" -"å…¥é•¿æ—¶é—´çš„æ— å“应状æ€ã€‚ä¸‹è½½æ–‡ä»¶æ—¶è¯·ä¿æŒ [code]0.0[/code],防æ¢åœ¨éœ€è¦èŠ±è´¹è¾ƒé•¿æ—¶" -"间下载时导致下载失败。" +"如果在请求开始å‰è®¾ä¸ºå¤§äºŽ [code]0.0[/code] 的值,在ç»è¿‡ [code]timeout[/code] " +"ç§’ä»æœª[i]完æˆ[/i]请求时,该 HTTP 请求就会超时。对于 REST API ç‰è¾ƒå°çš„ HTTP 请" +"求,将 [member timeout] 设为 [code]10.0[/code] 到 [code]30.0[/code] 之间的值" +"å¯ä»¥å®šæ—¶é˜²æ¢åº”用程åºåœ¨å¤±è´¥æ—¶é™·å…¥é•¿æ—¶é—´çš„æ— å“应状æ€ã€‚ä¸‹è½½æ–‡ä»¶æ—¶è¯·ä¿æŒ " +"[code]0.0[/code],防æ¢åœ¨éœ€è¦èŠ±è´¹è¾ƒé•¿æ—¶é—´ä¸‹è½½æ—¶å¯¼è‡´ä¸‹è½½å¤±è´¥ã€‚" #: doc/classes/HTTPRequest.xml msgid "If [code]true[/code], multithreading is used to improve performance." @@ -37641,7 +37669,6 @@ msgid "Controls the mouse mode. See [enum MouseMode] for more information." msgstr "æŽ§åˆ¶é¼ æ ‡æ¨¡å¼ã€‚详情请å‚阅 [enum MouseMode]。" #: doc/classes/Input.xml -#, fuzzy msgid "" "If [code]true[/code], similar input events sent by the operating system are " "accumulated. When input accumulation is enabled, all input events generated " @@ -37663,8 +37690,8 @@ msgstr "" "输入累积在默认情况下是å¯ç”¨çš„。它å¯ä»¥è¢«ç¦ç”¨ï¼Œå°†ä»¥å¢žåŠ CPU使用率为代价,获得ç¨å¾®" "æ›´ç²¾ç¡®åŠæ›´çµæ•的输入。在需è¦è‡ªç”±ç»˜åˆ¶çº¿æ¡çš„应用ä¸ï¼Œä¸€èˆ¬åº”ç”¨åœ¨ç”¨æˆ·ç»˜åˆ¶çº¿æ¡æ—¶ç¦" "ç”¨è¾“å…¥ç´¯åŠ ï¼Œä»¥èŽ·å¾—ç´§è·Ÿå®žé™…è¾“å…¥çš„ç»“æžœã€‚\n" -"[b]注æ„:[/b]默认[i]ç¦ç”¨[/i]输入累积是出于å‘åŽå…¼å®¹çš„缘故。然而我们推è那些ä¸" -"需è¦éžå¸¸æ´»è·ƒè¾“入的游æˆå°†å…¶å¯ç”¨ï¼Œèƒ½å¤Ÿé™ä½Ž CPU å 用。" +"[b]注æ„:[/b]输入累积是默认[i]å¯ç”¨[/i]的。推è那些ä¸éœ€è¦éžå¸¸æ´»è·ƒè¾“入的游æˆä¿" +"æŒå¯ç”¨ï¼Œèƒ½å¤Ÿé™ä½Ž CPU å 用。" #: doc/classes/Input.xml msgid "Emitted when a joypad device has been connected or disconnected." @@ -38390,7 +38417,6 @@ msgid "Input event type for mouse motion events." msgstr "é¼ æ ‡ç§»åŠ¨äº‹ä»¶çš„è¾“å…¥äº‹ä»¶ç±»åž‹ã€‚" #: doc/classes/InputEventMouseMotion.xml -#, fuzzy msgid "" "Contains mouse and pen motion information. Supports relative, absolute " "positions and speed. See [method Node._input].\n" @@ -38407,9 +38433,11 @@ msgid "" "avoid visible gaps in lines if the user is moving the mouse quickly." msgstr "" "包å«é¼ æ ‡å’Œç¬”çš„è¿åŠ¨ä¿¡æ¯ã€‚支æŒç›¸å¯¹ã€ç»å¯¹ä½ç½®å’Œé€Ÿåº¦ã€‚è§ [method Node._input]。\n" -"[b]注æ„:[/b]默认情况下,这个事件能够æ¯å¸§å‘出多次,æä¾›æ›´ç²¾ç¡®çš„输入报告,但代" -"价是更高的 CPU å ç”¨ã€‚ä½ å¯ä»¥å°† [member Input.use_accumulated_input] 设为 " -"[code]true[/code],将æ¯å¸§ä¸çš„多个事件åˆå¹¶ä¸ºå•个事件进行å‘é€ã€‚\n" +"[b]注æ„:[/b]è¿™ä¸ªäº‹ä»¶çš„è¡Œä¸ºå— [member Input.use_accumulated_input] å–值的影" +"å“。设为 [code]true[/code] 时(默认),从æ“作系统获å–åˆ°çš„é¼ æ ‡/笔的移动事件会" +"被åˆå¹¶ï¼Œæ¯ä¸ªæ¸²æŸ“帧最多åªä¼šå‘出一个累积事件。设为 [code]false[/code] 时,收到" +"å‡ ä¸ªäº‹ä»¶å°±ä¼šå‘å‡ºå‡ ä¸ªäº‹ä»¶ï¼Œå³æ¯ä¸ªæ¸²æŸ“帧å¯èƒ½å‘出多次,能够精确地汇报输入,但代" +"价是å 用 CPU。\n" "[b]注æ„:[/b]å¦‚æžœä½ ä½¿ç”¨ InputEventMouseMotion æ¥ç”»çº¿ï¼Œè¯·è€ƒè™‘åŒæ—¶å®žçް" "[url=https://zh.wikipedia.org/zh-cn/" "%E5%B8%83%E9%9B%B7%E6%A3%AE%E6%BC%A2%E5%A7%86%E7%9B%B4%E7%B7%9A%E6%BC%94%E7%AE%97%E6%B3%95]" @@ -38420,13 +38448,12 @@ msgid "Mouse and input coordinates" msgstr "é¼ æ ‡å’Œè¾“å…¥åæ ‡" #: doc/classes/InputEventMouseMotion.xml -#, fuzzy msgid "" "Returns [code]true[/code] when using the eraser end of a stylus pen.\n" "[b]Note:[/b] This property is implemented on Linux, macOS and Windows." msgstr "" -"返回键盘布局的数é‡ã€‚\n" -"[b]注æ„:[/b]本方法在Linuxã€macOSå’ŒWindows上实现。" +"使用手写笔的橡皮端时,返回 [code]true[/code]。\n" +"[b]注æ„:[/b]这个属性在 Linuxã€macOS å’Œ Windows 上实现。" #: doc/classes/InputEventMouseMotion.xml msgid "" @@ -40989,10 +41016,11 @@ msgid "The tint of [Font]'s outline." msgstr "对 [Font] 轮廓的染色。" #: doc/classes/Label3D.xml +#, fuzzy msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -41010,10 +41038,11 @@ msgid "The size of one pixel's width on the label to scale it in 3D." msgstr "æ ‡ç¾ä¸Šä¸€ä¸ªåƒç´ 宽度的大å°ï¼Œä»¥ 3D 缩放。" #: doc/classes/Label3D.xml +#, fuzzy msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -41048,8 +41077,9 @@ msgid "If set, lights in the environment affect the label." msgstr "如果打开,环境ä¸çš„ç¯å…‰ä¼šå½±å“è¯¥æ ‡ç¾ã€‚" #: doc/classes/Label3D.xml +#, fuzzy msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "如果打开,从åŽé¢ä¹Ÿå¯ä»¥çœ‹åˆ°æ–‡æœ¬ï¼Œå¦‚æžœä¸æ‰“开,从åŽé¢çœ‹å®ƒæ˜¯ä¸å¯è§çš„。" @@ -46047,6 +46077,7 @@ msgid "An instance of a [NavigationMesh]." msgstr "[NavigationMesh] 的一个实例。" #: doc/classes/NavigationMeshInstance.xml +#, fuzzy msgid "" "An instance of a [NavigationMesh]. It tells the [Navigation] node what can " "be navigated and what cannot, based on the [NavigationMesh] resource.\n" @@ -46060,7 +46091,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -46384,6 +46415,7 @@ msgid "A region of the 2D navigation map." msgstr "2D 导航地图上的一个地区。" #: doc/classes/NavigationPolygonInstance.xml +#, fuzzy msgid "" "A region of the navigation map. It tells the [Navigation2DServer] what can " "be navigated and what cannot, based on its [NavigationPolygon] resource.\n" @@ -46397,7 +46429,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -46551,6 +46583,54 @@ msgstr "" msgid "Control activation of this server." msgstr "控制这个æœåŠ¡å™¨æ˜¯å¦æ¿€æ´»ã€‚" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "返回连接的当å‰çжæ€ã€‚è§ [enum ConnectionStatus]。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +#, fuzzy +msgid "Set the max packet size that this peer can handle." +msgstr "设置该实例使用的光照图。" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -50248,8 +50328,14 @@ msgid "See [enum ShadowDetail]." msgstr "è§ [enum ShadowDetail]。" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." -msgstr "è§ [enum ShadowMode]。" +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." +msgstr "" #: doc/classes/OmniLight.xml msgid "" @@ -50259,9 +50345,11 @@ msgstr "" "é˜´å½±è¢«æ¸²æŸ“åˆ°ä¸€ä¸ªåŒæŠ›ç‰©é¢çº¹ç†ã€‚比 [constant SHADOW_CUBE] 更快,但质é‡è¾ƒå·®ã€‚" #: doc/classes/OmniLight.xml +#, fuzzy msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" "阴影被渲染æˆä¸€ä¸ªç«‹æ–¹ä½“贴图。比 [constant SHADOW_DUAL_PARABOLOID] æ…¢ï¼Œä½†è´¨é‡æ›´" "高。" @@ -57224,9 +57312,8 @@ msgstr "改å˜ç»™å®šç´¢å¼•处的å—节。" #: doc/classes/PoolIntArray.xml doc/classes/PoolRealArray.xml #: doc/classes/PoolStringArray.xml doc/classes/PoolVector2Array.xml #: doc/classes/PoolVector3Array.xml -#, fuzzy msgid "Sorts the elements of the array in ascending order." -msgstr "从数组ä¸åˆ 除ä½äºŽç´¢å¼•çš„å…ƒç´ ã€‚" +msgstr "将该数组ä¸çš„å…ƒç´ æŒ‰å‡åºæŽ’列。" #: doc/classes/PoolByteArray.xml msgid "" @@ -63789,14 +63876,14 @@ msgid "" "Generates a pseudo-random float between [code]0.0[/code] and [code]1.0[/" "code] (inclusive)." msgstr "" -"产生一个[code]0.0[/code]å’Œ[code]1.0[/code]ï¼ˆåŒ…æ‹¬ç«¯ç‚¹ï¼‰ä¹‹é—´çš„ä¼ªéšæœºæµ®ç‚¹æ•°ã€‚" +"生æˆä¸€ä¸ª[code]0.0[/code]å’Œ[code]1.0[/code]ï¼ˆåŒ…æ‹¬ç«¯ç‚¹ï¼‰ä¹‹é—´çš„ä¼ªéšæœºæµ®ç‚¹æ•°ã€‚" #: doc/classes/RandomNumberGenerator.xml msgid "" "Generates a pseudo-random float between [code]from[/code] and [code]to[/" "code] (inclusive)." msgstr "" -"产生一个[code]from[/code]å’Œ[code]to[/code]ï¼ˆåŒ…æ‹¬ç«¯ç‚¹ï¼‰ä¹‹é—´çš„ä¼ªéšæœºæµ®ç‚¹æ•°ã€‚" +"生æˆä¸€ä¸ª[code]from[/code]å’Œ[code]to[/code]ï¼ˆåŒ…æ‹¬ç«¯ç‚¹ï¼‰ä¹‹é—´çš„ä¼ªéšæœºæµ®ç‚¹æ•°ã€‚" #: doc/classes/RandomNumberGenerator.xml msgid "" @@ -63805,8 +63892,8 @@ msgid "" "specified [code]mean[/code] and a standard [code]deviation[/code]. This is " "also called Gaussian distribution." msgstr "" -"产生一个[url=https://en.wikipedia.org/wiki/Normal_distribution]æ£æ€åˆ†å¸ƒ[/url]" -"çš„ä¼ªéšæœºæ•°ï¼Œä½¿ç”¨Box-Mullerå˜æ¢ï¼Œå…·æœ‰æŒ‡å®šçš„[code]mean[/code]å’Œæ ‡å‡†" +"生æˆä¸€ä¸ª[url=https://en.wikipedia.org/wiki/Normal_distribution]æ£æ€åˆ†å¸ƒ[/url]" +"çš„ä¼ªéšæœºæ•°ï¼Œä½¿ç”¨ Box-Muller å˜æ¢ï¼Œå…·æœ‰æŒ‡å®šçš„ [code]mean[/code] å’Œæ ‡å‡† " "[code]deviation[/code]。这也被称为高斯分布。" #: doc/classes/RandomNumberGenerator.xml @@ -63814,16 +63901,16 @@ msgid "" "Generates a pseudo-random 32-bit unsigned integer between [code]0[/code] and " "[code]4294967295[/code] (inclusive)." msgstr "" -"产生一个[code]0[/code]å’Œ[code]4294967295[/code](å«ç«¯ç‚¹ï¼‰ä¹‹é—´çš„ä¼ªéšæœº32使— 符" -"å·æ•´æ•°ã€‚" +"生æˆä¸€ä¸ª [code]0[/code] å’Œ [code]4294967295[/code](å«ç«¯ç‚¹ï¼‰ä¹‹é—´çš„ä¼ªéšæœº 32 " +"使— ç¬¦å·æ•´æ•°ã€‚" #: doc/classes/RandomNumberGenerator.xml msgid "" "Generates a pseudo-random 32-bit signed integer between [code]from[/code] " "and [code]to[/code] (inclusive)." msgstr "" -"产生一个[code]to[/code]å’Œ[code]from[/code](å«ç«¯ç‚¹ï¼‰ä¹‹é—´çš„ä¼ªéšæœº32使œ‰ç¬¦å·æ•´" -"数。" +"生æˆä¸€ä¸ª [code]to[/code] å’Œ [code]from[/code](å«ç«¯ç‚¹ï¼‰ä¹‹é—´çš„ä¼ªéšæœº 32 使œ‰ç¬¦" +"å·æ•´æ•°ã€‚" #: doc/classes/RandomNumberGenerator.xml msgid "Setups a time-based seed to generator." @@ -63926,20 +64013,20 @@ msgstr "使该 [Range] åœæ¢ä¸Žä»»ä½•å…¶ä»– Range 共享其æˆå‘˜å˜é‡ã€‚" #: doc/classes/Range.xml msgid "" "If [code]true[/code], [member value] may be greater than [member max_value]." -msgstr "如果为 [code]true[/code],[member value]å¯èƒ½å¤§äºŽ[member max_value]。" +msgstr "如果为 [code]true[/code],[member value] å¯èƒ½å¤§äºŽ [member max_value]。" #: doc/classes/Range.xml msgid "" "If [code]true[/code], [member value] may be less than [member min_value]." -msgstr "如果为 [code]true[/code],[member value]å¯èƒ½å°äºŽ[member min_value]。" +msgstr "如果为 [code]true[/code],[member value] å¯èƒ½å°äºŽ [member min_value]。" #: doc/classes/Range.xml msgid "" "If [code]true[/code], and [code]min_value[/code] is greater than 0, " "[code]value[/code] will be represented exponentially rather than linearly." msgstr "" -"如果为 [code]true[/code],并且[code]min_value[/code]大于0,[code]value[/code]" -"将以指数方å¼è€Œä¸æ˜¯çº¿æ€§æ–¹å¼è¡¨ç¤ºã€‚" +"如果为 [code]true[/code],并且 [code]min_value[/code] 大于 0,[code]value[/" +"code] 将以指数方å¼è€Œä¸æ˜¯çº¿æ€§æ–¹å¼è¡¨ç¤ºã€‚" #: doc/classes/Range.xml msgid "" @@ -63961,12 +64048,12 @@ msgid "" "multiplied by [code]page[/code] over the difference between [code]min_value[/" "code] and [code]max_value[/code]." msgstr "" -"页é¢å¤§å°ã€‚主è¦ç”¨äºŽ[ScrollBar]。ScrollBar的长度是它的尺寸乘以[code]page[/code]" -"超过[code]min_value[/code]å’Œ[code]max_value[/code]之间的差值。" +"页é¢å¤§å°ã€‚主è¦ç”¨äºŽ [ScrollBar]。ScrollBar 的长度是它的尺寸乘以 [code]page[/" +"code] 超过 [code]min_value[/code] å’Œ [code]max_value[/code] 之间的差值。" #: doc/classes/Range.xml msgid "The value mapped between 0 and 1." -msgstr "该值在0å’Œ1ä¹‹é—´è¿›è¡Œæ˜ å°„ã€‚" +msgstr "该值在 0 å’Œ 1 ä¹‹é—´è¿›è¡Œæ˜ å°„ã€‚" #: doc/classes/Range.xml msgid "" @@ -63982,9 +64069,9 @@ msgid "" "[code]value[/code] will first be rounded to a multiple of [code]step[/code] " "then rounded to the nearest integer." msgstr "" -"如果大于0,[code]value[/code]将总是被四èˆäº”入为[code]step[/code]çš„å€æ•°ã€‚如果" -"[code]rounded[/code]也是[code]true[/code],[code]value[/code]将首先被四èˆäº”å…¥" -"为[code]step[/code]çš„å€æ•°ï¼Œç„¶åŽèˆå…¥ä¸ºæœ€è¿‘的整数。" +"如果大于 0,[code]value[/code] 将总是被四èˆäº”入为 [code]step[/code] çš„å€æ•°ã€‚" +"如果 [code]rounded[/code] 也是 [code]true[/code],[code]value[/code] 将首先被" +"å››èˆäº”入为 [code]step[/code] çš„å€æ•°ï¼Œç„¶åŽèˆå…¥ä¸ºæœ€è¿‘的整数。" #: doc/classes/Range.xml msgid "Range's current value." @@ -63995,8 +64082,8 @@ msgid "" "Emitted when [member min_value], [member max_value], [member page], or " "[member step] change." msgstr "" -"在 [member min_value], [member max_value], [member page], 或 [member step] 改" -"å˜æ—¶é‡Šæ”¾ä¿¡å·ã€‚" +"在 [member min_value]ã€[member max_value]ã€[member page]ã€[member step] 改å˜" +"时释放信å·ã€‚" #: doc/classes/Range.xml msgid "" @@ -64039,12 +64126,12 @@ msgstr "" "以便找到沿光线路径最近的对象。\n" "RayCast å¯ä»¥å¿½ç•¥æŸäº›å¯¹è±¡ï¼Œæ–¹æ³•是通过 [code]add_exception[/code] å°†å®ƒä»¬æ·»åŠ åˆ°" "例外列表ä¸ï¼Œæˆ–者通过使用碰撞层和掩ç 设置,进行适当的过滤。\n" -"RayCast å¯ä»¥é…置为报告与 [Area]([member collide_with_areas]) å’Œ/或 " -"[PhysicsBody]([member collide_with_bodies]) 的碰撞。\n" +"RayCast å¯ä»¥é…置为报告与 [Area]([member collide_with_areas])和/或 " +"[PhysicsBody]([member collide_with_bodies])的碰撞。\n" "åªæœ‰å¯ç”¨çš„光线投射æ‰èƒ½æ£€æµ‹ç©ºé—´å¹¶æŠ¥å‘Šç¢°æ’žã€‚\n" -"RayCast 计算æ¯ä¸ªç‰©ç†å¸§çš„交集(å‚阅 [Node]),并将结果缓å˜èµ·æ¥ï¼Œä»¥ä¾¿ç¨åŽä½¿ç”¨ï¼Œ" -"直到下一帧。如果物ç†å¸§ä¹‹é—´ï¼ˆæˆ–åŒä¸€å¸§æœŸé—´ï¼‰éœ€è¦å¤šæ¬¡æ£€æµ‹ï¼Œè¯·åœ¨è°ƒæ•´å…‰çº¿æŠ•å°„åŽä½¿" -"用[method force_raycast_update]。" +"RayCast 计算æ¯ä¸ªç‰©ç†å¸§çš„äº¤é›†ï¼ˆè§ [Node]),并将结果缓å˜èµ·æ¥ï¼Œä»¥ä¾¿ç¨åŽä½¿ç”¨ï¼Œç›´" +"到下一帧。如果物ç†å¸§ä¹‹é—´ï¼ˆæˆ–åŒä¸€å¸§æœŸé—´ï¼‰éœ€è¦å¤šæ¬¡æ£€æµ‹ï¼Œè¯·åœ¨è°ƒæ•´å…‰çº¿æŠ•å°„åŽä½¿ç”¨ " +"[method force_raycast_update]。" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -64072,7 +64159,7 @@ msgid "" msgstr "" "更新射线的碰撞信æ¯ã€‚ä½¿ç”¨æ¤æ–¹æ³•ç«‹å³æ›´æ–°ç¢°æ’žä¿¡æ¯ï¼Œè€Œä¸æ˜¯ç‰å¾…下一次 " "[code]_physics_process[/code] 调用,例如,如果光线或其父级已更改状æ€ã€‚\n" -"[b]注æ„:[/b][code]enabled[/code]ä¸éœ€è¦æ¤åŠŸèƒ½ã€‚" +"[b]注æ„:[/b][code]enabled[/code] ä¸éœ€è¦æ¤åŠŸèƒ½ã€‚" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -64098,7 +64185,7 @@ msgid "" "[b]Note:[/b] Bit indices range from 0-19." msgstr "" "如果通过的ä½ç´¢å¼•被打开,则返回 [code]true[/code]。\n" -"[b]注æ„:[/b]使Œ‡æ•°èŒƒå›´ä¸º0-19。" +"[b]注æ„:[/b]使Œ‡æ•°èŒƒå›´ä¸º 0-19。" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -64136,8 +64223,8 @@ msgid "" "Sets the bit index passed to the [code]value[/code] passed.\n" "[b]Note:[/b] Bit indexes range from 0-19." msgstr "" -"å°†ä¼ é€’çš„ä½ç´¢å¼•è®¾ç½®ä¸ºä¼ é€’çš„[code]值[/code]。\n" -"[b]注æ„:[/b]ä½ç´¢å¼•的范围是0-19。" +"å°†ä¼ é€’çš„ä½ç´¢å¼•è®¾ç½®ä¸ºä¼ é€’çš„ [code]value[/code]。\n" +"[b]注æ„:[/b]ä½ç´¢å¼•的范围是 0-19。" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "" @@ -64172,9 +64259,9 @@ msgid "" "If set to [code]Color(0.0, 0.0, 0.0)[/code] (by default), the color set in " "[member ProjectSettings.debug/shapes/collision/shape_color] is used." msgstr "" -"如果在 [b]Debug[/b] èœå•ä¸å¯ç”¨äº†å¯è§ç¢°æ’žå½¢çж [b]Visible Collision Shapes[/" -"b],则å¯ç”¨äºŽåœ¨ç¼–辑器ä¸å’Œè¿è¡Œæ—¶ç»˜åˆ¶å½¢çŠ¶çš„è‡ªå®šä¹‰é¢œè‰²ã€‚å¦‚æžœ [RayCast] 与æŸç‰©ä½“å‘" -"生碰撞,æ¤é¢œè‰²å°†åœ¨è¿è¡Œæ—¶çªå‡ºæ˜¾ç¤ºã€‚\n" +"如果在[b]调试[/b]èœå•ä¸å¯ç”¨äº†[b]显示碰撞区域[/b],则å¯ç”¨äºŽåœ¨ç¼–辑器ä¸å’Œè¿è¡Œæ—¶" +"绘制形状的自定义颜色。如果 [RayCast] 与æŸç‰©ä½“å‘生碰撞,æ¤é¢œè‰²å°†åœ¨è¿è¡Œæ—¶çªå‡ºæ˜¾" +"示。\n" "如果设置为 [code]Color(0.0, 0.0, 0.0)[/code](默认),则使用 [member " "ProjectSettings.debug/shapes/collision/shape_color] ä¸è®¾ç½®çš„颜色。" @@ -64186,8 +64273,8 @@ msgid "" "shape to be visible at run-time." msgstr "" "如果设置为 [code]1[/code],则将一æ¡çº¿ç”¨ä½œè°ƒè¯•形状。å¦åˆ™ï¼Œå°†ç»˜åˆ¶ä¸€ä¸ªæˆªæ–的金å—" -"å¡”æ¥è¡¨ç¤º [RayCast]。需è¦åœ¨ [b]调试[/b] èœå•ä¸å¯ç”¨å¯è§ç¢°æ’žå½¢çж [b]Visible " -"Collision Shapes[/b],以便调试形状在è¿è¡Œæ—¶å¯è§ã€‚" +"å¡”æ¥è¡¨ç¤º [RayCast]。需è¦åœ¨[b]调试[/b]èœå•ä¸å¯ç”¨[b]显示碰撞区域[/b],以便调试" +"形状在è¿è¡Œæ—¶å¯è§ã€‚" #: doc/classes/RayCast.xml doc/classes/RayCast2D.xml msgid "If [code]true[/code], collisions will be reported." @@ -64259,9 +64346,9 @@ msgid "" "itself from whatever is touching its far endpoint. It's often useful for " "characters." msgstr "" -"用于3D碰撞的射线形状,它å¯ä»¥è¢«è®¾ç½®æˆä¸€ä¸ª[PhysicsBody]或[Area]。一æ¡å°„çº¿å¹¶ä¸æ˜¯" -"真æ£çš„碰撞体;然而,它试图将自己与其远端点接触的东西分开。这通常对角色很有" -"用。" +"用于 3D 碰撞的射线形状,它å¯ä»¥è¢«è®¾ç½®æˆä¸€ä¸ª [PhysicsBody] 或 [Area]。一æ¡å°„线" +"并䏿˜¯çœŸæ£çš„碰撞体;然而,它试图将自己与其远端点接触的东西分开。这通常对角色" +"很有用。" #: doc/classes/RayShape.xml doc/classes/RayShape2D.xml msgid "The ray's length." @@ -64301,11 +64388,11 @@ msgstr "" #: doc/classes/Rect2.xml msgid "Constructs a [Rect2] by position and size." -msgstr "按ä½ç½®å’Œå¤§å°æž„é€ ä¸€ä¸ª[Rect2]。" +msgstr "按ä½ç½®å’Œå¤§å°æž„é€ ä¸€ä¸ª [Rect2]。" #: doc/classes/Rect2.xml msgid "Constructs a [Rect2] by x, y, width, and height." -msgstr "通过xã€yã€å®½åº¦å’Œé«˜åº¦æž„é€ ä¸€ä¸ª[Rect2]。" +msgstr "通过 xã€yã€å®½åº¦å’Œé«˜åº¦æž„é€ ä¸€ä¸ª [Rect2]。" #: doc/classes/Rect2.xml msgid "" @@ -68818,7 +68905,6 @@ msgid "" msgstr "返回该 [SceneTreeTween] ç›®å‰æ˜¯å¦æ£åœ¨æ‰§è¡Œï¼Œå³æœªæš‚åœä¸”未完æˆã€‚" #: doc/classes/SceneTreeTween.xml -#, fuzzy msgid "" "Returns whether the [SceneTreeTween] is valid. A valid [SceneTreeTween] is a " "[SceneTreeTween] contained by the scene tree (i.e. the array from [method " @@ -68832,7 +68918,7 @@ msgstr "" "[SceneTreeTween]ï¼ˆå³ [method SceneTree.get_processed_tweens] 返回的数组ä¸åŒ…å«" "这个 [SceneTreeTween])。[SceneTreeTween] 失效的情况有:补间完æˆã€è¢«é”€æ¯ã€ä½¿" "用 [code]SceneTreeTween.new()[/code] åˆ›å»ºã€‚æ— æ•ˆçš„ [SceneTreeTween] ä¸èƒ½è¿½åŠ " -"[Tweener]。" +"[Tweener]ã€‚ä½†ä½ ä»ç„¶èƒ½å¤Ÿä½¿ç”¨ [method interpolate_value]。" #: doc/classes/SceneTreeTween.xml msgid "Aborts all tweening operations and invalidates the [SceneTreeTween]." @@ -68879,7 +68965,6 @@ msgstr "" "的默认缓动类型。" #: doc/classes/SceneTreeTween.xml -#, fuzzy msgid "" "Sets the number of times the tweening sequence will be repeated, i.e. " "[code]set_loops(2)[/code] will run the animation twice.\n" @@ -70738,13 +70823,13 @@ msgstr "å¯ç”¨æ¤èŠ‚ç‚¹çš„å‘ˆçŽ°ã€‚å°† [member visible] 更改为 [code]true[/co msgid "" "Transforms [code]local_point[/code] from this node's local space to world " "space." -msgstr "å°† [code]local_point[/code] 从该节点的本地空间转æ¢ä¸ºä¸–界空间。" +msgstr "å°† [code]local_point[/code] 从这个节点的局部空间转æ¢ä¸ºä¸–界空间。" #: doc/classes/Spatial.xml msgid "" "Transforms [code]global_point[/code] from world space to this node's local " "space." -msgstr "å°† [code]global_point[/code] 从世界空间转æ¢åˆ°è¿™ä¸ªèŠ‚ç‚¹çš„æœ¬åœ°ç©ºé—´ã€‚" +msgstr "å°† [code]global_point[/code] 从世界空间转æ¢åˆ°è¿™ä¸ªèŠ‚ç‚¹çš„å±€éƒ¨ç©ºé—´ã€‚" #: doc/classes/Spatial.xml msgid "" @@ -70754,7 +70839,7 @@ msgid "" "offset of [code](2, 0, 0)[/code] would actually add 20 ([code]2 * 10[/code]) " "to the X coordinate." msgstr "" -"通过给定的åç§»é‡ [Vector3] 改å˜èŠ‚ç‚¹çš„ä½ç½®ã€‚\n" +"通过给定的åç§»é‡ [Vector3] 改å˜è¯¥èŠ‚ç‚¹çš„ä½ç½®ã€‚\n" "注æ„,平移 [code]offset[/code] å—节点缩放的影å“,所以如果按例如 [code]" "(10,1,1)[/code] 进行缩放,平移 [code](2,0,0)[/code] 实际上会在 X åæ ‡ä¸Šå¢žåŠ " "20 ([code]2 * 10[/code])。" @@ -70762,22 +70847,21 @@ msgstr "" #: doc/classes/Spatial.xml msgid "" "Changes the node's position by the given offset [Vector3] in local space." -msgstr "通过给定的åç§»é‡ [Vector3] 改å˜èŠ‚ç‚¹åœ¨å±€éƒ¨ç©ºé—´ä¸çš„ä½ç½®ã€‚" +msgstr "通过给定的局部空间åç§»é‡ [Vector3] 改å˜è¯¥èŠ‚ç‚¹çš„ä½ç½®ã€‚" #: doc/classes/Spatial.xml msgid "Updates the [SpatialGizmo] of this node." -msgstr "更新该节点的 [SpatialGizmo]。" +msgstr "更新这个节点的 [SpatialGizmo]。" #: doc/classes/Spatial.xml msgid "" "The [SpatialGizmo] for this node. Used for example in [EditorSpatialGizmo] " "as custom visualization and editing handles in Editor." msgstr "" -"æ¤èŠ‚ç‚¹çš„ [SpatialGizmo]。例如在 [EditorSpatialGizmo] ä¸ç”¨ä½œç¼–辑器ä¸çš„自定义å¯" -"视化和编辑手柄。" +"这个节点的 [SpatialGizmo]。例如在 [EditorSpatialGizmo] ä¸ç”¨ä½œç¼–辑器ä¸çš„自定义" +"å¯è§†åŒ–和编辑手柄。" #: doc/classes/Spatial.xml -#, fuzzy msgid "" "Rotation part of the global transformation in radians, specified in terms of " "YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n" @@ -70789,7 +70873,7 @@ msgid "" "point numbers. Therefore, applying affine operations on the rotation " "\"vector\" is not meaningful." msgstr "" -"å±€éƒ¨å˜æ¢çš„æ—‹è½¬éƒ¨åˆ†ä»¥å¼§åº¦è¡¨ç¤ºï¼Œä»¥ YXZ-Euler 角的形å¼è¡¨ç¤ºï¼ˆX è§’ã€Y è§’ã€Z " +"å…¨å±€å˜æ¢çš„æ—‹è½¬éƒ¨åˆ†ï¼Œå•ä½ä¸ºå¼§åº¦ï¼Œä»¥ YXZ 欧拉角的形å¼è¡¨ç¤ºï¼ˆX è§’ã€Y è§’ã€Z " "角)。\n" "[b]注æ„:[/b]åœ¨æ•°å¦æ„ä¹‰ä¸Šï¼Œæ—‹è½¬æ˜¯ä¸€ä¸ªçŸ©é˜µè€Œä¸æ˜¯ä¸€ä¸ªå‘é‡ã€‚这三个欧拉角是旋转矩" "é˜µæ¬§æ‹‰è§’å‚æ•°åŒ–çš„ä¸‰ä¸ªç‹¬ç«‹å‚æ•°ï¼Œå˜å‚¨åœ¨ [Vector3] æ•°æ®ç»“æž„ä¸å¹¶ä¸æ˜¯å› 为旋转是一个" @@ -70798,13 +70882,13 @@ msgstr "" #: doc/classes/Spatial.xml msgid "World space (global) [Transform] of this node." -msgstr "æ¤èŠ‚ç‚¹çš„ä¸–ç•Œç©ºé—´ï¼ˆå…¨å±€ï¼‰[Transform]。" +msgstr "è¿™ä¸ªèŠ‚ç‚¹çš„ä¸–ç•Œç©ºé—´ï¼ˆå…¨å±€ï¼‰å˜æ¢ [Transform]。" #: doc/classes/Spatial.xml msgid "" "Global position of this node. This is equivalent to [code]global_transform." "origin[/code]." -msgstr "" +msgstr "这个节点的全局ä½ç½®ã€‚与 [code]global_transform.origin[/code] ç‰ä»·ã€‚" #: doc/classes/Spatial.xml msgid "" @@ -70818,7 +70902,7 @@ msgid "" "point numbers. Therefore, applying affine operations on the rotation " "\"vector\" is not meaningful." msgstr "" -"å±€éƒ¨å˜æ¢çš„æ—‹è½¬éƒ¨åˆ†ä»¥å¼§åº¦è¡¨ç¤ºï¼Œä»¥ YXZ-Euler 角的形å¼è¡¨ç¤ºï¼ˆX è§’ã€Y è§’ã€Z " +"å±€éƒ¨å˜æ¢çš„æ—‹è½¬éƒ¨åˆ†ï¼Œå•ä½ä¸ºå¼§åº¦ï¼Œä»¥ YXZ 欧拉角的形å¼è¡¨ç¤ºï¼ˆX è§’ã€Y è§’ã€Z " "角)。\n" "[b]注æ„:[/b]åœ¨æ•°å¦æ„ä¹‰ä¸Šï¼Œæ—‹è½¬æ˜¯ä¸€ä¸ªçŸ©é˜µè€Œä¸æ˜¯ä¸€ä¸ªå‘é‡ã€‚这三个欧拉角是旋转矩" "é˜µæ¬§æ‹‰è§’å‚æ•°åŒ–çš„ä¸‰ä¸ªç‹¬ç«‹å‚æ•°ï¼Œå˜å‚¨åœ¨ [Vector3] æ•°æ®ç»“æž„ä¸å¹¶ä¸æ˜¯å› 为旋转是一个" @@ -70839,17 +70923,17 @@ msgid "" "transformation matrices in Godot, the scale values will either be all " "positive or all negative." msgstr "" -"æœ¬åœ°å˜æ¢ä¸çš„缩放。\n" +"å±€éƒ¨å˜æ¢çš„缩放部分。\n" "[b]注æ„:[/b]3D ä¸ï¼Œå˜æ¢çŸ©é˜µæ˜¯æ— 法分解出æ£è´Ÿæ··åˆçš„缩放的。由于 Godot ä¸ä½¿ç”¨å˜" "æ¢çŸ©é˜µæ¥è¡¨ç¤ºç¼©æ”¾ï¼Œå¾—到的缩放值è¦ä¹ˆå…¨æ£ã€è¦ä¹ˆå…¨è´Ÿã€‚" #: doc/classes/Spatial.xml msgid "Local space [Transform] of this node, with respect to the parent node." -msgstr "该节点相对于父节点的局部空间 [Transform]。" +msgstr "这个节点相对于父节点的局部空间 [Transform]。" #: doc/classes/Spatial.xml msgid "Local translation of this node." -msgstr "æ¤èŠ‚ç‚¹çš„å±€éƒ¨å˜æ¢ã€‚" +msgstr "è¿™ä¸ªèŠ‚ç‚¹çš„å±€éƒ¨å˜æ¢ã€‚" #: doc/classes/Spatial.xml msgid "" @@ -72817,10 +72901,11 @@ msgid "The size of one pixel's width on the sprite to scale it in 3D." msgstr "ç²¾çµä¸Šä¸€ä¸ªåƒç´ 宽度的大å°ï¼Œä»¥ 3D 缩放。" #: doc/classes/SpriteBase3D.xml +#, fuzzy msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -76414,9 +76499,10 @@ msgid "Sets the text for a specific line." msgstr "设置特定行的文本。" #: doc/classes/TextEdit.xml +#, fuzzy msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" "如果 [code]bookmark[/code] 为 true,则为行 [code]line[/code] 设置书ç¾ã€‚如果 " @@ -80281,7 +80367,7 @@ msgid "" "is_selected]." msgstr "" "返回当å‰èŽ·å¾—ç„¦ç‚¹çš„åˆ—ï¼Œå¦‚æžœæ²¡æœ‰ç„¦ç‚¹åˆ—ï¼Œåˆ™è¿”å›ž -1。\n" -"在[constant SELECT_SINGLE] 模å¼ä¸‹ï¼Œç„¦ç‚¹åˆ—是被选ä¸çš„列。在 [constant " +"在 [constant SELECT_SINGLE] 模å¼ä¸‹ï¼Œç„¦ç‚¹åˆ—是被选ä¸çš„列。在 [constant " "SELECT_ROW] 模å¼ä¸‹ï¼Œå¦‚果有任æ„项被选ä¸ï¼Œç„¦ç‚¹åˆ—总是 0。在 [constant " "SELECT_MULTI] 模å¼ä¸‹ï¼Œç„¦ç‚¹åˆ—æ˜¯ç„¦ç‚¹å…‰æ ‡ä¸‹çš„åˆ—ï¼Œä½†ä¸ä¸€å®šæœ‰åˆ—被选ä¸ã€‚\n" "è¦åˆ¤æ–一个项的æŸä¸€åˆ—是å¦è¢«é€‰ä¸ï¼Œè¯·ä½¿ç”¨ [method TreeItem.is_selected]。" @@ -80306,12 +80392,12 @@ msgid "" "will use their \"min_width\" in a similar fashion to [member Control." "size_flags_stretch_ratio]." msgstr "" -"设置一个列的最å°å®½åº¦ã€‚拥有“Expandâ€æ ‡å¿—的列将以类似于 [member Control." +"设置æŸä¸€åˆ—的最å°å®½åº¦ã€‚拥有“Expandâ€æ ‡å¿—的列将以类似于 [member Control." "size_flags_stretch_ratio] 的方å¼ä½¿ç”¨å…¶â€œmin_widthâ€æœ€å°å®½åº¦ã€‚" #: doc/classes/Tree.xml msgid "Sets the title of a column." -msgstr "è®¾ç½®ä¸€ä¸ªåˆ—çš„æ ‡é¢˜ã€‚" +msgstr "设置æŸä¸€åˆ—çš„æ ‡é¢˜ã€‚" #: doc/classes/Tree.xml msgid "" @@ -80485,7 +80571,7 @@ msgid "" "other flags." msgstr "" "ç¦ç”¨æ‰€æœ‰æ”¾ç½®éƒ¨åˆ†ï¼Œä½†ä»ç„¶å…许通过 [method get_drop_section_at_position] 检" -"测“物å“上â€çš„æ”¾ç½®éƒ¨åˆ†ã€‚\n" +"测“项目上â€çš„æ”¾ç½®éƒ¨åˆ†ã€‚\n" "[b]注æ„:[/b]è¿™æ˜¯é»˜è®¤çš„æ ‡å¿—ï¼Œå½“ä¸Žå…¶ä»–æ ‡å¿—ç»“åˆæ—¶ï¼Œå®ƒæ²¡æœ‰æ•ˆæžœã€‚" #: doc/classes/Tree.xml @@ -80549,7 +80635,7 @@ msgid "" "Draws the guidelines if not zero, this acts as a boolean. The guideline is a " "horizontal line drawn at the bottom of each item." msgstr "" -"如果ä¸ä¸ºé›¶å°±ç»˜åˆ¶å‚考线,这作为一个布尔值。å‚考线是在æ¯ä¸ªé¡¹çš„åº•éƒ¨ç”»çš„ä¸€æ¡æ°´å¹³" +"如果ä¸ä¸ºé›¶å°±ç»˜åˆ¶å‚考线,行为类似于布尔值。å‚考线是在æ¯ä¸ªé¡¹çš„åº•éƒ¨ç”»çš„ä¸€æ¡æ°´å¹³" "线。" #: doc/classes/Tree.xml @@ -80557,8 +80643,8 @@ msgid "" "Draws the relationship lines if not zero, this acts as a boolean. " "Relationship lines are drawn at the start of child items to show hierarchy." msgstr "" -"如果ä¸ä¸ºé›¶ï¼Œåˆ™ç»˜åˆ¶å…³ç³»çº¿ï¼Œè¿™ä½œä¸ºä¸€ä¸ªå¸ƒå°”值。关系线在å项的开始处绘制,以显示" -"层次结构。" +"如果ä¸ä¸ºé›¶å°±ç»˜åˆ¶å…³ç³»çº¿ï¼Œè¡Œä¸ºç±»ä¼¼äºŽå¸ƒå°”值。关系线在å项的开始处绘制,以显示层" +"次结构。" #: doc/classes/Tree.xml msgid "" @@ -80820,14 +80906,17 @@ msgid "" msgstr "返回使用 [method set_metadata] 为指定列设置的元数æ®ã€‚" #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "è¿”å›žæ ‘ä¸çš„下一个 TreeItem,如果没有,则返回一个空对象。" #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -80841,14 +80930,17 @@ msgid "Returns the parent TreeItem or a null object if there is none." msgstr "返回父级 TreeItem,如果没有,则返回一个空对象。" #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "è¿”å›žæ ‘ä¸çš„å‰ä¸€ä¸ª TreeItem,如果没有,则返回一个空对象。" #: doc/classes/TreeItem.xml +#, fuzzy msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -89175,8 +89267,12 @@ msgid "Sets the viewport's global transformation matrix." msgstr "è®¾ç½®è§†çª—çš„å…¨å±€å˜æ¢çŸ©é˜µã€‚" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." -msgstr "如果为 [code]true[/code],视窗将呈现为 hdr。" +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" #: doc/classes/VisualServer.xml msgid "If [code]true[/code], the viewport's canvas is not rendered." @@ -89274,6 +89370,22 @@ msgid "" msgstr "设置视窗的 2D/3D 模å¼ã€‚é€‰é¡¹è§ [enum ViewportUsage] 常é‡ã€‚" #: doc/classes/VisualServer.xml +#, fuzzy +msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" +"如果为 [code]true[/code],分é…该视窗的帧缓冲时将使用完整浮点数精度(32 ä½ï¼‰è€Œ" +"䏿˜¯åŠæµ®ç‚¹æ•°ç²¾åº¦ï¼ˆ16 ä½ï¼‰ã€‚ä»…åœ¨åŒæ—¶å¯ç”¨ [member hdr] 时有效。\n" +"[b]注æ„:[/b]å¯ç”¨è¿™ä¸ªè®¾ç½®ä¸ä¼šæå‡æ¸²æŸ“è´¨é‡ã€‚ä½¿ç”¨å®Œæ•´æµ®ç‚¹æ•°ç²¾åº¦è¾ƒæ…¢ï¼Œä¸€èˆ¬åªæœ‰è¦" +"求更高精度的高级ç€è‰²å™¨éœ€è¦ä½¿ç”¨ã€‚如果是è¦å‡å°‘æ¡å¸¦æ•ˆåº”,请å¯ç”¨ [member " +"debanding]。\n" +"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸å¯ç”¨ã€‚" + +#: doc/classes/VisualServer.xml msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." diff --git a/doc/translations/zh_TW.po b/doc/translations/zh_TW.po index cd8d5c0eb5..59cd8b199b 100644 --- a/doc/translations/zh_TW.po +++ b/doc/translations/zh_TW.po @@ -948,7 +948,14 @@ msgid "" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml -msgid "Like [method print], but prints only when used in debug mode." +msgid "" +"Like [method print], but includes the current stack frame when running with " +"the debugger turned on.\n" +"Output in the console would look something like this:\n" +"[codeblock]\n" +"Test print\n" +" At: res://test.gd:15:_process()\n" +"[/codeblock]" msgstr "" #: modules/gdscript/doc_classes/@GDScript.xml @@ -7798,8 +7805,8 @@ msgstr "" #: doc/classes/ARVRController.xml msgid "" "The degree to which the controller vibrates. Ranges from [code]0.0[/code] to " -"[code]1.0[/code] with precision [code].01[/code]. If changed, updates " -"[member ARVRPositionalTracker.rumble] accordingly.\n" +"[code]1.0[/code]. If changed, updates [member ARVRPositionalTracker.rumble] " +"accordingly.\n" "This is a useful property to animate if you want the controller to vibrate " "for a limited duration." msgstr "" @@ -11871,7 +11878,12 @@ msgstr "" #: doc/classes/Camera.xml msgid "" -"If [code]true[/code], the ancestor [Viewport] is currently using this camera." +"If [code]true[/code], the ancestor [Viewport] is currently using this " +"camera.\n" +"If multiple cameras are in the scene, one will always be made current. For " +"example, if two [Camera] nodes are present in the scene and only one is " +"current, setting one camera's [member current] to [code]false[/code] will " +"cause the other camera to be made current." msgstr "" #: doc/classes/Camera.xml @@ -20299,7 +20311,7 @@ msgstr "" msgid "" "Saves the editor feature profile to a file in JSON format. It can then be " "imported using the feature profile manager's [b]Import[/b] button or the " -"[method load_from_file] button." +"[method load_from_file] method." msgstr "" #: doc/classes/EditorFeatureProfile.xml @@ -23691,7 +23703,7 @@ msgstr "" #: doc/classes/Environment.xml msgid "" "The tonemapping mode to use. Tonemapping is the process that \"converts\" " -"HDR values to be suitable for rendering on a LDR display. (Godot doesn't " +"HDR values to be suitable for rendering on a SDR display. (Godot doesn't " "support rendering on HDR displays yet.)" msgstr "" @@ -25528,7 +25540,7 @@ msgstr "" #: doc/classes/Geometry.xml msgid "" "Given an array of [Vector2]s representing tiles, builds an atlas. The " -"returned dictionary has two keys: [code]points[/code] is a vector of " +"returned dictionary has two keys: [code]points[/code] is an array of " "[Vector2] that specifies the positions of each tile, [code]size[/code] " "contains the overall size of the whole atlas as [Vector2]." msgstr "" @@ -32638,7 +32650,7 @@ msgstr "" msgid "" "Sets the render priority for the text outline. Higher priority objects will " "be sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32654,7 +32666,7 @@ msgstr "" msgid "" "Sets the render priority for the text. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -32684,7 +32696,7 @@ msgstr "" #: doc/classes/Label3D.xml msgid "" -"If set, text can be seen from the back as well. If not, the texture is " +"If set, text can be seen from the back as well. If not, the text is " "invisible when looking at it from behind." msgstr "" @@ -36820,7 +36832,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The cost of entering this region from another region can be controlled with " "the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The cost of traveling distances inside this region can be controlled with " "the [member travel_cost] multiplier." @@ -37083,7 +37095,7 @@ msgid "" "two regions. They must share a similar edge.\n" "The pathfinding cost of entering this region from another region can be " "controlled with the [member enter_cost] value.\n" -"[b]Note[/b]: This value is not added to the path cost when the start " +"[b]Note:[/b] This value is not added to the path cost when the start " "position is already inside this region.\n" "The pathfinding cost of traveling distances inside this region can be " "controlled with the [member travel_cost] multiplier." @@ -37201,6 +37213,52 @@ msgstr "" msgid "Control activation of this server." msgstr "" +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be controlled from a " +"script." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"A [NetworkedMultiplayerPeer] implementation that can be used as a [member " +"MultiplayerAPI.network_peer] and controlled from a script.\n" +"Its purpose is to allow adding a new backend for the high-Level multiplayer " +"API without needing to use GDNative." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Deliver a packet to the local [MultiplayerAPI].\n" +"When your script receives a packet from other peers over the network " +"(originating from the [signal packet_generated] signal on the sending peer), " +"passing it to this method will deliver it locally." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Initialize the peer with the given [code]peer_id[/code] (must be between 1 " +"and 2147483647)." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Set the state of the connection. See [enum NetworkedMultiplayerPeer." +"ConnectionStatus]." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "Set the max packet size that this peer can handle." +msgstr "" + +#: doc/classes/NetworkedMultiplayerCustom.xml +msgid "" +"Emitted when the local [MultiplayerAPI] generates a packet.\n" +"Your script should take this packet and send it to the requested peer over " +"the network (which should call [method deliver_packet] with the data when " +"it's received)." +msgstr "" + #: modules/enet/doc_classes/NetworkedMultiplayerENet.xml msgid "" "PacketPeer implementation using the [url=http://enet.bespin.org/index." @@ -39898,7 +39956,13 @@ msgid "See [enum ShadowDetail]." msgstr "" #: doc/classes/OmniLight.xml -msgid "See [enum ShadowMode]." +msgid "" +"The shadow rendering mode to use for this [OmniLight]. See [enum " +"ShadowMode].\n" +"[b]Note:[/b] In GLES2, [constant SHADOW_CUBE] is only supported on GPUs that " +"feature support for depth cubemaps. Old GPUs such as the Radeon HD 4000 " +"series don't support cubemap shadows and will fall back to dual paraboloid " +"shadows as a result." msgstr "" #: doc/classes/OmniLight.xml @@ -39910,7 +39974,8 @@ msgstr "" #: doc/classes/OmniLight.xml msgid "" "Shadows are rendered to a cubemap. Slower than [constant " -"SHADOW_DUAL_PARABOLOID], but higher-quality." +"SHADOW_DUAL_PARABOLOID], but higher-quality. Only supported on GPUs that " +"feature support for depth cubemaps." msgstr "" #: doc/classes/OmniLight.xml @@ -57697,7 +57762,7 @@ msgstr "" msgid "" "Sets the render priority for the sprite. Higher priority objects will be " "sorted in front of lower priority objects.\n" -"[b]Node:[/b] This only applies if [member alpha_cut] is set to [constant " +"[b]Note:[/b] This only applies if [member alpha_cut] is set to [constant " "ALPHA_CUT_DISABLED] (default value).\n" "[b]Note:[/b] This only applies to sorting of transparent objects. This will " "not impact how transparent objects are sorted relative to opaque objects. " @@ -60599,8 +60664,8 @@ msgstr "" #: doc/classes/TextEdit.xml msgid "" -"Bookmarks the [code]line[/code] if [code]bookmark[/code] is true. Deletes " -"the bookmark if [code]bookmark[/code] is false.\n" +"Bookmarks the [code]line[/code] if [code]bookmark[/code] is [code]true[/" +"code]. Deletes the bookmark if [code]bookmark[/code] is [code]false[/code].\n" "Bookmarks are shown in the [member breakpoint_gutter]." msgstr "" @@ -64234,13 +64299,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next TreeItem in the tree or a null object if there is none." +"Returns the next sibling TreeItem in the tree or a null object if there is " +"none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the next visible TreeItem in the tree or a null object if there is " -"none.\n" +"Returns the next visible sibling TreeItem in the tree or a null object if " +"there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the first " "visible element in the tree when called on the last visible element, " "otherwise it returns [code]null[/code]." @@ -64252,13 +64318,14 @@ msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous TreeItem in the tree or a null object if there is none." +"Returns the previous sibling TreeItem in the tree or a null object if there " +"is none." msgstr "" #: doc/classes/TreeItem.xml msgid "" -"Returns the previous visible TreeItem in the tree or a null object if there " -"is none.\n" +"Returns the previous visible sibling TreeItem in the tree or a null object " +"if there is none.\n" "If [code]wrap[/code] is enabled, the method will wrap around to the last " "visible element in the tree when called on the first visible element, " "otherwise it returns [code]null[/code]." @@ -71172,7 +71239,11 @@ msgid "Sets the viewport's global transformation matrix." msgstr "" #: doc/classes/VisualServer.xml -msgid "If [code]true[/code], the viewport renders to hdr." +msgid "" +"If [code]true[/code], the viewport renders to high dynamic range (HDR) " +"instead of standard dynamic range (SDR). See also [method " +"viewport_set_use_32_bpc_depth].\n" +"[b]Note:[/b] Only available on the GLES3 backend." msgstr "" #: doc/classes/VisualServer.xml @@ -71257,6 +71328,15 @@ msgstr "" #: doc/classes/VisualServer.xml msgid "" +"If [code]true[/code], allocates the viewport's framebuffer with full " +"floating-point precision (32-bit) instead of half floating-point precision " +"(16-bit). Only effective if [method viewport_set_use_32_bpc_depth] is used " +"on the same [Viewport] to set HDR to [code]true[/code].\n" +"[b]Note:[/b] Only available on the GLES3 backend." +msgstr "" + +#: doc/classes/VisualServer.xml +msgid "" "If [code]true[/code], the viewport uses augmented or virtual reality " "technologies. See [ARVRInterface]." msgstr "" diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index 276e69e470..cc38c2352f 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -38,7 +38,7 @@ #define kOutputBus 0 #define kInputBus 1 -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED OSStatus AudioDriverCoreAudio::input_device_address_cb(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inClientData) { @@ -72,7 +72,7 @@ Error AudioDriverCoreAudio::init() { AudioComponentDescription desc; memset(&desc, 0, sizeof(desc)); desc.componentType = kAudioUnitType_Output; -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED desc.componentSubType = kAudioUnitSubType_HALOutput; #else desc.componentSubType = kAudioUnitSubType_RemoteIO; @@ -85,7 +85,7 @@ Error AudioDriverCoreAudio::init() { OSStatus result = AudioComponentInstanceNew(comp, &audio_unit); ERR_FAIL_COND_V(result != noErr, FAILED); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED AudioObjectPropertyAddress prop; prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice; prop.mScope = kAudioObjectPropertyScopeGlobal; @@ -135,7 +135,7 @@ Error AudioDriverCoreAudio::init() { // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels) buffer_frames = closest_power_of_2(latency * mix_rate / 1000); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32)); ERR_FAIL_COND_V(result != noErr, FAILED); #endif @@ -313,7 +313,7 @@ void AudioDriverCoreAudio::finish() { ERR_PRINT("AudioUnitUninitialize failed"); } -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED AudioObjectPropertyAddress prop; prop.mSelector = kAudioHardwarePropertyDefaultOutputDevice; prop.mScope = kAudioObjectPropertyScopeGlobal; @@ -339,7 +339,7 @@ Error AudioDriverCoreAudio::capture_init() { AudioComponentDescription desc; memset(&desc, 0, sizeof(desc)); desc.componentType = kAudioUnitType_Output; -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED desc.componentSubType = kAudioUnitSubType_HALOutput; #else desc.componentSubType = kAudioUnitSubType_RemoteIO; @@ -352,7 +352,7 @@ Error AudioDriverCoreAudio::capture_init() { OSStatus result = AudioComponentInstanceNew(comp, &input_unit); ERR_FAIL_COND_V(result != noErr, FAILED); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED AudioObjectPropertyAddress prop; prop.mSelector = kAudioHardwarePropertyDefaultInputDevice; prop.mScope = kAudioObjectPropertyScopeGlobal; @@ -370,7 +370,7 @@ Error AudioDriverCoreAudio::capture_init() { ERR_FAIL_COND_V(result != noErr, FAILED); UInt32 size; -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED AudioDeviceID deviceId; size = sizeof(AudioDeviceID); AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; @@ -447,7 +447,7 @@ void AudioDriverCoreAudio::capture_finish() { ERR_PRINT("AudioUnitUninitialize failed"); } -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED AudioObjectPropertyAddress prop; prop.mSelector = kAudioHardwarePropertyDefaultInputDevice; prop.mScope = kAudioObjectPropertyScopeGlobal; @@ -491,7 +491,7 @@ Error AudioDriverCoreAudio::capture_stop() { return OK; } -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED Array AudioDriverCoreAudio::_get_device_list(bool capture) { Array list; diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h index f86037f092..7fac8a99ed 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.h +++ b/drivers/coreaudio/audio_driver_coreaudio.h @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef COREAUDIO_ENABLED - #ifndef AUDIO_DRIVER_COREAUDIO_H #define AUDIO_DRIVER_COREAUDIO_H +#ifdef COREAUDIO_ENABLED + #include "servers/audio_server.h" #import <AudioUnit/AudioUnit.h> -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED #import <CoreAudio/AudioHardware.h> #endif @@ -58,7 +58,7 @@ class AudioDriverCoreAudio : public AudioDriver { Vector<int32_t> samples_in; Vector<int16_t> input_buf; -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED Array _get_device_list(bool capture = false); void _set_device(const String &device, bool capture = false); @@ -106,7 +106,7 @@ public: bool try_lock(); void stop(); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED virtual Array get_device_list(); virtual String get_device(); virtual void set_device(String device); @@ -120,6 +120,6 @@ public: ~AudioDriverCoreAudio() {} }; -#endif +#endif // COREAUDIO_ENABLED -#endif +#endif // AUDIO_DRIVER_COREAUDIO_H diff --git a/drivers/coremidi/midi_driver_coremidi.h b/drivers/coremidi/midi_driver_coremidi.h index 0085141c6d..ac2ad99eb3 100644 --- a/drivers/coremidi/midi_driver_coremidi.h +++ b/drivers/coremidi/midi_driver_coremidi.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef COREMIDI_ENABLED - #ifndef MIDI_DRIVER_COREMIDI_H #define MIDI_DRIVER_COREMIDI_H +#ifdef COREMIDI_ENABLED + #include "core/os/midi_driver.h" #include "core/templates/vector.h" @@ -57,5 +57,6 @@ public: virtual ~MIDIDriverCoreMidi(); }; -#endif // MIDI_DRIVER_COREMIDI_H #endif // COREMIDI_ENABLED + +#endif // MIDI_DRIVER_COREMIDI_H diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub index ddeec6f4c6..7e8bd22960 100644 --- a/drivers/gl_context/SCsub +++ b/drivers/gl_context/SCsub @@ -2,7 +2,7 @@ Import("env") -if env["platform"] in ["haiku", "osx", "windows", "linuxbsd"]: +if env["platform"] in ["haiku", "macos", "windows", "linuxbsd"]: # Thirdparty source files thirdparty_dir = "#thirdparty/glad/" thirdparty_sources = [ diff --git a/drivers/gles3/effects/copy_effects.h b/drivers/gles3/effects/copy_effects.h index 1cf1ac9404..b863e76579 100644 --- a/drivers/gles3/effects/copy_effects.h +++ b/drivers/gles3/effects/copy_effects.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COPY_GL_H -#define COPY_GL_H +#ifndef COPY_EFFECTS_GLES3_H +#define COPY_EFFECTS_GLES3_H #ifdef GLES3_ENABLED @@ -70,4 +70,5 @@ public: } //namespace GLES3 #endif // GLES3_ENABLED -#endif // !COPY_GL_H + +#endif // COPY_EFFECTS_GLES3_H diff --git a/drivers/gles3/environment/fog.h b/drivers/gles3/environment/fog.h index 22bf3bb017..350eb459cf 100644 --- a/drivers/gles3/environment/fog.h +++ b/drivers/gles3/environment/fog.h @@ -59,4 +59,4 @@ public: #endif // GLES3_ENABLED -#endif // !FOG_GLES3_H +#endif // FOG_GLES3_H diff --git a/drivers/gles3/environment/gi.h b/drivers/gles3/environment/gi.h index b633520784..7a0634f22b 100644 --- a/drivers/gles3/environment/gi.h +++ b/drivers/gles3/environment/gi.h @@ -93,4 +93,4 @@ public: #endif // GLES3_ENABLED -#endif // !GI_GLES3_H +#endif // GI_GLES3_H diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 82f7450bc2..abbc11847f 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -135,7 +135,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ Size2i ssize = texture_storage->render_target_get_size(p_to_render_target); Transform3D screen_transform; - screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); + screen_transform.translate_local(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); @@ -183,7 +183,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_state_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW); - GLuint global_buffer = material_storage->global_variables_get_uniform_buffer(); + GLuint global_buffer = material_storage->global_shader_uniforms_get_uniform_buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_LOCATION, global_buffer); glBindBuffer(GL_UNIFORM_BUFFER, 0); @@ -1217,7 +1217,7 @@ void RasterizerCanvasGLES3::reset_canvas() { void RasterizerCanvasGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) { } -void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) { +void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, Projection *p_xform_cache) { } void RasterizerCanvasGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) { @@ -1570,7 +1570,7 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() { glBindBuffer(GL_UNIFORM_BUFFER, 0); String global_defines; - global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now + global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now global_defines += "#define MAX_LIGHTS " + itos(state.max_instances_per_batch) + "\n"; global_defines += "#define MAX_DRAW_DATA_INSTANCES " + itos(state.max_instances_per_batch) + "\n"; diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index caf649aaf6..f920e37130 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_CANVAS_OPENGL_H -#define RASTERIZER_CANVAS_OPENGL_H +#ifndef RASTERIZER_CANVAS_GLES3_H +#define RASTERIZER_CANVAS_GLES3_H #ifdef GLES3_ENABLED @@ -209,7 +209,7 @@ public: void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample); void reset_canvas(); - void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache); + void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, Projection *p_xform_cache); virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override; @@ -262,4 +262,5 @@ public: }; #endif // GLES3_ENABLED -#endif // RASTERIZER_CANVAS_OPENGL_H + +#endif // RASTERIZER_CANVAS_GLES3_H diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 613a7f37d9..33303b1e38 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -69,7 +69,7 @@ #endif #endif -#if !defined(IPHONE_ENABLED) && !defined(JAVASCRIPT_ENABLED) +#if !defined(IOS_ENABLED) && !defined(JAVASCRIPT_ENABLED) // We include EGL below to get debug callback on GLES2 platforms, // but EGL is not available on iOS. #define CAN_DEBUG diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index e842b6d70c..97543af0d5 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_OPENGL_H -#define RASTERIZER_OPENGL_H +#ifndef RASTERIZER_GLES3_H +#define RASTERIZER_GLES3_H #ifdef GLES3_ENABLED @@ -112,4 +112,4 @@ public: #endif // GLES3_ENABLED -#endif +#endif // RASTERIZER_GLES3_H diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index eee303a2ca..26d84aa6a3 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/templates/sort_array.h" #include "servers/rendering/rendering_server_default.h" +#include "servers/rendering/rendering_server_globals.h" #include "storage/config.h" #include "storage/light_storage.h" #include "storage/mesh_storage.h" @@ -39,15 +40,9 @@ #ifdef GLES3_ENABLED -uint64_t RasterizerSceneGLES3::auto_exposure_counter = 2; - RasterizerSceneGLES3 *RasterizerSceneGLES3::singleton = nullptr; -RasterizerSceneGLES3 *RasterizerSceneGLES3::get_singleton() { - return singleton; -} - -RendererSceneRender::GeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_base) { +RenderGeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_base) { RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); @@ -57,176 +52,36 @@ RendererSceneRender::GeometryInstance *RasterizerSceneGLES3::geometry_instance_c ginstance->data->base = p_base; ginstance->data->base_type = type; - _geometry_instance_mark_dirty(ginstance); + ginstance->_mark_dirty(); return ginstance; } -void RasterizerSceneGLES3::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->skeleton = p_skeleton; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RasterizerSceneGLES3::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_override = p_override; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RasterizerSceneGLES3::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_overlay = p_overlay; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RasterizerSceneGLES3::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->surface_materials = p_materials; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RasterizerSceneGLES3::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ERR_FAIL_COND(!ginstance); - ginstance->mesh_instance = p_mesh_instance; - - _geometry_instance_mark_dirty(ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->transform = p_transform; - ginstance->mirror = p_transform.basis.determinant() < 0; - ginstance->data->aabb = p_aabb; - ginstance->transformed_aabb = p_transformed_aabb; - - Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); - // handle non uniform scale here - - float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); - ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; - - ginstance->lod_model_scale = max_scale; -} - -void RasterizerSceneGLES3::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->layer_mask = p_layer_mask; -} - -void RasterizerSceneGLES3::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lod_bias = p_lod_bias; -} - -void RasterizerSceneGLES3::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->force_alpha = CLAMP(1.0 - p_transparency, 0, 1); -} - -void RasterizerSceneGLES3::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->fade_near = p_enable_near; - ginstance->fade_near_begin = p_near_begin; - ginstance->fade_near_end = p_near_end; - ginstance->fade_far = p_enable_far; - ginstance->fade_far_begin = p_far_begin; - ginstance->fade_far_end = p_far_end; -} - -void RasterizerSceneGLES3::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->parent_fade_alpha = p_alpha; -} - -void RasterizerSceneGLES3::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_baked_light = p_enable; - - _geometry_instance_mark_dirty(ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_dynamic_gi = p_enable; - _geometry_instance_mark_dirty(ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->shader_parameters_offset = p_offset; - _geometry_instance_mark_dirty(ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->cast_double_sided_shadows = p_enable; - _geometry_instance_mark_dirty(ginstance); -} - uint32_t RasterizerSceneGLES3::geometry_instance_get_pair_mask() { return (1 << RS::INSTANCE_LIGHT); } -void RasterizerSceneGLES3::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - +void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) { GLES3::Config *config = GLES3::Config::get_singleton(); - ginstance->omni_light_count = 0; - ginstance->spot_light_count = 0; - ginstance->omni_lights.clear(); - ginstance->spot_lights.clear(); + omni_light_count = 0; + spot_light_count = 0; + omni_lights.clear(); + spot_lights.clear(); for (uint32_t i = 0; i < p_light_instance_count; i++) { - RS::LightType type = light_instance_get_type(p_light_instances[i]); + RS::LightType type = RasterizerSceneGLES3::get_singleton()->light_instance_get_type(p_light_instances[i]); switch (type) { case RS::LIGHT_OMNI: { - if (ginstance->omni_light_count < (uint32_t)config->max_lights_per_object) { - ginstance->omni_lights.push_back(p_light_instances[i]); - ginstance->omni_light_count++; + if (omni_light_count < (uint32_t)config->max_lights_per_object) { + omni_lights.push_back(p_light_instances[i]); + omni_light_count++; } } break; case RS::LIGHT_SPOT: { - if (ginstance->spot_light_count < (uint32_t)config->max_lights_per_object) { - ginstance->spot_lights.push_back(p_light_instances[i]); - ginstance->spot_light_count++; + if (spot_light_count < (uint32_t)config->max_lights_per_object) { + spot_lights.push_back(p_light_instances[i]); + spot_light_count++; } } break; default: @@ -235,21 +90,7 @@ void RasterizerSceneGLES3::geometry_instance_pair_light_instances(GeometryInstan } } -void RasterizerSceneGLES3::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { -} - -void RasterizerSceneGLES3::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { -} - -void RasterizerSceneGLES3::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { -} - -void RasterizerSceneGLES3::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); -} - -void RasterizerSceneGLES3::geometry_instance_free(GeometryInstance *p_geometry_instance) { +void RasterizerSceneGLES3::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) { GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); GeometryInstanceSurface *surf = ginstance->surface_caches; @@ -262,24 +103,29 @@ void RasterizerSceneGLES3::geometry_instance_free(GeometryInstance *p_geometry_i geometry_instance_alloc.free(ginstance); } -void RasterizerSceneGLES3::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { - GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); - if (ginstance->dirty_list_element.in_list()) { +void RasterizerSceneGLES3::GeometryInstanceGLES3::_mark_dirty() { + if (dirty_list_element.in_list()) { return; } //clear surface caches - GeometryInstanceSurface *surf = ginstance->surface_caches; + GeometryInstanceSurface *surf = surface_caches; while (surf) { GeometryInstanceSurface *next = surf->next; - geometry_instance_surface_alloc.free(surf); + RasterizerSceneGLES3::get_singleton()->geometry_instance_surface_alloc.free(surf); surf = next; } - ginstance->surface_caches = nullptr; + surface_caches = nullptr; + + RasterizerSceneGLES3::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element); +} + +void RasterizerSceneGLES3::GeometryInstanceGLES3::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { +} - geometry_instance_dirty_list.add(&ginstance->dirty_list_element); +void RasterizerSceneGLES3::GeometryInstanceGLES3::set_lightmap_capture(const Color *p_sh9) { } void RasterizerSceneGLES3::_update_dirty_geometry_instances() { @@ -295,7 +141,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::Dep case Dependency::DEPENDENCY_CHANGED_PARTICLES: case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { - static_cast<RasterizerSceneGLES3 *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata); @@ -310,7 +156,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::Dep } void RasterizerSceneGLES3::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { - static_cast<RasterizerSceneGLES3 *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { @@ -467,7 +313,7 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface(GeometryInstanceGLES3 } } -void RasterizerSceneGLES3::_geometry_instance_update(GeometryInstance *p_geometry_instance) { +void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton(); GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); @@ -650,8 +496,7 @@ void RasterizerSceneGLES3::_update_dirty_skys() { while (sky) { if (sky->radiance == 0) { - sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) + 1; - + sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) - 2; // Left uninitialized, will attach a texture at render time glGenFramebuffers(1, &sky->radiance_framebuffer); @@ -715,13 +560,13 @@ void RasterizerSceneGLES3::_update_dirty_skys() { dirty_sky_list = nullptr; } -void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { +void RasterizerSceneGLES3::_setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); GLES3::SkyMaterialData *material = nullptr; - Sky *sky = sky_owner.get_or_null(p_env->sky); + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env)); RID sky_material; @@ -861,17 +706,17 @@ void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers, } } -void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); - Sky *sky = sky_owner.get_or_null(p_env->sky); + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env)); ERR_FAIL_COND(!sky); GLES3::SkyMaterialData *material_data = nullptr; RID sky_material; - RS::EnvironmentBG background = p_env->background; + RS::EnvironmentBG background = environment_get_background(p_env); if (sky) { ERR_FAIL_COND(!sky); @@ -901,18 +746,18 @@ void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_p ERR_FAIL_COND(!shader_data); // Camera - CameraMatrix camera; + Projection camera; - if (p_env->sky_custom_fov) { + if (environment_get_sky_custom_fov(p_env)) { float near_plane = p_projection.get_z_near(); float far_plane = p_projection.get_z_far(); float aspect = p_projection.get_aspect(); - camera.set_perspective(p_env->sky_custom_fov, aspect, near_plane, far_plane); + camera.set_perspective(environment_get_sky_custom_fov(p_env), aspect, near_plane, far_plane); } else { camera = p_projection; } - Basis sky_transform = p_env->sky_orientation; + Basis sky_transform = environment_get_sky_orientation(p_env); sky_transform.invert(); sky_transform = p_transform.basis * sky_transform; @@ -926,17 +771,17 @@ void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_p glDrawArrays(GL_TRIANGLES, 0, 3); } -void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); - Sky *sky = sky_owner.get_or_null(p_env->sky); + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env)); ERR_FAIL_COND(!sky); GLES3::SkyMaterialData *material_data = nullptr; RID sky_material; - RS::EnvironmentBG background = p_env->background; + RS::EnvironmentBG background = environment_get_background(p_env); if (sky) { ERR_FAIL_COND(!sky); @@ -990,7 +835,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Camera int max_processing_layer = sky->mipmap_count; // Update radiance cubemap - if (sky->reflection_dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) { + if (sky->reflection_dirty && (sky->processing_layer > max_processing_layer || update_single_frame)) { static const Vector3 view_normals[6] = { Vector3(+1, 0, 0), Vector3(-1, 0, 0), @@ -1008,9 +853,9 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Camera Vector3(0, -1, 0) }; - CameraMatrix cm; + Projection cm; cm.set_perspective(90, 1, 0.01, 10.0); - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); cm = correction * cm; @@ -1034,7 +879,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Camera } if (update_single_frame) { - for (int i = 0; i < max_processing_layer; i++) { + for (int i = 0; i <= max_processing_layer; i++) { _filter_sky_radiance(sky, i); } } else { @@ -1044,13 +889,52 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Camera sky->reflection_dirty = false; } else { - if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) { + if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer <= max_processing_layer) { _filter_sky_radiance(sky, sky->processing_layer); sky->processing_layer++; } } } +// Helper functions for IBL filtering + +Vector3 importance_sample_GGX(Vector2 xi, float roughness4) { + // Compute distribution direction + float phi = 2.0 * Math_PI * xi.x; + float cos_theta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y)); + float sin_theta = sqrt(1.0 - cos_theta * cos_theta); + + // Convert to spherical direction + Vector3 half_vector; + half_vector.x = sin_theta * cos(phi); + half_vector.y = sin_theta * sin(phi); + half_vector.z = cos_theta; + + return half_vector; +} + +float distribution_GGX(float NdotH, float roughness4) { + float NdotH2 = NdotH * NdotH; + float denom = (NdotH2 * (roughness4 - 1.0) + 1.0); + denom = Math_PI * denom * denom; + + return roughness4 / denom; +} + +float radical_inverse_vdC(uint32_t bits) { + bits = (bits << 16) | (bits >> 16); + bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >> 1); + bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >> 2); + bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >> 4); + bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >> 8); + + return float(bits) * 2.3283064365386963e-10; +} + +Vector2 hammersley(uint32_t i, uint32_t N) { + return Vector2(float(i) / float(N), radical_inverse_vdC(i)); +} + void RasterizerSceneGLES3::_filter_sky_radiance(Sky *p_sky, int p_base_layer) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); @@ -1062,21 +946,60 @@ void RasterizerSceneGLES3::_filter_sky_radiance(Sky *p_sky, int p_base_layer) { if (p_base_layer == 0) { glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + // Copy over base layer without filtering. mode = CubemapFilterShaderGLES3::MODE_COPY; - - //Copy over base layer } - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, sky_globals.radical_inverse_vdc_cache_tex); int size = p_sky->radiance_size >> p_base_layer; glViewport(0, 0, size, size); glBindVertexArray(sky_globals.screen_triangle_array); material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, mode); - material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::SAMPLE_COUNT, sky_globals.ggx_samples, scene_globals.cubemap_filter_shader_version, mode); - material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, float(p_base_layer) / (p_sky->mipmap_count - 1.0), scene_globals.cubemap_filter_shader_version, mode); - material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::FACE_SIZE, float(size), scene_globals.cubemap_filter_shader_version, mode); + + if (p_base_layer > 0) { + const uint32_t sample_counts[4] = { 1, sky_globals.ggx_samples / 4, sky_globals.ggx_samples / 2, sky_globals.ggx_samples }; + uint32_t sample_count = sample_counts[MIN(3, p_base_layer)]; + + float roughness = float(p_base_layer) / (p_sky->mipmap_count); + float roughness4 = roughness * roughness; + roughness4 *= roughness4; + + float solid_angle_texel = 4.0 * Math_PI / float(6 * size * size); + + LocalVector<float> sample_directions; + sample_directions.resize(4 * sample_count); + + uint32_t index = 0; + float weight = 0.0; + for (uint32_t i = 0; i < sample_count; i++) { + Vector2 xi = hammersley(i, sample_count); + Vector3 dir = importance_sample_GGX(xi, roughness4); + Vector3 light_vec = (2.0 * dir.z * dir - Vector3(0.0, 0.0, 1.0)); + + if (light_vec.z < 0.0) { + continue; + } + + sample_directions[index * 4] = light_vec.x; + sample_directions[index * 4 + 1] = light_vec.y; + sample_directions[index * 4 + 2] = light_vec.z; + + float D = distribution_GGX(dir.z, roughness4); + float pdf = D * dir.z / (4.0 * dir.z) + 0.0001; + + float solid_angle_sample = 1.0 / (float(sample_count) * pdf + 0.0001); + + float mip_level = MAX(0.5 * log2(solid_angle_sample / solid_angle_texel) + float(MAX(1, p_base_layer - 3)), 1.0); + + sample_directions[index * 4 + 3] = mip_level; + weight += light_vec.z; + index++; + } + + glUniform4fv(material_storage->shaders.cubemap_filter_shader.version_get_uniform(CubemapFilterShaderGLES3::SAMPLE_DIRECTIONS_MIP, scene_globals.cubemap_filter_shader_version, mode), sample_count, sample_directions.ptr()); + material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::WEIGHT, weight, scene_globals.cubemap_filter_shader_version, mode); + material_storage->shaders.cubemap_filter_shader.version_set_uniform(CubemapFilterShaderGLES3::SAMPLE_COUNT, index, scene_globals.cubemap_filter_shader_version, mode); + } for (int i = 0; i < 6; i++) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, p_sky->radiance, p_base_layer); @@ -1099,84 +1022,6 @@ Ref<Image> RasterizerSceneGLES3::sky_bake_panorama(RID p_sky, float p_energy, bo /* ENVIRONMENT API */ -RID RasterizerSceneGLES3::environment_allocate() { - return environment_owner.allocate_rid(); -} - -void RasterizerSceneGLES3::environment_initialize(RID p_rid) { - environment_owner.initialize_rid(p_rid); -} - -void RasterizerSceneGLES3::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->background = p_bg; -} - -void RasterizerSceneGLES3::environment_set_sky(RID p_env, RID p_sky) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky = p_sky; -} - -void RasterizerSceneGLES3::environment_set_sky_custom_fov(RID p_env, float p_scale) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky_custom_fov = p_scale; -} - -void RasterizerSceneGLES3::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky_orientation = p_orientation; -} - -void RasterizerSceneGLES3::environment_set_bg_color(RID p_env, const Color &p_color) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->bg_color = p_color; -} - -void RasterizerSceneGLES3::environment_set_bg_energy(RID p_env, float p_energy) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->bg_energy = p_energy; -} - -void RasterizerSceneGLES3::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->canvas_max_layer = p_max_layer; -} - -void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->ambient_light = p_color; - env->ambient_source = p_ambient; - env->ambient_light_energy = p_energy; - env->ambient_sky_contribution = p_sky_contribution; - env->reflection_source = p_reflection_source; -} - -void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7"); - env->glow_enabled = p_enable; - env->glow_levels = p_levels; - env->glow_intensity = p_intensity; - env->glow_strength = p_strength; - env->glow_mix = p_mix; - env->glow_bloom = p_bloom_threshold; - env->glow_blend_mode = p_blend_mode; - env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold; - env->glow_hdr_bleed_scale = p_hdr_bleed_scale; - env->glow_hdr_luminance_cap = p_hdr_luminance_cap; - env->glow_map_strength = p_glow_map_strength; - env->glow_map = p_glow_map; -} - void RasterizerSceneGLES3::environment_glow_set_use_bicubic_upscale(bool p_enable) { glow_bicubic_upscale = p_enable; } @@ -1185,35 +1030,15 @@ void RasterizerSceneGLES3::environment_glow_set_use_high_quality(bool p_enable) glow_high_quality = p_enable; } -void RasterizerSceneGLES3::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) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->ssr_enabled = p_enable; - env->ssr_max_steps = p_max_steps; - env->ssr_fade_in = p_fade_int; - env->ssr_fade_out = p_fade_out; - env->ssr_depth_tolerance = p_depth_tolerance; -} - void RasterizerSceneGLES3::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) { } -void RasterizerSceneGLES3::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) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); -} - void RasterizerSceneGLES3::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) { } -void RasterizerSceneGLES3::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) { -} void RasterizerSceneGLES3::environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) { } -void RasterizerSceneGLES3::environment_set_sdfgi(RID p_env, bool p_enable, int 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) { -} - void RasterizerSceneGLES3::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) { } @@ -1223,49 +1048,6 @@ void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_converge(RS::Environm void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) { } -void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->exposure = p_exposure; - env->tone_mapper = p_tone_mapper; - if (!env->auto_exposure && p_auto_exposure) { - env->auto_exposure_version = ++auto_exposure_counter; - } - env->auto_exposure = p_auto_exposure; - env->white = p_white; - env->min_luminance = p_min_luminance; - env->max_luminance = p_max_luminance; - env->auto_exp_speed = p_auto_exp_speed; - env->auto_exp_scale = p_auto_exp_scale; -} - -void RasterizerSceneGLES3::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) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->adjustments_enabled = p_enable; - env->adjustments_brightness = p_brightness; - env->adjustments_contrast = p_contrast; - env->adjustments_saturation = p_saturation; - env->use_1d_color_correction = p_use_1d_color_correction; - env->color_correction = p_color_correction; -} - -void RasterizerSceneGLES3::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) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->fog_enabled = p_enable; - env->fog_light_color = p_light_color; - env->fog_light_energy = p_light_energy; - env->fog_sun_scatter = p_sun_scatter; - env->fog_density = p_density; - env->fog_height = p_height; - env->fog_height_density = p_height_density; - env->fog_aerial_perspective = p_aerial_perspective; -} - -void RasterizerSceneGLES3::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { -} - void RasterizerSceneGLES3::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { } @@ -1273,27 +1055,9 @@ void RasterizerSceneGLES3::environment_set_volumetric_fog_filter_active(bool p_e } Ref<Image> RasterizerSceneGLES3::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Ref<Image>()); return Ref<Image>(); } -bool RasterizerSceneGLES3::is_environment(RID p_env) const { - return environment_owner.owns(p_env); -} - -RS::EnvironmentBG RasterizerSceneGLES3::environment_get_background(RID p_env) const { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); - return env->background; -} - -int RasterizerSceneGLES3::environment_get_canvas_max_layer(RID p_env) const { - Environment *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->canvas_max_layer; -} - RID RasterizerSceneGLES3::camera_effects_allocate() { return RID(); } @@ -1345,7 +1109,7 @@ void RasterizerSceneGLES3::light_instance_set_aabb(RID p_light_instance, const A light_instance->aabb = p_aabb; } -void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { +void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { } void RasterizerSceneGLES3::light_instance_mark_visible(RID p_light_instance) { @@ -1431,7 +1195,7 @@ bool RasterizerSceneGLES3::voxel_gi_needs_update(RID p_probe) const { return false; } -void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) { +void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { } void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) { @@ -1608,9 +1372,9 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const // Needs to be called after _setup_lights so that directional_light_count is accurate. void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(p_flip_y); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; //store camera into ubo GLES3::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); @@ -1633,18 +1397,17 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da scene_state.ubo.time = time; if (is_environment(p_render_data->environment)) { - Environment *env = environment_owner.get_or_null(p_render_data->environment); - RS::EnvironmentBG env_bg = env->background; - RS::EnvironmentAmbientSource ambient_src = env->ambient_source; + RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment); + RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment); - float bg_energy = env->bg_energy; + float bg_energy = environment_get_bg_energy(p_render_data->environment); scene_state.ubo.ambient_light_color_energy[3] = bg_energy; - scene_state.ubo.ambient_color_sky_mix = env->ambient_sky_contribution; + scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment); //ambient if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) { - Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : env->bg_color; + Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment); color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy; @@ -1653,14 +1416,14 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da scene_state.ubo.use_ambient_light = true; scene_state.ubo.use_ambient_cubemap = false; } else { - float energy = env->ambient_light_energy; - Color color = env->ambient_light; + float energy = environment_get_ambient_light_energy(p_render_data->environment); + Color color = environment_get_ambient_light(p_render_data->environment); color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; scene_state.ubo.ambient_light_color_energy[2] = color.b * energy; - Basis sky_transform = env->sky_orientation; + Basis sky_transform = environment_get_sky_orientation(p_render_data->environment); sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis; GLES3::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform); scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY; @@ -1668,27 +1431,27 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da } //specular - RS::EnvironmentReflectionSource ref_src = env->reflection_source; + RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment); if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) { scene_state.ubo.use_reflection_cubemap = true; } else { scene_state.ubo.use_reflection_cubemap = false; } - scene_state.ubo.fog_enabled = env->fog_enabled; - scene_state.ubo.fog_density = env->fog_density; - scene_state.ubo.fog_height = env->fog_height; - scene_state.ubo.fog_height_density = env->fog_height_density; - scene_state.ubo.fog_aerial_perspective = env->fog_aerial_perspective; + scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment); + scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); + scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); + scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); + scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment); - Color fog_color = env->fog_light_color.srgb_to_linear(); - float fog_energy = env->fog_light_energy; + Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear(); + float fog_energy = environment_get_fog_light_energy(p_render_data->environment); scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - scene_state.ubo.fog_sun_scatter = env->fog_sun_scatter; + scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment); } else { } @@ -1905,7 +1668,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b glBindBuffer(GL_UNIFORM_BUFFER, 0); } -void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info) { +void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); RENDER_TIMESTAMP("Setup 3D Scene"); @@ -1970,7 +1733,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * // Fill Light lists here ////////// - GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_variables_get_uniform_buffer(); + GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_uniforms_get_uniform_buffer(); glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer); Color clear_color; @@ -1980,8 +1743,6 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * clear_color = texture_storage->get_default_clear_color(); } - Environment *env = environment_owner.get_or_null(p_environment); - bool fb_cleared = false; Size2i screen_size; @@ -1991,10 +1752,10 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * bool use_wireframe = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME; SceneState::TonemapUBO tonemap_ubo; - if (env) { - tonemap_ubo.exposure = env->exposure; - tonemap_ubo.white = env->white; - tonemap_ubo.tonemapper = int32_t(env->tone_mapper); + if (render_data.environment.is_valid()) { + tonemap_ubo.exposure = environment_get_exposure(render_data.environment); + tonemap_ubo.white = environment_get_white(render_data.environment); + tonemap_ubo.tonemapper = int32_t(environment_get_tone_mapper(render_data.environment)); } if (scene_state.tonemap_buffer == 0) { @@ -2017,25 +1778,25 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black - } else if (env) { - RS::EnvironmentBG bg_mode = env->background; - float bg_energy = env->bg_energy; + } else if (render_data.environment.is_valid()) { + RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment); + float bg_energy = environment_get_bg_energy(render_data.environment); switch (bg_mode) { case RS::ENV_BG_CLEAR_COLOR: { clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if (env->fog_enabled) { + if (environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); } } break; case RS::ENV_BG_COLOR: { - clear_color = env->bg_color; + clear_color = environment_get_bg_color(render_data.environment); clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if (env->fog_enabled) { + if (environment_get_fog_enabled(render_data.environment)) { draw_sky_fog_only = true; GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color)); } @@ -2055,20 +1816,20 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * } } // setup sky if used for ambient, reflections, or background - if (draw_sky || draw_sky_fog_only || env->reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || env->ambient_source == RS::ENV_AMBIENT_SOURCE_SKY) { + if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); - CameraMatrix projection = render_data.cam_projection; + Projection projection = render_data.cam_projection; if (render_data.reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); projection = correction * render_data.cam_projection; } - _setup_sky(env, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size); + _setup_sky(render_data.environment, p_render_buffers, *render_data.lights, projection, render_data.cam_transform, screen_size); - if (env->sky.is_valid()) { - if (env->reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || env->ambient_source == RS::ENV_AMBIENT_SOURCE_SKY || (env->reflection_source == RS::ENV_REFLECTION_SOURCE_BG && env->background == RS::ENV_BG_SKY)) { - _update_sky_radiance(env, projection, render_data.cam_transform); + if (environment_get_sky(render_data.environment).is_valid()) { + if (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(render_data.environment) == RS::ENV_AMBIENT_SOURCE_SKY || (environment_get_reflection_source(render_data.environment) == RS::ENV_REFLECTION_SOURCE_BG && environment_get_background(render_data.environment) == RS::ENV_BG_SKY)) { + _update_sky_radiance(render_data.environment, projection, render_data.cam_transform); } } else { // do not try to draw sky if invalid @@ -2148,7 +1909,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS; } - if (!env || (env && !env->fog_enabled)) { + if (render_data.environment.is_null() || (render_data.environment.is_valid() && !environment_get_fog_enabled(render_data.environment))) { spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG; } } @@ -2172,7 +1933,7 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED; scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK; - _draw_sky(env, render_data.cam_projection, render_data.cam_transform); + _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform); } RENDER_TIMESTAMP("Render 3D Transparent Pass"); @@ -2221,11 +1982,10 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } if (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) { - Environment *env = environment_owner.get_or_null(p_render_data->environment); glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 2); GLuint texture_to_bind = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_CUBEMAP_BLACK))->tex_id; - if (env) { - Sky *sky = sky_owner.get_or_null(env->sky); + if (p_render_data->environment.is_valid()) { + Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment)); if (sky && sky->radiance != 0) { texture_to_bind = sky->radiance; // base_spec_constant |= USE_RADIANCE_MAP; @@ -2490,10 +2250,10 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } } -void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { } -void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) { +void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) { } void RasterizerSceneGLES3::set_time(double p_time, double p_step) { @@ -2510,7 +2270,7 @@ RID RasterizerSceneGLES3::render_buffers_create() { return render_buffers_owner.make_rid(rb); } -void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { +void RasterizerSceneGLES3::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); @@ -2624,8 +2384,8 @@ TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const Vector } bool RasterizerSceneGLES3::free(RID p_rid) { - if (environment_owner.owns(p_rid)) { - environment_owner.free(p_rid); + if (is_environment(p_rid)) { + environment_free(p_rid); } else if (sky_owner.owns(p_rid)) { Sky *sky = sky_owner.get_or_null(p_rid); ERR_FAIL_COND_V(!sky, false); @@ -2705,7 +2465,7 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { { String global_defines; - global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now + global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now global_defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(config->max_renderable_lights) + "\n"; global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n"; global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "\n"; @@ -2744,13 +2504,17 @@ void fragment() { sky_globals.ggx_samples = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples"); String global_defines; - global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now + global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_globals.max_directional_lights) + "\n"; material_storage->shaders.sky_shader.initialize(global_defines); sky_globals.shader_default_version = material_storage->shaders.sky_shader.version_create(); material_storage->shaders.sky_shader.version_bind_shader(sky_globals.shader_default_version, SkyShaderGLES3::MODE_BACKGROUND); + } - material_storage->shaders.cubemap_filter_shader.initialize(); + { + String global_defines; + global_defines += "\n#define MAX_SAMPLE_COUNT " + itos(sky_globals.ggx_samples) + "\n"; + material_storage->shaders.cubemap_filter_shader.initialize(global_defines); scene_globals.cubemap_filter_shader_version = material_storage->shaders.cubemap_filter_shader.version_create(); material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, CubemapFilterShaderGLES3::MODE_DEFAULT); } @@ -2820,36 +2584,6 @@ void sky() { glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind } - // Radical inverse vdc cache texture used for cubemap filtering. - { - glGenTextures(1, &sky_globals.radical_inverse_vdc_cache_tex); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, sky_globals.radical_inverse_vdc_cache_tex); - - uint8_t radical_inverse[512]; - - for (uint32_t i = 0; i < 512; i++) { - uint32_t bits = i; - - bits = (bits << 16) | (bits >> 16); - bits = ((bits & 0x55555555) << 1) | ((bits & 0xAAAAAAAA) >> 1); - bits = ((bits & 0x33333333) << 2) | ((bits & 0xCCCCCCCC) >> 2); - bits = ((bits & 0x0F0F0F0F) << 4) | ((bits & 0xF0F0F0F0) >> 4); - bits = ((bits & 0x00FF00FF) << 8) | ((bits & 0xFF00FF00) >> 8); - - float value = float(bits) * 2.3283064365386963e-10; - radical_inverse[i] = uint8_t(CLAMP(value * 255.0, 0, 255)); - } - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 512, 1, 0, GL_RED, GL_UNSIGNED_BYTE, radical_inverse); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //need this for proper sampling - - glBindTexture(GL_TEXTURE_2D, 0); - } #ifdef GLES_OVER_GL glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS); #endif diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 4222743cec..e227b2df82 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RASTERIZER_SCENE_OPENGL_H -#define RASTERIZER_SCENE_OPENGL_H +#ifndef RASTERIZER_SCENE_GLES3_H +#define RASTERIZER_SCENE_GLES3_H #ifdef GLES3_ENABLED -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/paged_allocator.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" @@ -96,18 +96,18 @@ struct RenderDataGLES3 { Transform3D cam_transform = Transform3D(); Transform3D inv_cam_transform = Transform3D(); - CameraMatrix cam_projection = CameraMatrix(); + Projection cam_projection = Projection(); bool cam_orthogonal = false; // For stereo rendering uint32_t view_count = 1; Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS]; - CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; float z_near = 0.0; float z_far = 0.0; - const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr; + const PagedArray<RenderGeometryInstance *> *instances = nullptr; const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *reflection_probes = nullptr; RID environment = RID(); @@ -210,7 +210,7 @@ private: mutable RID_Owner<LightInstance> light_instance_owner; - struct GeometryInstanceGLES3; + class GeometryInstanceGLES3; // Cached data for drawing surfaces struct GeometryInstanceSurface { @@ -265,33 +265,16 @@ private: GeometryInstanceGLES3 *owner = nullptr; }; - struct GeometryInstanceGLES3 : public GeometryInstance { + class GeometryInstanceGLES3 : public RenderGeometryInstanceBase { + public: //used during rendering - bool mirror = false; - bool non_uniform_scale = false; - float lod_bias = 0.0; - float lod_model_scale = 1.0; - AABB transformed_aabb; //needed for LOD - float depth = 0; - uint32_t flags_cache = 0; bool store_transform_cache = true; - int32_t shader_parameters_offset = -1; - uint32_t layer_mask = 1; int32_t instance_count = 0; - RID mesh_instance; bool can_sdfgi = false; bool using_projectors = false; bool using_softshadows = false; - bool fade_near = false; - float fade_near_begin = 0; - float fade_near_end = 0; - bool fade_far = false; - float fade_far_begin = 0; - float fade_far_end = 0; - float force_alpha = 1.0; - float parent_fade_alpha = 1.0; uint32_t omni_light_count = 0; LocalVector<RID> omni_lights; @@ -301,35 +284,22 @@ private: LocalVector<uint32_t> spot_light_gl_cache; //used during setup - uint32_t base_flags = 0; - Transform3D transform; GeometryInstanceSurface *surface_caches = nullptr; SelfList<GeometryInstanceGLES3> dirty_list_element; - struct Data { - //data used less often goes into regular heap - RID base; - RS::InstanceType base_type; - - RID skeleton; - Vector<RID> surface_materials; - RID material_override; - RID material_overlay; - AABB aabb; - - bool use_dynamic_gi = false; - bool use_baked_light = false; - bool cast_double_sided_shadows = false; - bool mirror = false; - bool dirty_dependencies = false; + GeometryInstanceGLES3() : + dirty_list_element(this) {} - DependencyTracker dependency_tracker; - }; + virtual void _mark_dirty() override; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; + virtual void set_lightmap_capture(const Color *p_sh9) override; - Data *data = nullptr; + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override; + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} - GeometryInstanceGLES3() : - dirty_list_element(this) {} + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override {} }; enum { @@ -357,8 +327,7 @@ private: void _geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); void _geometry_instance_add_surface_with_material_chain(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, RID p_mat_src, RID p_mesh); void _geometry_instance_add_surface(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); - void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); - void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance); void _update_dirty_geometry_instances(); struct SceneState { @@ -570,88 +539,8 @@ protected: /* Environment */ - struct Environment { - // BG - RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR; - RID sky; - float sky_custom_fov = 0.0; - Basis sky_orientation; - Color bg_color; - float bg_energy = 1.0; - int canvas_max_layer = 0; - RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG; - Color ambient_light; - float ambient_light_energy = 1.0; - float ambient_sky_contribution = 1.0; - RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG; - Color ao_color; - - /// Tonemap - - RS::EnvironmentToneMapper tone_mapper; - float exposure = 1.0; - float white = 1.0; - bool auto_exposure = false; - float min_luminance = 0.2; - float max_luminance = 8.0; - float auto_exp_speed = 0.2; - float auto_exp_scale = 0.5; - uint64_t auto_exposure_version = 0; - - // Fog - bool fog_enabled = false; - Color fog_light_color = Color(0.5, 0.6, 0.7); - float fog_light_energy = 1.0; - float fog_sun_scatter = 0.0; - float fog_density = 0.001; - float fog_height = 0.0; - float fog_height_density = 0.0; //can be negative to invert effect - float fog_aerial_perspective = 0.0; - - /// Glow - bool glow_enabled = false; - Vector<float> glow_levels; - float glow_intensity = 0.8; - float glow_strength = 1.0; - float glow_bloom = 0.0; - float glow_mix = 0.01; - RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT; - float glow_hdr_bleed_threshold = 1.0; - float glow_hdr_luminance_cap = 12.0; - float glow_hdr_bleed_scale = 2.0; - float glow_map_strength = 1.0; - RID glow_map = RID(); - - /// SSAO - bool ssao_enabled = false; - float ssao_radius = 1.0; - float ssao_intensity = 2.0; - float ssao_power = 1.5; - float ssao_detail = 0.5; - float ssao_horizon = 0.06; - float ssao_sharpness = 0.98; - float ssao_direct_light_affect = 0.0; - float ssao_ao_channel_affect = 0.0; - - /// SSR - bool ssr_enabled = false; - int ssr_max_steps = 64; - float ssr_fade_in = 0.15; - float ssr_fade_out = 2.0; - float ssr_depth_tolerance = 0.2; - - /// Adjustments - bool adjustments_enabled = false; - float adjustments_brightness = 1.0f; - float adjustments_contrast = 1.0f; - float adjustments_saturation = 1.0f; - bool use_1d_color_correction = false; - RID color_correction = RID(); - }; - RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM; bool ssao_half_size = false; - bool ssao_using_half_size = false; float ssao_adaptive_target = 0.5; int ssao_blur_passes = 2; float ssao_fadeout_from = 50.0; @@ -661,10 +550,6 @@ protected: bool glow_high_quality = false; RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW; - static uint64_t auto_exposure_counter; - - mutable RID_Owner<Environment, true> environment_owner; - /* Sky */ struct SkyGlobals { @@ -730,44 +615,23 @@ protected: Sky *dirty_sky_list = nullptr; mutable RID_Owner<Sky, true> sky_owner; - void _setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); + void _setup_sky(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); void _invalidate_sky(Sky *p_sky); void _update_dirty_skys(); - void _update_sky_radiance(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform); + void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform); void _filter_sky_radiance(Sky *p_sky, int p_base_layer); - void _draw_sky(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform); + void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform); void _free_sky_data(Sky *p_sky); public: + static RasterizerSceneGLES3 *get_singleton() { return singleton; } + RasterizerCanvasGLES3 *canvas; - GeometryInstance *geometry_instance_create(RID p_base) override; - void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override; - void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override; - void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) override; - void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override; - void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override; - void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override; - void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override; - void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override; - void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override; - void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; - void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override; - void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override; - void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override; - void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; - void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override; - void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override; - void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override; + RenderGeometryInstance *geometry_instance_create(RID p_base) override; + void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; uint32_t geometry_instance_get_pair_mask() override; - void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override; - void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; - void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; - void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; - - void geometry_instance_free(GeometryInstance *p_geometry_instance) override; /* SHADOW ATLAS API */ @@ -804,49 +668,24 @@ public: /* ENVIRONMENT API */ - RID environment_allocate() override; - 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; - void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override; - void environment_set_bg_color(RID p_env, const Color &p_color) override; - void environment_set_bg_energy(RID p_env, float p_energy) override; - void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override; - void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override; - - void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override; void environment_glow_set_use_bicubic_upscale(bool p_enable) override; void environment_glow_set_use_high_quality(bool p_enable) override; - 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) override; void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override; - 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_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override; - void environment_set_ssil_quality(RS::EnvironmentSSILQuality 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, int 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_ssil_quality(RS::EnvironmentSSILQuality 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_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override; void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override; void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override; - void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override; - - 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_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) 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; Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override; - bool is_environment(RID p_env) const override; - RS::EnvironmentBG environment_get_background(RID p_env) const override; - int environment_get_canvas_max_layer(RID p_env) const override; - RID camera_effects_allocate() override; void camera_effects_initialize(RID p_rid) override; void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override; @@ -861,7 +700,7 @@ public: RID light_instance_create(RID p_light) override; void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override; void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override; - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override; + void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override; void light_instance_mark_visible(RID p_light_instance) override; _FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) { @@ -900,13 +739,13 @@ public: RID voxel_gi_instance_create(RID p_voxel_gi) override; void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override; bool voxel_gi_needs_update(RID p_probe) const override; - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override; + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) override; void voxel_gi_set_quality(RS::VoxelGIQuality) override; - void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info = nullptr) override; - void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override; + void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info = nullptr) override; + void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override; void set_scene_pass(uint64_t p_pass) override { scene_pass = p_pass; @@ -923,7 +762,7 @@ public: } RID render_buffers_create() override; - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; + void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; void gi_set_use_half_resolution(bool p_enable) override; void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override; @@ -941,11 +780,10 @@ public: void decals_set_filter(RS::DecalFilter p_filter) override; void light_projectors_set_filter(RS::LightProjectorFilter p_filter) override; - static RasterizerSceneGLES3 *get_singleton(); RasterizerSceneGLES3(); ~RasterizerSceneGLES3(); }; #endif // GLES3_ENABLED -#endif // RASTERIZER_SCENE_OPENGL_H +#endif // RASTERIZER_SCENE_GLES3_H diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index e1385669cd..2b72549b5b 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHADER_OPENGL_H -#define SHADER_OPENGL_H +#ifndef SHADER_GLES3_H +#define SHADER_GLES3_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/os/mutex.h" #include "core/string/string_builder.h" #include "core/templates/hash_map.h" @@ -248,5 +248,6 @@ public: virtual ~ShaderGLES3(); }; -#endif // SHADER_OPENGL_H -#endif +#endif // GLES3_ENABLED + +#endif // SHADER_GLES3_H diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl index e08a15e59d..852dccf415 100644 --- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl +++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl @@ -58,8 +58,8 @@ struct DrawData { uvec4 lights; }; -layout(std140) uniform GlobalVariableData { //ubo:1 - vec4 global_variables[MAX_GLOBAL_VARIABLES]; +layout(std140) uniform GlobalShaderUniformData { //ubo:1 + vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; layout(std140) uniform CanvasData { //ubo:0 diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index ebf0c08ec4..57f0d7d0b8 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -29,19 +29,15 @@ uniform samplerCube source_cube; //texunit:0 /* clang-format on */ uniform int face_id; -uniform float roughness; -uniform float face_size; -uniform int sample_count; -//Todo, profile on low end hardware to see if fixed loop is faster -#ifdef USE_FIXED_SAMPLES -#define FIXED_SAMPLE_COUNT 32 +#ifndef MODE_DIRECT_WRITE +uniform int sample_count; +uniform vec4 sample_directions_mip[MAX_SAMPLE_COUNT]; +uniform float weight; #endif in highp vec2 uv_interp; -uniform sampler2D radical_inverse_vdc_cache; // texunit:1 - layout(location = 0) out vec4 frag_color; #define M_PI 3.14159265359 @@ -93,48 +89,6 @@ vec3 texelCoordToVec(vec2 uv, int faceID) { return normalize(result); } -vec3 ImportanceSampleGGX(vec2 xi, float roughness4) { - // Compute distribution direction - float Phi = 2.0 * M_PI * xi.x; - float CosTheta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y)); - float SinTheta = sqrt(1.0 - CosTheta * CosTheta); - - // Convert to spherical direction - vec3 H; - H.x = SinTheta * cos(Phi); - H.y = SinTheta * sin(Phi); - H.z = CosTheta; - - return H; -} - -float DistributionGGX(float NdotH, float roughness4) { - float NdotH2 = NdotH * NdotH; - float denom = (NdotH2 * (roughness4 - 1.0) + 1.0); - denom = M_PI * denom * denom; - - return roughness4 / denom; -} - -// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float GGX(float NdotV, float a) { - float k = a / 2.0; - return NdotV / (NdotV * (1.0 - k) + k); -} - -// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float G_Smith(float a, float nDotV, float nDotL) { - return GGX(nDotL, a * a) * GGX(nDotV, a * a); -} - -float radical_inverse_VdC(int i) { - return texture(radical_inverse_vdc_cache, vec2(float(i) / 512.0, 0.0)).x; -} - -vec2 Hammersley(int i, int N) { - return vec2(float(i) / float(N), radical_inverse_VdC(i)); -} - void main() { vec3 color = vec3(0.0); vec2 uv = uv_interp; @@ -145,9 +99,6 @@ void main() { #else vec4 sum = vec4(0.0); - float solid_angle_texel = 4.0 * M_PI / (6.0 * face_size * face_size); - float roughness2 = roughness * roughness; - float roughness4 = roughness2 * roughness2; vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); mat3 T; T[0] = normalize(cross(UpVector, N)); @@ -155,32 +106,15 @@ void main() { T[2] = N; for (int sample_num = 0; sample_num < sample_count; sample_num++) { - vec2 xi = Hammersley(sample_num, sample_count); - - vec3 H = T * ImportanceSampleGGX(xi, roughness4); - float NdotH = dot(N, H); - vec3 L = (2.0 * NdotH * H - N); - - float NdotL = clamp(dot(N, L), 0.0, 1.0); - - if (NdotL > 0.0) { - float D = DistributionGGX(NdotH, roughness4); - float pdf = D * NdotH / (4.0 * NdotH) + 0.0001; - - float solid_angle_sample = 1.0 / (float(sample_count) * pdf + 0.0001); - - float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(solid_angle_sample / solid_angle_texel); - - vec3 val = textureLod(source_cube, L, mipLevel).rgb; - // Mix using linear - val = srgb_to_linear(val); - - sum.rgb += val * NdotL; - sum.a += NdotL; - } + vec4 sample = sample_directions_mip[sample_num]; + vec3 L = T * sample.xyz; + vec3 val = textureLod(source_cube, L, sample.w).rgb; + // Mix using linear + val = srgb_to_linear(val); + sum.rgb += val * sample.z; } - sum /= sum.a; + sum /= weight; sum.rgb = linear_to_srgb(sum.rgb); frag_color = vec4(sum.rgb, 1.0); diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 4f2be8bf60..cd88ba6cb7 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -104,8 +104,8 @@ layout(location = 14) in highp vec4 instance_xform2; layout(location = 15) in highp uvec4 instance_color_custom_data; // Color packed into xy, Custom data into zw. #endif -layout(std140) uniform GlobalVariableData { //ubo:1 - vec4 global_variables[MAX_GLOBAL_VARIABLES]; +layout(std140) uniform GlobalShaderUniformData { //ubo:1 + vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; layout(std140) uniform SceneData { // ubo:2 @@ -399,8 +399,8 @@ uniform samplerCube radiance_map; // texunit:-2 #endif -layout(std140) uniform GlobalVariableData { //ubo:1 - vec4 global_variables[MAX_GLOBAL_VARIABLES]; +layout(std140) uniform GlobalShaderUniformData { //ubo:1 + vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; /* Material Uniforms */ diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl index 50ab38bc31..eb1befe38e 100644 --- a/drivers/gles3/shaders/sky.glsl +++ b/drivers/gles3/shaders/sky.glsl @@ -42,8 +42,8 @@ uniform sampler2D half_res; //texunit:-2 uniform sampler2D quarter_res; //texunit:-3 #endif -layout(std140) uniform GlobalVariableData { //ubo:1 - vec4 global_variables[MAX_GLOBAL_VARIABLES]; +layout(std140) uniform GlobalShaderUniformData { //ubo:1 + vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; struct DirectionalLightData { diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index db76aa79fb..b83c83f425 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -90,4 +90,4 @@ public: #endif // GLES3_ENABLED -#endif // !CONFIG_GLES3_H +#endif // CONFIG_GLES3_H diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h index 575ab93eab..857a0261fa 100644 --- a/drivers/gles3/storage/light_storage.h +++ b/drivers/gles3/storage/light_storage.h @@ -342,6 +342,6 @@ public: } // namespace GLES3 -#endif // !GLES3_ENABLED +#endif // GLES3_ENABLED -#endif // !LIGHT_STORAGE_GLES3_H +#endif // LIGHT_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 8a8d79b3f7..117481faf5 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -176,75 +176,98 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } break; case ShaderLanguage::TYPE_IVEC2: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 2 * p_array_size; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 2 * p_array_size; - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 2, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - } else { - gui[j] = 0; - gui[j + 1] = 0; + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 2, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + } + gui[j + 2] = 0; // ignored + gui[j + 3] = 0; // ignored } - gui[j + 2] = 0; // ignored - gui[j + 3] = 0; // ignored + } else { + Vector2i v = value; + gui[0] = v.x; + gui[1] = v.y; } } break; case ShaderLanguage::TYPE_IVEC3: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 3 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 3, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - gui[j + 2] = r[i + 2]; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); + + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 3 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 3, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + gui[j + 2] = r[i + 2]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored } - gui[j + 3] = 0; // ignored + } else { + Vector3i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; } } break; case ShaderLanguage::TYPE_IVEC4: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 4 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0; i < count; i += 4) { - if (i < s) { - gui[i] = r[i]; - gui[i + 1] = r[i + 1]; - gui[i + 2] = r[i + 2]; - gui[i + 3] = r[i + 3]; - } else { - gui[i] = 0; - gui[i + 1] = 0; - gui[i + 2] = 0; - gui[i + 3] = 0; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); + + if (p_array_size <= 0) { + p_array_size = 1; } + int count = 4 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0; i < count; i += 4) { + if (i < s) { + gui[i] = r[i]; + gui[i + 1] = r[i + 1]; + gui[i + 2] = r[i + 2]; + gui[i + 3] = r[i + 3]; + } else { + gui[i] = 0; + gui[i + 1] = 0; + gui[i + 2] = 0; + gui[i + 3] = 0; + } + } + } else { + Vector4i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } break; case ShaderLanguage::TYPE_UINT: { @@ -271,75 +294,98 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } break; case ShaderLanguage::TYPE_UVEC2: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 2 * p_array_size; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 2 * p_array_size; - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 2, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - } else { - gui[j] = 0; - gui[j + 1] = 0; + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 2, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + } + gui[j + 2] = 0; // ignored + gui[j + 3] = 0; // ignored } - gui[j + 2] = 0; // ignored - gui[j + 3] = 0; // ignored + } else { + Vector2i v = value; + gui[0] = v.x; + gui[1] = v.y; } } break; case ShaderLanguage::TYPE_UVEC3: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 3 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 3, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - gui[j + 2] = r[i + 2]; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); + + if (p_array_size <= 0) { + p_array_size = 1; } - gui[j + 3] = 0; // ignored + int count = 3 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 3, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + gui[j + 2] = r[i + 2]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored + } + } else { + Vector3i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; } } break; case ShaderLanguage::TYPE_UVEC4: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 4 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0; i < count; i++) { - if (i < s) { - gui[i] = r[i]; - gui[i + 1] = r[i + 1]; - gui[i + 2] = r[i + 2]; - gui[i + 3] = r[i + 3]; - } else { - gui[i] = 0; - gui[i + 1] = 0; - gui[i + 2] = 0; - gui[i + 3] = 0; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); + + if (p_array_size <= 0) { + p_array_size = 1; } + int count = 4 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0; i < count; i++) { + if (i < s) { + gui[i] = r[i]; + gui[i + 1] = r[i + 1]; + gui[i + 2] = r[i + 2]; + gui[i + 3] = r[i + 3]; + } else { + gui[i] = 0; + gui[i + 1] = 0; + gui[i + 2] = 0; + gui[i + 3] = 0; + } + } + } else { + Vector4i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } break; case ShaderLanguage::TYPE_FLOAT: { @@ -504,6 +550,13 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[1] = v.y; gui[2] = v.z; gui[3] = v.w; + } else if (value.get_type() == Variant::VECTOR4) { + Vector4 v = value; + + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } else { Plane v = value; @@ -660,7 +713,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[i + 15] = 1; } } - } else { + } else if (value.get_type() == Variant::TRANSFORM3D) { Transform3D v = value; gui[0] = v.basis.rows[0][0]; gui[1] = v.basis.rows[1][0]; @@ -681,6 +734,13 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[13] = v.origin.y; gui[14] = v.origin.z; gui[15] = 1; + } else { + Projection v = value; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + gui[i * 4 + j] = v.matrix[i][j]; + } + } } } break; default: { @@ -937,7 +997,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { //this is a global variable, get the index to it - GlobalVariables::Variable *gv = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *gv = material_storage->global_shader_uniforms.variables.getptr(E.key); uint32_t index = 0; if (gv) { index = gv->buffer_index; @@ -993,9 +1053,9 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (uses_global_buffer != (global_buffer_E != nullptr)) { if (uses_global_buffer) { - global_buffer_E = material_storage->global_variables.materials_using_buffer.push_back(self); + global_buffer_E = material_storage->global_shader_uniforms.materials_using_buffer.push_back(self); } else { - material_storage->global_variables.materials_using_buffer.erase(global_buffer_E); + material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E); global_buffer_E = nullptr; } } @@ -1006,20 +1066,20 @@ MaterialData::~MaterialData() { if (global_buffer_E) { //unregister global buffers - material_storage->global_variables.materials_using_buffer.erase(global_buffer_E); + material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E); } if (global_texture_E) { //unregister global textures for (const KeyValue<StringName, uint64_t> &E : used_global_textures) { - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } } //unregister material from those using global textures - material_storage->global_variables.materials_using_texture.erase(global_texture_E); + material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E); } if (uniform_buffer) { @@ -1050,7 +1110,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet if (p_texture_uniforms[i].global) { uses_global_textures = true; - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(uniform_name); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name); if (v) { if (v->buffer_index >= 0) { WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); @@ -1222,7 +1282,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet if (E.value != global_textures_pass) { to_delete.push_back(E.key); - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } @@ -1236,9 +1296,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet //handle registering/unregistering global textures if (uses_global_textures != (global_texture_E != nullptr)) { if (uses_global_textures) { - global_texture_E = material_storage->global_variables.materials_using_texture.push_back(self); + global_texture_E = material_storage->global_shader_uniforms.materials_using_texture.push_back(self); } else { - material_storage->global_variables.materials_using_texture.erase(global_texture_E); + material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E); global_texture_E = nullptr; } } @@ -1305,22 +1365,22 @@ MaterialStorage::MaterialStorage() { material_data_request_func[RS::SHADER_SKY] = _create_sky_material_func; material_data_request_func[RS::SHADER_FOG] = nullptr; - static_assert(sizeof(GlobalVariables::Value) == 16); + static_assert(sizeof(GlobalShaderUniforms::Value) == 16); - global_variables.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); - if (global_variables.buffer_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) { - global_variables.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size); + global_shader_uniforms.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); + if (global_shader_uniforms.buffer_size > uint32_t(Config::get_singleton()->max_uniform_buffer_size)) { + global_shader_uniforms.buffer_size = uint32_t(Config::get_singleton()->max_uniform_buffer_size); WARN_PRINT("Project setting: rendering/limits/global_shader_variables/buffer_size exceeds maximum uniform buffer size of: " + itos(Config::get_singleton()->max_uniform_buffer_size)); } - global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size); - memset(global_variables.buffer_values, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size); - global_variables.buffer_usage = memnew_arr(GlobalVariables::ValueUsage, global_variables.buffer_size); - global_variables.buffer_dirty_regions = memnew_arr(bool, global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); - memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); - glGenBuffers(1, &global_variables.buffer); - glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalVariables::Value) * global_variables.buffer_size, nullptr, GL_DYNAMIC_DRAW); + global_shader_uniforms.buffer_values = memnew_arr(GlobalShaderUniforms::Value, global_shader_uniforms.buffer_size); + memset(global_shader_uniforms.buffer_values, 0, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer_usage = memnew_arr(GlobalShaderUniforms::ValueUsage, global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer_dirty_regions = memnew_arr(bool, global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); + memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); + glGenBuffers(1, &global_shader_uniforms.buffer); + glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, nullptr, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); { @@ -1458,7 +1518,7 @@ MaterialStorage::MaterialStorage() { actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; - actions.renames["FOG"] = "custom_fog"; + actions.renames["FOG"] = "fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; actions.renames["BONE_INDICES"] = "bone_attrib"; @@ -1614,7 +1674,7 @@ ShaderCompiler::DefaultIdentifierActions actions; actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; particles_shader.compiler.initialize(actions); */ @@ -1676,25 +1736,25 @@ ShaderCompiler::DefaultIdentifierActions actions; MaterialStorage::~MaterialStorage() { //shaders.copy.version_free(shaders.copy_version); - memdelete_arr(global_variables.buffer_values); - memdelete_arr(global_variables.buffer_usage); - memdelete_arr(global_variables.buffer_dirty_regions); - glDeleteBuffers(1, &global_variables.buffer); + memdelete_arr(global_shader_uniforms.buffer_values); + memdelete_arr(global_shader_uniforms.buffer_usage); + memdelete_arr(global_shader_uniforms.buffer_dirty_regions); + glDeleteBuffers(1, &global_shader_uniforms.buffer); singleton = nullptr; } -/* GLOBAL VARIABLE API */ +/* GLOBAL SHADER UNIFORM API */ -int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) { +int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) { int32_t idx = 0; - while (idx + p_elements <= global_variables.buffer_size) { - if (global_variables.buffer_usage[idx].elements == 0) { + while (idx + p_elements <= global_shader_uniforms.buffer_size) { + if (global_shader_uniforms.buffer_usage[idx].elements == 0) { bool valid = true; for (uint32_t i = 1; i < p_elements; i++) { - if (global_variables.buffer_usage[idx + i].elements > 0) { + if (global_shader_uniforms.buffer_usage[idx + i].elements > 0) { valid = false; - idx += i + global_variables.buffer_usage[idx + i].elements; + idx += i + global_shader_uniforms.buffer_usage[idx + i].elements; break; } } @@ -1705,17 +1765,17 @@ int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) { return idx; } else { - idx += global_variables.buffer_usage[idx].elements; + idx += global_shader_uniforms.buffer_usage[idx].elements; } } return -1; } -void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { +void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; bool b = p_value; bv.x = b ? 1.0 : 0.0; bv.y = 0.0; @@ -1724,7 +1784,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_BVEC2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1732,7 +1792,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0.0; } break; case RS::GLOBAL_VAR_TYPE_BVEC3: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1740,7 +1800,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0.0; } break; case RS::GLOBAL_VAR_TYPE_BVEC4: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1748,7 +1808,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = (bvec & 8) ? 1.0 : 0.0; } break; case RS::GLOBAL_VAR_TYPE_INT: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; int32_t v = p_value; bv.x = v; bv.y = 0; @@ -1756,7 +1816,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC2: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector2i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1764,7 +1824,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC3: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector3i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1772,7 +1832,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC4: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector<int32_t> v = p_value; bv.x = v.size() >= 1 ? v[0] : 0; bv.y = v.size() >= 2 ? v[1] : 0; @@ -1780,7 +1840,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size() >= 4 ? v[3] : 0; } break; case RS::GLOBAL_VAR_TYPE_RECT2I: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Rect2i v = p_value; bv.x = v.position.x; bv.y = v.position.y; @@ -1788,7 +1848,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size.y; } break; case RS::GLOBAL_VAR_TYPE_UINT: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; uint32_t v = p_value; bv.x = v; bv.y = 0; @@ -1796,7 +1856,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC2: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector2i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1804,7 +1864,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC3: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector3i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1812,7 +1872,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC4: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector<int32_t> v = p_value; bv.x = v.size() >= 1 ? v[0] : 0; bv.y = v.size() >= 2 ? v[1] : 0; @@ -1820,7 +1880,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size() >= 4 ? v[3] : 0; } break; case RS::GLOBAL_VAR_TYPE_FLOAT: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; float v = p_value; bv.x = v; bv.y = 0; @@ -1828,7 +1888,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Vector2 v = p_value; bv.x = v.x; bv.y = v.y; @@ -1836,7 +1896,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC3: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Vector3 v = p_value; bv.x = v.x; bv.y = v.y; @@ -1844,7 +1904,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Plane v = p_value; bv.x = v.normal.x; bv.y = v.normal.y; @@ -1852,14 +1912,14 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.d; } break; case RS::GLOBAL_VAR_TYPE_COLOR: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Color v = p_value; bv.x = v.r; bv.y = v.g; bv.z = v.b; bv.w = v.a; - GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1]; + GlobalShaderUniforms::Value &bv_linear = global_shader_uniforms.buffer_values[p_index + 1]; //v = v.srgb_to_linear(); bv_linear.x = v.r; bv_linear.y = v.g; @@ -1868,7 +1928,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_RECT2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Rect2 v = p_value; bv.x = v.position.x; bv.y = v.position.y; @@ -1876,7 +1936,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size.y; } break; case RS::GLOBAL_VAR_TYPE_MAT2: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Vector<float> m2 = p_value; if (m2.size() < 4) { m2.resize(4); @@ -1893,7 +1953,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_MAT3: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Basis v = p_value; bv[0].x = v.rows[0][0]; bv[0].y = v.rows[1][0]; @@ -1912,7 +1972,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_MAT4: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Vector<float> m2 = p_value; if (m2.size() < 16) { @@ -1941,7 +2001,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Transform2D v = p_value; bv[0].x = v.columns[0][0]; bv[0].y = v.columns[0][1]; @@ -1960,7 +2020,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Transform3D v = p_value; bv[0].x = v.basis.rows[0][0]; bv[0].y = v.basis.rows[1][0]; @@ -1989,15 +2049,15 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } } -void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { +void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { int32_t prev_chunk = -1; for (int32_t i = 0; i < p_elements; i++) { - int32_t chunk = (p_index + i) / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + int32_t chunk = (p_index + i) / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; if (chunk != prev_chunk) { - if (!global_variables.buffer_dirty_regions[chunk]) { - global_variables.buffer_dirty_regions[chunk] = true; - global_variables.buffer_dirty_region_count++; + if (!global_shader_uniforms.buffer_dirty_regions[chunk]) { + global_shader_uniforms.buffer_dirty_regions[chunk] = true; + global_shader_uniforms.buffer_dirty_region_count++; } } @@ -2005,16 +2065,16 @@ void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_ } } -void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { - ERR_FAIL_COND(global_variables.variables.has(p_name)); - GlobalVariables::Variable gv; +void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) { + ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name)); + GlobalShaderUniforms::Variable gv; gv.type = p_type; gv.value = p_value; gv.buffer_index = -1; if (p_type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { //is texture - global_variables.must_update_texture_materials = true; //normally there are none + global_shader_uniforms.must_update_texture_materials = true; //normally there are none } else { gv.buffer_elements = 1; if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) { @@ -2031,56 +2091,56 @@ void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVa } //is vector, allocate in buffer and update index - gv.buffer_index = _global_variable_allocate(gv.buffer_elements); + gv.buffer_index = _global_shader_uniform_allocate(gv.buffer_elements); ERR_FAIL_COND_MSG(gv.buffer_index < 0, vformat("Failed allocating global variable '%s' out of buffer memory. Consider increasing it in the Project Settings.", String(p_name))); - global_variables.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + global_shader_uniforms.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); - global_variables.must_update_buffer_materials = true; //normally there are none + global_shader_uniforms.must_update_buffer_materials = true; //normally there are none } - global_variables.variables[p_name] = gv; + global_shader_uniforms.variables[p_name] = gv; } -void MaterialStorage::global_variable_remove(const StringName &p_name) { - if (!global_variables.variables.has(p_name)) { +void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { + if (!global_shader_uniforms.variables.has(p_name)) { return; } - GlobalVariables::Variable &gv = global_variables.variables[p_name]; + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; if (gv.buffer_index >= 0) { - global_variables.buffer_usage[gv.buffer_index].elements = 0; - global_variables.must_update_buffer_materials = true; + global_shader_uniforms.buffer_usage[gv.buffer_index].elements = 0; + global_shader_uniforms.must_update_buffer_materials = true; } else { - global_variables.must_update_texture_materials = true; + global_shader_uniforms.must_update_texture_materials = true; } - global_variables.variables.erase(p_name); + global_shader_uniforms.variables.erase(p_name); } -Vector<StringName> MaterialStorage::global_variable_get_list() const { +Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } Vector<StringName> names; - for (const KeyValue<StringName, GlobalVariables::Variable> &E : global_variables.variables) { + for (const KeyValue<StringName, GlobalShaderUniforms::Variable> &E : global_shader_uniforms.variables) { names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); return names; } -void MaterialStorage::global_variable_set(const StringName &p_name, const Variant &p_value) { - ERR_FAIL_COND(!global_variables.variables.has(p_name)); - GlobalVariables::Variable &gv = global_variables.variables[p_name]; +void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) { + ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name)); + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.value = p_value; if (gv.override.get_type() == Variant::NIL) { if (gv.buffer_index >= 0) { //buffer - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -2093,26 +2153,26 @@ void MaterialStorage::global_variable_set(const StringName &p_name, const Varian } } -void MaterialStorage::global_variable_set_override(const StringName &p_name, const Variant &p_value) { - if (!global_variables.variables.has(p_name)) { +void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) { + if (!global_shader_uniforms.variables.has(p_name)) { return; //variable may not exist } ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); - GlobalVariables::Variable &gv = global_variables.variables[p_name]; + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.override = p_value; if (gv.buffer_index >= 0) { //buffer if (gv.override.get_type() == Variant::NIL) { - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); } else { - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.override); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.override); } - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -2124,35 +2184,35 @@ void MaterialStorage::global_variable_set_override(const StringName &p_name, con } } -Variant MaterialStorage::global_variable_get(const StringName &p_name) const { +Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } - if (!global_variables.variables.has(p_name)) { + if (!global_shader_uniforms.variables.has(p_name)) { return Variant(); } - return global_variables.variables[p_name].value; + return global_shader_uniforms.variables[p_name].value; } -RS::GlobalVariableType MaterialStorage::global_variable_get_type_internal(const StringName &p_name) const { - if (!global_variables.variables.has(p_name)) { +RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const { + if (!global_shader_uniforms.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } - return global_variables.variables[p_name].type; + return global_shader_uniforms.variables[p_name].type; } -RS::GlobalVariableType MaterialStorage::global_variable_get_type(const StringName &p_name) const { +RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); } - return global_variable_get_type_internal(p_name); + return global_shader_uniform_get_type_internal(p_name); } -void MaterialStorage::global_variables_load_settings(bool p_load_textures) { +void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -2197,11 +2257,11 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { "samplerCube", }; - RS::GlobalVariableType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX; for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { if (global_var_type_names[i] == type) { - gvtype = RS::GlobalVariableType(i); + gvtype = RS::GlobalShaderUniformType(i); break; } } @@ -2223,47 +2283,47 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { value = resource; } - if (global_variables.variables.has(name)) { + if (global_shader_uniforms.variables.has(name)) { //has it, update it - global_variable_set(name, value); + global_shader_uniform_set(name, value); } else { - global_variable_add(name, gvtype, value); + global_shader_uniform_add(name, gvtype, value); } } } } -void MaterialStorage::global_variables_clear() { - global_variables.variables.clear(); +void MaterialStorage::global_shader_uniforms_clear() { + global_shader_uniforms.variables.clear(); } -GLuint MaterialStorage::global_variables_get_uniform_buffer() const { - return global_variables.buffer; +GLuint MaterialStorage::global_shader_uniforms_get_uniform_buffer() const { + return global_shader_uniforms.buffer; } -int32_t MaterialStorage::global_variables_instance_allocate(RID p_instance) { - ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1); - int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); - global_variables.instance_buffer_pos[p_instance] = pos; //save anyway +int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) { + ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1); + int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); + global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway ERR_FAIL_COND_V_MSG(pos < 0, -1, "Too many instances using shader instance variables. Increase buffer size in Project Settings."); - global_variables.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; + global_shader_uniforms.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; return pos; } -void MaterialStorage::global_variables_instance_free(RID p_instance) { - ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance)); - int32_t pos = global_variables.instance_buffer_pos[p_instance]; +void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { + ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance)); + int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos >= 0) { - global_variables.buffer_usage[pos].elements = 0; + global_shader_uniforms.buffer_usage[pos].elements = 0; } - global_variables.instance_buffer_pos.erase(p_instance); + global_shader_uniforms.instance_buffer_pos.erase(p_instance); } -void MaterialStorage::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { - if (!global_variables.instance_buffer_pos.has(p_instance)) { +void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) { + if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } - int32_t pos = global_variables.instance_buffer_pos[p_instance]; + int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos < 0) { return; //again, not allocated, ignore @@ -2298,59 +2358,59 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind pos += p_index; - _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos]); - _global_variable_mark_buffer_dirty(pos, 1); + _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_shader_uniforms.buffer_values[pos]); + _global_shader_uniform_mark_buffer_dirty(pos, 1); } -void MaterialStorage::_update_global_variables() { +void MaterialStorage::_update_global_shader_uniforms() { MaterialStorage *material_storage = MaterialStorage::get_singleton(); - if (global_variables.buffer_dirty_region_count > 0) { - uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; - if (total_regions / global_variables.buffer_dirty_region_count <= 4) { + if (global_shader_uniforms.buffer_dirty_region_count > 0) { + uint32_t total_regions = global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; + if (total_regions / global_shader_uniforms.buffer_dirty_region_count <= 4) { // 25% of regions dirty, just update all buffer - glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer); - glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalVariables::Value) * global_variables.buffer_size, global_variables.buffer_values, GL_DYNAMIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, global_shader_uniforms.buffer_values, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); - memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * total_regions); + memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * total_regions); } else { - uint32_t region_byte_size = sizeof(GlobalVariables::Value) * GlobalVariables::BUFFER_DIRTY_REGION_SIZE; - glBindBuffer(GL_UNIFORM_BUFFER, global_variables.buffer); + uint32_t region_byte_size = sizeof(GlobalShaderUniforms::Value) * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; + glBindBuffer(GL_UNIFORM_BUFFER, global_shader_uniforms.buffer); for (uint32_t i = 0; i < total_regions; i++) { - if (global_variables.buffer_dirty_regions[i]) { - glBufferSubData(GL_UNIFORM_BUFFER, i * region_byte_size, region_byte_size, &global_variables.buffer_values[i * GlobalVariables::BUFFER_DIRTY_REGION_SIZE]); - global_variables.buffer_dirty_regions[i] = false; + if (global_shader_uniforms.buffer_dirty_regions[i]) { + glBufferSubData(GL_UNIFORM_BUFFER, i * region_byte_size, region_byte_size, &global_shader_uniforms.buffer_values[i * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE]); + global_shader_uniforms.buffer_dirty_regions[i] = false; } } glBindBuffer(GL_UNIFORM_BUFFER, 0); } - global_variables.buffer_dirty_region_count = 0; + global_shader_uniforms.buffer_dirty_region_count = 0; } - if (global_variables.must_update_buffer_materials) { + if (global_shader_uniforms.must_update_buffer_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (const RID &E : global_variables.materials_using_buffer) { + for (const RID &E : global_shader_uniforms.materials_using_buffer) { Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); //wtf material_storage->_material_queue_update(material, true, false); } - global_variables.must_update_buffer_materials = false; + global_shader_uniforms.must_update_buffer_materials = false; } - if (global_variables.must_update_texture_materials) { + if (global_shader_uniforms.must_update_texture_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (const RID &E : global_variables.materials_using_texture) { + for (const RID &E : global_shader_uniforms.materials_using_texture) { Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); //wtf material_storage->_material_queue_update(material, false, true); } - global_variables.must_update_texture_materials = false; + global_shader_uniforms.must_update_texture_materials = false; } } @@ -2462,6 +2522,13 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { } } +void MaterialStorage::shader_set_path_hint(RID p_shader, const String &p_path) { + GLES3::Shader *shader = shader_owner.get_or_null(p_shader); + ERR_FAIL_COND(!shader); + + shader->path_hint = p_path; +} + String MaterialStorage::shader_get_code(RID p_shader) const { const GLES3::Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, String()); @@ -2833,7 +2900,22 @@ void CanvasShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); @@ -3056,7 +3138,22 @@ void SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); @@ -3366,7 +3463,22 @@ void SceneShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index 6ad277c2b9..8fc15ddcba 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -73,6 +73,7 @@ struct Material; struct Shader { ShaderData *data = nullptr; String code; + String path_hint; RS::ShaderMode mode; HashMap<StringName, HashMap<int, RID>> default_texture_parameter; HashSet<Material *> owners; @@ -364,15 +365,15 @@ struct SceneMaterialData : public MaterialData { MaterialData *_create_scene_material_func(ShaderData *p_shader); -/* Global variable structs */ -struct GlobalVariables { +/* Global shader uniform structs */ +struct GlobalShaderUniforms { enum { BUFFER_DIRTY_REGION_SIZE = 1024 }; struct Variable { HashSet<RID> texture_materials; // materials using this - RS::GlobalVariableType type; + RS::GlobalShaderUniformType type; Variant value; Variant override; int32_t buffer_index; //for vectors @@ -428,13 +429,13 @@ private: friend struct MaterialData; static MaterialStorage *singleton; - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - GlobalVariables global_variables; + GlobalShaderUniforms global_shader_uniforms; - int32_t _global_variable_allocate(uint32_t p_elements); - void _global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value); - void _global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements); + int32_t _global_shader_uniform_allocate(uint32_t p_elements); + void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value); + void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements); /* SHADER API */ @@ -487,7 +488,7 @@ public: p_array[11] = 0; } - static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { + static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { p_array[i * 4 + j] = p_mtx.matrix[i][j]; @@ -507,28 +508,28 @@ public: ShaderCompiler compiler_sky; } shaders; - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - void _update_global_variables(); + void _update_global_shader_uniforms(); - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override; - virtual void global_variable_remove(const StringName &p_name) override; - virtual Vector<StringName> global_variable_get_list() const override; + virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override; + virtual void global_shader_uniform_remove(const StringName &p_name) override; + virtual Vector<StringName> global_shader_uniform_get_list() const override; - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override; - virtual Variant global_variable_get(const StringName &p_name) const override; - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override; - RS::GlobalVariableType global_variable_get_type_internal(const StringName &p_name) const; + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override; + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override; + virtual Variant global_shader_uniform_get(const StringName &p_name) const override; + virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override; + RS::GlobalShaderUniformType global_shader_uniform_get_type_internal(const StringName &p_name) const; - virtual void global_variables_load_settings(bool p_load_textures = true) override; - virtual void global_variables_clear() override; + virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override; + virtual void global_shader_uniforms_clear() override; - virtual int32_t global_variables_instance_allocate(RID p_instance) override; - virtual void global_variables_instance_free(RID p_instance) override; - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override; + virtual void global_shader_uniforms_instance_free(RID p_instance) override; + virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override; - GLuint global_variables_get_uniform_buffer() const; + GLuint global_shader_uniforms_get_uniform_buffer() const; /* SHADER API */ @@ -542,6 +543,7 @@ public: virtual void shader_free(RID p_rid) override; virtual void shader_set_code(RID p_shader, const String &p_code) override; + virtual void shader_set_path_hint(RID p_shader, const String &p_path) override; virtual String shader_get_code(RID p_shader) const override; virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; @@ -597,4 +599,4 @@ public: #endif // GLES3_ENABLED -#endif // !MATERIAL_STORAGE_GLES3_H +#endif // MATERIAL_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h index c51cd5dcd6..339380b3b0 100644 --- a/drivers/gles3/storage/mesh_storage.h +++ b/drivers/gles3/storage/mesh_storage.h @@ -543,4 +543,4 @@ public: #endif // GLES3_ENABLED -#endif // !MESH_STORAGE_GLES3_H +#endif // MESH_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/particles_storage.h b/drivers/gles3/storage/particles_storage.h index cf47ada5d5..84d1f94d8c 100644 --- a/drivers/gles3/storage/particles_storage.h +++ b/drivers/gles3/storage/particles_storage.h @@ -137,4 +137,4 @@ public: #endif // GLES3_ENABLED -#endif // !PARTICLES_STORAGE_GLES3_H +#endif // PARTICLES_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index b5d5641086..77ec1da6f5 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -577,6 +577,6 @@ inline String TextureStorage::get_framebuffer_error(GLenum p_status) { } // namespace GLES3 -#endif // !GLES3_ENABLED +#endif // GLES3_ENABLED -#endif // !TEXTURE_STORAGE_GLES3_H +#endif // TEXTURE_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp index a00210a2ab..654104722b 100644 --- a/drivers/gles3/storage/utilities.cpp +++ b/drivers/gles3/storage/utilities.cpp @@ -293,7 +293,7 @@ void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_de /* MISC */ void Utilities::update_dirty_resources() { - MaterialStorage::get_singleton()->_update_global_variables(); + MaterialStorage::get_singleton()->_update_global_shader_uniforms(); MaterialStorage::get_singleton()->_update_queued_materials(); //MeshStorage::get_singleton()->_update_dirty_skeletons(); MeshStorage::get_singleton()->_update_dirty_multimeshes(); diff --git a/drivers/gles3/storage/utilities.h b/drivers/gles3/storage/utilities.h index 523033886c..e054f2f816 100644 --- a/drivers/gles3/storage/utilities.h +++ b/drivers/gles3/storage/utilities.h @@ -156,4 +156,4 @@ public: #endif // GLES3_ENABLED -#endif // !UTILITIES_GLES3_H +#endif // UTILITIES_GLES3_H diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h index 522cc901d4..9bcfb720d3 100644 --- a/drivers/png/image_loader_png.h +++ b/drivers/png/image_loader_png.h @@ -45,4 +45,4 @@ public: ImageLoaderPNG(); }; -#endif +#endif // IMAGE_LOADER_PNG_H diff --git a/drivers/png/png_driver_common.h b/drivers/png/png_driver_common.h index 62302bbdbb..24546d4402 100644 --- a/drivers/png/png_driver_common.h +++ b/drivers/png/png_driver_common.h @@ -43,4 +43,4 @@ Error png_to_image(const uint8_t *p_source, size_t p_size, bool p_force_linear, Error image_to_png(const Ref<Image> &p_image, Vector<uint8_t> &p_buffer); } // namespace PNGDriverCommon -#endif +#endif // PNG_DRIVER_COMMON_H diff --git a/drivers/register_driver_types.h b/drivers/register_driver_types.h index c008d93185..41f95b57e7 100644 --- a/drivers/register_driver_types.h +++ b/drivers/register_driver_types.h @@ -37,4 +37,4 @@ void unregister_core_driver_types(); void register_driver_types(); void unregister_driver_types(); -#endif +#endif // REGISTER_DRIVER_TYPES_H diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 39dbadf3cd..b8b72b8d30 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -516,4 +516,4 @@ DirAccessUnix::~DirAccessUnix() { list_dir_end(); } -#endif //posix_enabled +#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h index 5e2129b74a..18f435f942 100644 --- a/drivers/unix/dir_access_unix.h +++ b/drivers/unix/dir_access_unix.h @@ -90,5 +90,6 @@ public: ~DirAccessUnix(); }; -#endif //UNIX ENABLED -#endif +#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED + +#endif // DIR_ACCESS_UNIX_H diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 99836b7bea..388ad479b9 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -339,4 +339,4 @@ FileAccessUnix::~FileAccessUnix() { _close(); } -#endif +#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 0261b8be53..d61fc08f57 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -86,5 +86,6 @@ public: virtual ~FileAccessUnix(); }; -#endif -#endif +#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED + +#endif // FILE_ACCESS_UNIX_H diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h index 06fcdb6e17..798d02095c 100644 --- a/drivers/unix/ip_unix.h +++ b/drivers/unix/ip_unix.h @@ -50,4 +50,5 @@ public: }; #endif + #endif // IP_UNIX_H diff --git a/drivers/unix/net_socket_posix.h b/drivers/unix/net_socket_posix.h index 867513099a..5558114cb1 100644 --- a/drivers/unix/net_socket_posix.h +++ b/drivers/unix/net_socket_posix.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NET_SOCKET_UNIX_H -#define NET_SOCKET_UNIX_H +#ifndef NET_SOCKET_POSIX_H +#define NET_SOCKET_POSIX_H #include "core/io/net_socket.h" @@ -104,4 +104,4 @@ public: ~NetSocketPosix(); }; -#endif +#endif // NET_SOCKET_POSIX_H diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 091287c652..5bf14056ab 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -65,7 +65,7 @@ #include <time.h> #include <unistd.h> -#if defined(OSX_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) +#if defined(MACOS_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) // Random location for getentropy. Fitting. #include <sys/random.h> #define UNIX_GET_ENTROPY diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index a1ed4bd501..f4609a565b 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -98,6 +98,6 @@ public: virtual ~UnixTerminalLogger(); }; -#endif +#endif // UNIX_ENABLED -#endif +#endif // OS_UNIX_H diff --git a/drivers/unix/syslog_logger.h b/drivers/unix/syslog_logger.h index 697a96a6f9..cc6617eb25 100644 --- a/drivers/unix/syslog_logger.h +++ b/drivers/unix/syslog_logger.h @@ -43,6 +43,6 @@ public: virtual ~SyslogLogger(); }; -#endif +#endif // UNIX_ENABLED -#endif +#endif // SYSLOG_LOGGER_H diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h index 9cd3ecbe90..672adcba72 100644 --- a/drivers/unix/thread_posix.h +++ b/drivers/unix/thread_posix.h @@ -35,4 +35,4 @@ void init_thread_posix(); #endif -#endif +#endif // THREAD_POSIX_H diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub index b6ceb1cdea..a076c0ac54 100644 --- a/drivers/vulkan/SCsub +++ b/drivers/vulkan/SCsub @@ -15,11 +15,11 @@ if env["use_volk"]: if env["platform"] == "android": env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_ANDROID_KHR"]) -elif env["platform"] == "iphone": +elif env["platform"] == "ios": env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_IOS_MVK"]) -elif env["platform"] == "linuxbsd": +elif env["platform"] == "linuxbsd" and env["x11"]: env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_XLIB_KHR"]) -elif env["platform"] == "osx": +elif env["platform"] == "macos": env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_MACOS_MVK"]) elif env["platform"] == "windows": env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_WIN32_KHR"]) @@ -40,7 +40,7 @@ elif env["platform"] == "android": # Our current NDK version only provides old Vulkan headers, # so we have to limit VMA. env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_VULKAN_VERSION=1000000"]) -elif env["platform"] == "osx" or env["platform"] == "iphone": +elif env["platform"] == "macos" or env["platform"] == "ios": # MoltenVK supports only Vulkan 1.1 API, limit VMA to the same version. env_thirdparty_vma.AppendUnique(CPPDEFINES=["VMA_VULKAN_VERSION=1001000"]) diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index e8b443cceb..0979ae9e16 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -1834,6 +1834,11 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T if (p_format.usage_bits & TEXTURE_USAGE_STORAGE_ATOMIC_BIT && !(flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) { ERR_FAIL_V_MSG(RID(), "Format " + format_text + " does not support usage as atomic storage image."); } + + // Validation via VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR fails if VRS attachment is not supported. + if (p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT && p_format.format != DATA_FORMAT_R8_UINT) { + ERR_FAIL_V_MSG(RID(), "Format " + format_text + " does not support usage as VRS attachment."); + } } //some view validation @@ -3354,6 +3359,11 @@ bool RenderingDeviceVulkan::texture_is_format_supported_for_usage(DataFormat p_f return false; } + // Validation via VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR fails if VRS attachment is not supported. + if (p_usage & TEXTURE_USAGE_VRS_ATTACHMENT_BIT && p_format != DATA_FORMAT_R8_UINT) { + return false; + } + return true; } @@ -3396,7 +3406,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF ERR_FAIL_INDEX_V(p_attachments[i].format, DATA_FORMAT_MAX, VK_NULL_HANDLE); ERR_FAIL_INDEX_V(p_attachments[i].samples, TEXTURE_SAMPLES_MAX, VK_NULL_HANDLE); ERR_FAIL_COND_V_MSG(!(p_attachments[i].usage_flags & (TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | TEXTURE_USAGE_INPUT_ATTACHMENT_BIT | TEXTURE_USAGE_VRS_ATTACHMENT_BIT)), - VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (color, depth, input or stencil) bit set."); + VK_NULL_HANDLE, "Texture format for index (" + itos(i) + ") requires an attachment (color, depth-stencil, input or VRS) bit set."); VkAttachmentDescription2KHR description = {}; description.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR; @@ -3762,9 +3772,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF if (context->get_vrs_capabilities().attachment_vrs_supported && pass->vrs_attachment != FramebufferPass::ATTACHMENT_UNUSED) { int32_t attachment = pass->vrs_attachment; - ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), depth attachment."); - ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer depth format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as vrs, but it's not a vrs attachment."); - ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer vrs attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass."); + ERR_FAIL_INDEX_V_MSG(attachment, p_attachments.size(), VK_NULL_HANDLE, "Invalid framebuffer VRS format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), VRS attachment."); + ERR_FAIL_COND_V_MSG(!(p_attachments[attachment].usage_flags & TEXTURE_USAGE_VRS_ATTACHMENT_BIT), VK_NULL_HANDLE, "Invalid framebuffer VRS format attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it's marked as VRS, but it's not a VRS attachment."); + ERR_FAIL_COND_V_MSG(attachment_last_pass[attachment] == i, VK_NULL_HANDLE, "Invalid framebuffer VRS attachment(" + itos(attachment) + "), in pass (" + itos(i) + "), it already was used for something else before in this pass."); VkAttachmentReference2KHR &vrs_reference = vrs_reference_array[i]; vrs_reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR; @@ -3807,7 +3817,12 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF subpass.pNext = subpass_nextptr; subpass.flags = 0; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.viewMask = view_mask; + if (p_view_count == 1) { + // VUID-VkSubpassDescription2-multiview-06558: If the multiview feature is not enabled, viewMask must be 0. + subpass.viewMask = 0; + } else { + subpass.viewMask = view_mask; + } subpass.inputAttachmentCount = input_references.size(); if (input_references.size()) { subpass.pInputAttachments = input_references.ptr(); @@ -3895,8 +3910,14 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF render_pass_create_info.pDependencies = nullptr; } - render_pass_create_info.correlatedViewMaskCount = 1; - render_pass_create_info.pCorrelatedViewMasks = &correlation_mask; + if (p_view_count == 1) { + // VUID-VkRenderPassCreateInfo2-viewMask-03057: If the VkSubpassDescription2::viewMask member of all elements of pSubpasses is 0, correlatedViewMaskCount must be 0. + render_pass_create_info.correlatedViewMaskCount = 0; + render_pass_create_info.pCorrelatedViewMasks = nullptr; + } else { + render_pass_create_info.correlatedViewMaskCount = 1; + render_pass_create_info.pCorrelatedViewMasks = &correlation_mask; + } Vector<uint32_t> view_masks; VkRenderPassMultiviewCreateInfo render_pass_multiview_create_info; @@ -3997,6 +4018,7 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c subpass.pNext = nullptr; subpass.flags = 0; subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass.viewMask = 0; subpass.inputAttachmentCount = 0; //unsupported for now subpass.pInputAttachments = nullptr; subpass.colorAttachmentCount = 0; @@ -4016,6 +4038,8 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c render_pass_create_info.pSubpasses = &subpass; render_pass_create_info.dependencyCount = 0; render_pass_create_info.pDependencies = nullptr; + render_pass_create_info.correlatedViewMaskCount = 0; + render_pass_create_info.pCorrelatedViewMasks = nullptr; VkRenderPass render_pass; VkResult res = context->vkCreateRenderPass2KHR(device, &render_pass_create_info, nullptr, &render_pass); diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 814cec2ec0..0d8a3310fd 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -646,7 +646,7 @@ Error VulkanContext::_check_capabilities() { subgroup_capabilities.quadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages; if (vrs_capabilities.pipeline_vrs_supported || vrs_capabilities.primitive_vrs_supported || vrs_capabilities.attachment_vrs_supported) { - print_verbose("- Vulkan Varying Shading Rates supported:"); + print_verbose("- Vulkan Variable Rate Shading supported:"); if (vrs_capabilities.pipeline_vrs_supported) { print_verbose(" Pipeline fragment shading rate"); } @@ -664,7 +664,7 @@ Error VulkanContext::_check_capabilities() { } } else { - print_verbose("- Vulkan Varying Shading Rates not supported"); + print_verbose("- Vulkan Variable Rate Shading not supported"); } if (multiview_capabilities.is_supported) { @@ -1827,7 +1827,7 @@ Error VulkanContext::_update_swap_chain(Window *window) { /*pNext*/ nullptr, /*flags*/ 0, /*pipelineBindPoint*/ VK_PIPELINE_BIND_POINT_GRAPHICS, - /*viewMask*/ 1, + /*viewMask*/ 0, /*inputAttachmentCount*/ 0, /*pInputAttachments*/ nullptr, /*colorAttachmentCount*/ 1, @@ -1838,7 +1838,6 @@ Error VulkanContext::_update_swap_chain(Window *window) { /*pPreserveAttachments*/ nullptr, }; - uint32_t view_masks = 1; const VkRenderPassCreateInfo2KHR rp_info = { /*sType*/ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR, /*pNext*/ nullptr, @@ -1849,8 +1848,8 @@ Error VulkanContext::_update_swap_chain(Window *window) { /*pSubpasses*/ &subpass, /*dependencyCount*/ 0, /*pDependencies*/ nullptr, - /*correlatedViewMaskCount*/ 1, - /*pCorrelatedViewMasks*/ &view_masks, + /*correlatedViewMaskCount*/ 0, + /*pCorrelatedViewMasks*/ nullptr, }; err = vkCreateRenderPass2KHR(device, &rp_info, nullptr, &window->render_pass); @@ -2402,7 +2401,7 @@ void VulkanContext::command_begin_label(VkCommandBuffer p_command_buffer, String return; } - CharString cs = p_label_name.utf8().get_data(); + CharString cs = p_label_name.utf8(); VkDebugUtilsLabelEXT label; label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; label.pNext = nullptr; @@ -2418,7 +2417,7 @@ void VulkanContext::command_insert_label(VkCommandBuffer p_command_buffer, Strin if (!enabled_debug_utils) { return; } - CharString cs = p_label_name.utf8().get_data(); + CharString cs = p_label_name.utf8(); VkDebugUtilsLabelEXT label; label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT; label.pNext = nullptr; diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h index b2eb43975f..35e7ce7db8 100644 --- a/drivers/vulkan/vulkan_context.h +++ b/drivers/vulkan/vulkan_context.h @@ -272,11 +272,11 @@ public: uint32_t get_vulkan_major() const { return vulkan_major; }; uint32_t get_vulkan_minor() const { return vulkan_minor; }; - SubgroupCapabilities get_subgroup_capabilities() const { return subgroup_capabilities; }; - MultiviewCapabilities get_multiview_capabilities() const { return multiview_capabilities; }; - VRSCapabilities get_vrs_capabilities() const { return vrs_capabilities; }; - ShaderCapabilities get_shader_capabilities() const { return shader_capabilities; }; - StorageBufferCapabilities get_storage_buffer_capabilities() const { return storage_buffer_capabilities; }; + const SubgroupCapabilities &get_subgroup_capabilities() const { return subgroup_capabilities; }; + const MultiviewCapabilities &get_multiview_capabilities() const { return multiview_capabilities; }; + const VRSCapabilities &get_vrs_capabilities() const { return vrs_capabilities; }; + const ShaderCapabilities &get_shader_capabilities() const { return shader_capabilities; }; + const StorageBufferCapabilities &get_storage_buffer_capabilities() const { return storage_buffer_capabilities; }; VkDevice get_device(); VkPhysicalDevice get_physical_device(); @@ -330,4 +330,4 @@ public: virtual ~VulkanContext(); }; -#endif // VULKAN_DEVICE_H +#endif // VULKAN_CONTEXT_H diff --git a/drivers/vulkan/vulkan_hooks.h b/drivers/vulkan/vulkan_hooks.h index 3f244b4d45..dec2042d0d 100644 --- a/drivers/vulkan/vulkan_hooks.h +++ b/drivers/vulkan/vulkan_hooks.h @@ -45,4 +45,4 @@ public: virtual ~VulkanHooks(){}; }; -#endif +#endif // VULKAN_HOOKS_H diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index 89ed90e97b..9058077a1f 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -120,4 +120,5 @@ public: }; #endif // WASAPI_ENABLED + #endif // AUDIO_DRIVER_WASAPI_H diff --git a/drivers/winmidi/midi_driver_winmidi.h b/drivers/winmidi/midi_driver_winmidi.h index 6572ba0c16..e42f3df4cf 100644 --- a/drivers/winmidi/midi_driver_winmidi.h +++ b/drivers/winmidi/midi_driver_winmidi.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef WINMIDI_ENABLED - #ifndef MIDI_DRIVER_WINMIDI_H #define MIDI_DRIVER_WINMIDI_H +#ifdef WINMIDI_ENABLED + #include "core/os/midi_driver.h" #include "core/templates/vector.h" @@ -57,5 +57,6 @@ public: virtual ~MIDIDriverWinMidi(); }; -#endif // MIDI_DRIVER_WINMIDI_H #endif // WINMIDI_ENABLED + +#endif // MIDI_DRIVER_WINMIDI_H diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h index 9072269a0e..81432ceb8e 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.h +++ b/drivers/xaudio2/audio_driver_xaudio2.h @@ -106,4 +106,4 @@ public: ~AudioDriverXAudio2() {} }; -#endif +#endif // AUDIO_DRIVER_XAUDIO2_H diff --git a/editor/SCsub b/editor/SCsub index a596c7d364..c217f162b4 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -76,7 +76,7 @@ if env["tools"]: # Editor translations to_include = ( - "ar,bg,ca,cs,de,el,eo,es_AR,es,fi,fr,gl,he,hu,id,it,ja,ko,lv,ms,nb,nl,pl,pt_BR,pt,ro,ru,sk,th,tr,uk,vi,zh_CN,zh_TW" + "ar,bg,ca,cs,de,el,eo,es_AR,es,fi,fr,gl,he,hu,id,it,ja,ko,lv,ms,nb,nl,pl,pt_BR,pt,ro,ru,sk,sv,th,tr,uk,vi,zh_CN,zh_TW" ).split(",") tlist = [env.Dir("#editor/translations").abspath + "/" + f + ".po" for f in to_include] env.Depends("#editor/editor_translations.gen.h", tlist) @@ -113,6 +113,7 @@ if env["tools"]: env.add_source_files(env.editor_sources, "register_exporters.gen.cpp") SConscript("debugger/SCsub") + SConscript("export/SCsub") SConscript("fileserver/SCsub") SConscript("icons/SCsub") SConscript("import/SCsub") diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h index d8c40a97a7..1ca3c5bac0 100644 --- a/editor/action_map_editor.h +++ b/editor/action_map_editor.h @@ -209,4 +209,4 @@ public: ActionMapEditor(); }; -#endif +#endif // ACTION_MAP_EDITOR_H diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 703cfaee3d..f01a83ea4c 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -3746,19 +3746,7 @@ void AnimationTrackEditor::_insert_track(bool p_reset_wanted, bool p_create_bezi undo_redo->commit_action(); if (advance) { - float step = animation->get_step(); - if (step == 0) { - step = 1; - } - - float pos = timeline->get_play_position(); - - pos = Math::snapped(pos + step, step); - if (pos > animation->get_length()) { - pos = animation->get_length(); - } - set_anim_pos(pos); - emit_signal(SNAME("timeline_changed"), pos, true, false); + _edit_menu_pressed(EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY); } } @@ -4086,12 +4074,20 @@ void AnimationTrackEditor::_confirm_insert_list() { } TrackIndices next_tracks(animation.ptr(), reset_anim.ptr()); + bool advance = false; while (insert_data.size()) { + if (insert_data.front()->get().advance) { + advance = true; + } next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, create_reset, reset_anim, insert_confirm_bezier->is_pressed()); insert_data.pop_front(); } undo_redo->commit_action(); + + if (advance) { + _edit_menu_pressed(EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY); + } } PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val) { @@ -5597,7 +5593,7 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) { emit_signal(SNAME("timeline_changed"), pos, true, false); } -void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event) { +void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event, bool p_timeline_only) { if (animation.is_null()) { return; } @@ -5621,7 +5617,7 @@ void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event) { } set_anim_pos(pos); - emit_signal(SNAME("timeline_changed"), pos, true, false); + emit_signal(SNAME("timeline_changed"), pos, true, p_timeline_only); } void AnimationTrackEditor::_edit_menu_pressed(int p_option) { @@ -5969,8 +5965,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { _update_key_edit(); } } break; + case EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY: case EDIT_GOTO_NEXT_STEP: { - goto_next_step(false); + goto_next_step(false, p_option == EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY); } break; case EDIT_GOTO_PREV_STEP: { goto_prev_step(false); @@ -6113,7 +6110,8 @@ float AnimationTrackEditor::snap_time(float p_value, bool p_relative) { void AnimationTrackEditor::_show_imported_anim_warning() { // It looks terrible on a single line but the TTR extractor doesn't support line breaks yet. - EditorNode::get_singleton()->show_warning(TTR("This animation belongs to an imported scene, so changes to imported tracks will not be saved.\n\nTo 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.\nAlternatively, use an import preset that imports animations to separate files."), + EditorNode::get_singleton()->show_warning( + TTR("This animation belongs to an imported scene, so changes to imported tracks will not be saved.\n\nTo modify this animation, navigate to the scene's Advanced Import settings and select the animation.\nSome options, including looping, are available here. To add custom tracks, enable \"Save To File\" and\n\"Keep Custom Tracks\"."), TTR("Warning: Editing imported animation")); } @@ -6299,6 +6297,7 @@ AnimationTrackEditor::AnimationTrackEditor() { imported_anim_warning = memnew(Button); imported_anim_warning->hide(); + imported_anim_warning->set_text(TTR("Imported Scene")); imported_anim_warning->set_tooltip(TTR("Warning: Editing imported animation")); imported_anim_warning->connect("pressed", callable_mp(this, &AnimationTrackEditor::_show_imported_anim_warning)); bottom_hb->add_child(imported_anim_warning); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index dede2e9bbe..18ce2ded63 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -518,6 +518,7 @@ public: EDIT_ADD_RESET_KEY, EDIT_DELETE_SELECTION, EDIT_GOTO_NEXT_STEP, + EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY, // Next step without updating animation. EDIT_GOTO_PREV_STEP, EDIT_APPLY_RESET, EDIT_OPTIMIZE_ANIMATION, @@ -563,7 +564,7 @@ public: void goto_prev_step(bool p_from_mouse_event); /** If `p_from_mouse_event` is `true`, handle Shift key presses for precise snapping. */ - void goto_next_step(bool p_from_mouse_event); + void goto_next_step(bool p_from_mouse_event, bool p_timeline_only = false); MenuButton *get_edit_menu(); AnimationTrackEditor(); diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp index bea95d873e..fc47e1ef5c 100644 --- a/editor/audio_stream_preview.cpp +++ b/editor/audio_stream_preview.cpp @@ -153,6 +153,8 @@ void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) { singleton->call_deferred(SNAME("_update_emit"), preview->id); } + preview->preview->version++; + preview->playback->stop(); preview->generating.clear(); @@ -171,7 +173,7 @@ Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref< Preview *preview = &previews[p_stream->get_instance_id()]; preview->base_stream = p_stream; - preview->playback = preview->base_stream->instance_playback(); + preview->playback = preview->base_stream->instantiate_playback(); preview->generating.set(); preview->id = p_stream->get_instance_id(); diff --git a/editor/audio_stream_preview.h b/editor/audio_stream_preview.h index 307dd93b34..0e3c8f70d2 100644 --- a/editor/audio_stream_preview.h +++ b/editor/audio_stream_preview.h @@ -43,8 +43,10 @@ class AudioStreamPreview : public RefCounted { float length; friend class AudioStreamPreviewGenerator; + uint64_t version = 1; public: + uint64_t get_version() const { return version; } float get_length() const; float get_max(float p_time, float p_time_next) const; float get_min(float p_time, float p_time_next) const; diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 3a0edf301d..99ca82b311 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -824,12 +824,15 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) { if (k->is_pressed()) { if (ED_IS_SHORTCUT("script_editor/zoom_in", p_event)) { _zoom_in(); + accept_event(); } if (ED_IS_SHORTCUT("script_editor/zoom_out", p_event)) { _zoom_out(); + accept_event(); } if (ED_IS_SHORTCUT("script_editor/reset_zoom", p_event)) { _reset_zoom(); + accept_event(); } } } @@ -1594,6 +1597,10 @@ void CodeTextEditor::set_error_pos(int p_line, int p_column) { error_column = p_column; } +Point2i CodeTextEditor::get_error_pos() const { + return Point2i(error_line, error_column); +} + void CodeTextEditor::goto_error() { if (!error->get_text().is_empty()) { if (text_editor->get_line_count() != error_line) { diff --git a/editor/code_editor.h b/editor/code_editor.h index e2441cec2b..49679cc700 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -253,13 +253,14 @@ public: void update_editor_settings(); void set_error(const String &p_error); void set_error_pos(int p_line, int p_column); + Point2i get_error_pos() const; void update_line_and_column() { _line_col_changed(); } CodeEdit *get_text_editor() { return text_editor; } FindReplaceBar *get_find_replace_bar() { return find_replace_bar; } void set_find_replace_bar(FindReplaceBar *p_bar); void remove_find_replace_bar(); virtual void apply_code() {} - void goto_error(); + virtual void goto_error(); void toggle_bookmark(); void goto_next_bookmark(); diff --git a/editor/create_dialog.h b/editor/create_dialog.h index dc8618a1c0..04094108ad 100644 --- a/editor/create_dialog.h +++ b/editor/create_dialog.h @@ -125,4 +125,4 @@ public: CreateDialog(); }; -#endif +#endif // CREATE_DIALOG_H diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.cpp b/editor/debugger/debug_adapter/debug_adapter_parser.cpp index 0caeb90108..3c3e4faa6f 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_parser.cpp @@ -34,6 +34,7 @@ #include "editor/debugger/script_editor_debugger.h" #include "editor/editor_node.h" #include "editor/editor_run_native.h" +#include "editor/export/editor_export_platform.h" #include "editor/plugins/script_editor_plugin.h" void DebugAdapterParser::_bind_methods() { diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.h b/editor/debugger/debug_adapter/debug_adapter_parser.h index f458151e17..ee32306146 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.h +++ b/editor/debugger/debug_adapter/debug_adapter_parser.h @@ -93,4 +93,4 @@ public: Dictionary ev_breakpoint(const DAP::Breakpoint &p_breakpoint, const bool &p_enabled) const; }; -#endif +#endif // DEBUG_ADAPTER_PARSER_H diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.h b/editor/debugger/debug_adapter/debug_adapter_protocol.h index a17e550dfc..29f577ef97 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.h +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.h @@ -152,4 +152,4 @@ public: ~DebugAdapterProtocol(); }; -#endif +#endif // DEBUG_ADAPTER_PROTOCOL_H diff --git a/editor/debugger/debug_adapter/debug_adapter_server.h b/editor/debugger/debug_adapter/debug_adapter_server.h index a2b01f92c6..633739eaae 100644 --- a/editor/debugger/debug_adapter/debug_adapter_server.h +++ b/editor/debugger/debug_adapter/debug_adapter_server.h @@ -54,4 +54,4 @@ public: void stop(); }; -#endif +#endif // DEBUG_ADAPTER_SERVER_H diff --git a/editor/debugger/debug_adapter/debug_adapter_types.h b/editor/debugger/debug_adapter/debug_adapter_types.h index fd66905f9b..eb10184ab3 100644 --- a/editor/debugger/debug_adapter/debug_adapter_types.h +++ b/editor/debugger/debug_adapter/debug_adapter_types.h @@ -278,4 +278,4 @@ struct Variable { } // namespace DAP -#endif +#endif // DEBUG_ADAPTER_TYPES_H diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp index 0e3d424a4b..58206efc20 100644 --- a/editor/debugger/editor_debugger_inspector.cpp +++ b/editor/debugger/editor_debugger_inspector.cpp @@ -126,25 +126,25 @@ void EditorDebuggerInspector::_object_selected(ObjectID p_object) { } ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) { - EditorDebuggerRemoteObject *debugObj = nullptr; + EditorDebuggerRemoteObject *debug_obj = nullptr; SceneDebuggerObject obj; obj.deserialize(p_arr); ERR_FAIL_COND_V(obj.id.is_null(), ObjectID()); if (remote_objects.has(obj.id)) { - debugObj = remote_objects[obj.id]; + debug_obj = remote_objects[obj.id]; } else { - debugObj = memnew(EditorDebuggerRemoteObject); - debugObj->remote_object_id = obj.id; - debugObj->type_name = obj.class_name; - remote_objects[obj.id] = debugObj; - debugObj->connect("value_edited", callable_mp(this, &EditorDebuggerInspector::_object_edited)); + debug_obj = memnew(EditorDebuggerRemoteObject); + debug_obj->remote_object_id = obj.id; + debug_obj->type_name = obj.class_name; + remote_objects[obj.id] = debug_obj; + debug_obj->connect("value_edited", callable_mp(this, &EditorDebuggerInspector::_object_edited)); } - int old_prop_size = debugObj->prop_list.size(); + int old_prop_size = debug_obj->prop_list.size(); - debugObj->prop_list.clear(); + debug_obj->prop_list.clear(); int new_props_added = 0; HashSet<String> changed; for (int i = 0; i < obj.properties.size(); i++) { @@ -165,12 +165,14 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) { var = ResourceLoader::load(path); if (pinfo.hint_string == "Script") { - if (debugObj->get_script() != var) { - debugObj->set_script(Ref<RefCounted>()); + if (debug_obj->get_script() != var) { + debug_obj->set_script(Ref<RefCounted>()); Ref<Script> script(var); if (!script.is_null()) { - ScriptInstance *script_instance = script->placeholder_instance_create(debugObj); - debugObj->set_script_and_instance(var, script_instance); + ScriptInstance *script_instance = script->placeholder_instance_create(debug_obj); + if (script_instance) { + debug_obj->set_script_and_instance(var, script_instance); + } } } } @@ -178,27 +180,27 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) { } //always add the property, since props may have been added or removed - debugObj->prop_list.push_back(pinfo); + debug_obj->prop_list.push_back(pinfo); - if (!debugObj->prop_values.has(pinfo.name)) { + if (!debug_obj->prop_values.has(pinfo.name)) { new_props_added++; - debugObj->prop_values[pinfo.name] = var; + debug_obj->prop_values[pinfo.name] = var; } else { - if (bool(Variant::evaluate(Variant::OP_NOT_EQUAL, debugObj->prop_values[pinfo.name], var))) { - debugObj->prop_values[pinfo.name] = var; + if (bool(Variant::evaluate(Variant::OP_NOT_EQUAL, debug_obj->prop_values[pinfo.name], var))) { + debug_obj->prop_values[pinfo.name] = var; changed.insert(pinfo.name); } } } - if (old_prop_size == debugObj->prop_list.size() && new_props_added == 0) { + if (old_prop_size == debug_obj->prop_list.size() && new_props_added == 0) { //only some may have changed, if so, then update those, if exist for (const String &E : changed) { - emit_signal(SNAME("object_property_updated"), debugObj->remote_object_id, E); + emit_signal(SNAME("object_property_updated"), debug_obj->remote_object_id, E); } } else { //full update, because props were added or removed - debugObj->update(); + debug_obj->update(); } return obj.id; } diff --git a/editor/debugger/editor_debugger_inspector.h b/editor/debugger/editor_debugger_inspector.h index 0e73928558..5aac4dbf11 100644 --- a/editor/debugger/editor_debugger_inspector.h +++ b/editor/debugger/editor_debugger_inspector.h @@ -30,6 +30,7 @@ #ifndef EDITOR_DEBUGGER_INSPECTOR_H #define EDITOR_DEBUGGER_INSPECTOR_H + #include "editor/editor_inspector.h" class EditorDebuggerRemoteObject : public Object { diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h index d50cbec291..4c9ad49ac4 100644 --- a/editor/debugger/editor_debugger_node.h +++ b/editor/debugger/editor_debugger_node.h @@ -205,4 +205,5 @@ public: void add_debugger_plugin(const Ref<Script> &p_script); void remove_debugger_plugin(const Ref<Script> &p_script); }; + #endif // EDITOR_DEBUGGER_NODE_H diff --git a/editor/debugger/editor_debugger_server.h b/editor/debugger/editor_debugger_server.h index adf9a27c71..f3805f54d8 100644 --- a/editor/debugger/editor_debugger_server.h +++ b/editor/debugger/editor_debugger_server.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITOR_DEBUGGER_CONNECTION_H -#define EDITOR_DEBUGGER_CONNECTION_H +#ifndef EDITOR_DEBUGGER_SERVER_H +#define EDITOR_DEBUGGER_SERVER_H #include "core/debugger/remote_debugger_peer.h" #include "core/object/ref_counted.h" @@ -57,4 +57,4 @@ public: virtual Ref<RemoteDebuggerPeer> take_connection() = 0; }; -#endif // EDITOR_DEBUGGER_CONNECTION_H +#endif // EDITOR_DEBUGGER_SERVER_H diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h index bba524039e..9d163fd548 100644 --- a/editor/debugger/editor_debugger_tree.h +++ b/editor/debugger/editor_debugger_tree.h @@ -71,4 +71,5 @@ public: void update_scene_tree(const SceneDebuggerTree *p_tree, int p_debugger); EditorDebuggerTree(); }; + #endif // EDITOR_DEBUGGER_TREE_H diff --git a/editor/debugger/editor_network_profiler.h b/editor/debugger/editor_network_profiler.h index d2e70a083d..aea7ce3eec 100644 --- a/editor/debugger/editor_network_profiler.h +++ b/editor/debugger/editor_network_profiler.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITORNETWORKPROFILER_H -#define EDITORNETWORKPROFILER_H +#ifndef EDITOR_NETWORK_PROFILER_H +#define EDITOR_NETWORK_PROFILER_H #include "scene/debugger/scene_debugger.h" #include "scene/gui/box_container.h" @@ -69,4 +69,4 @@ public: EditorNetworkProfiler(); }; -#endif //EDITORNETWORKPROFILER_H +#endif // EDITOR_NETWORK_PROFILER_H diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h index cb01a1819f..df92125258 100644 --- a/editor/debugger/editor_profiler.h +++ b/editor/debugger/editor_profiler.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITORPROFILER_H -#define EDITORPROFILER_H +#ifndef EDITOR_PROFILER_H +#define EDITOR_PROFILER_H #include "scene/gui/box_container.h" #include "scene/gui/button.h" @@ -165,4 +165,4 @@ public: EditorProfiler(); }; -#endif // EDITORPROFILER_H +#endif // EDITOR_PROFILER_H diff --git a/editor/debugger/editor_visual_profiler.h b/editor/debugger/editor_visual_profiler.h index 4e5169da9e..8aa9e7b308 100644 --- a/editor/debugger/editor_visual_profiler.h +++ b/editor/debugger/editor_visual_profiler.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITOR_FRAME_PROFILER_H -#define EDITOR_FRAME_PROFILER_H +#ifndef EDITOR_VISUAL_PROFILER_H +#define EDITOR_VISUAL_PROFILER_H #include "scene/gui/box_container.h" #include "scene/gui/button.h" @@ -144,4 +144,4 @@ public: EditorVisualProfiler(); }; -#endif // EDITOR_FRAME_PROFILER_H +#endif // EDITOR_VISUAL_PROFILER_H diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index aa03b7e252..4f89e1b2d1 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -58,6 +58,9 @@ void DependencyEditor::_load_pressed(Object *p_item, int p_cell, int p_button, M search->set_title(TTR("Search Replacement For:") + " " + replacing.get_file()); + // Set directory to closest existing directory. + search->set_current_dir(replacing.get_base_dir()); + search->clear_filters(); List<String> ext; ResourceLoader::get_recognized_extensions_for_type(ti->get_metadata(0), &ext); diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index a6c7970264..773fcc5017 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -498,53 +498,7 @@ void DocTools::generate(bool p_basic_types) { } DocData::MethodDoc method; - - method.name = E.name; - - if (E.flags & METHOD_FLAG_VIRTUAL) { - method.qualifiers = "virtual"; - } - - if (E.flags & METHOD_FLAG_CONST) { - if (!method.qualifiers.is_empty()) { - method.qualifiers += " "; - } - method.qualifiers += "const"; - } - - if (E.flags & METHOD_FLAG_VARARG) { - if (!method.qualifiers.is_empty()) { - method.qualifiers += " "; - } - method.qualifiers += "vararg"; - } - - if (E.flags & METHOD_FLAG_STATIC) { - if (!method.qualifiers.is_empty()) { - method.qualifiers += " "; - } - method.qualifiers += "static"; - } - - for (int i = -1; i < E.arguments.size(); i++) { - if (i == -1) { -#ifdef DEBUG_METHODS_ENABLED - DocData::return_doc_from_retinfo(method, E.return_val); -#endif - } else { - const PropertyInfo &arginfo = E.arguments[i]; - DocData::ArgumentDoc argument; - DocData::argument_doc_from_arginfo(argument, arginfo); - - int darg_idx = i - (E.arguments.size() - E.default_arguments.size()); - if (darg_idx >= 0) { - Variant default_arg = E.default_arguments[darg_idx]; - argument.default_value = default_arg.get_construct_string().replace("\n", " "); - } - - method.arguments.push_back(argument); - } - } + DocData::method_doc_from_methodinfo(method, E, ""); Vector<Error> errs = ClassDB::get_method_error_return_values(name, E.name); if (errs.size()) { diff --git a/editor/doc_tools.h b/editor/doc_tools.h index 843cdf87a6..b3e45c6472 100644 --- a/editor/doc_tools.h +++ b/editor/doc_tools.h @@ -53,4 +53,4 @@ public: Error load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size); }; -#endif // DOC_DATA_H +#endif // DOC_TOOLS_H diff --git a/editor/editor_about.h b/editor/editor_about.h index 6f05700582..971843f6d2 100644 --- a/editor/editor_about.h +++ b/editor/editor_about.h @@ -75,4 +75,4 @@ public: ~EditorAbout(); }; -#endif +#endif // EDITOR_ABOUT_H diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 3d4bee4b4e..8dc8a0ab6b 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -100,8 +100,8 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { extension_guess["tga"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")); extension_guess["webp"] = tree->get_theme_icon(SNAME("ImageTexture"), SNAME("EditorIcons")); - extension_guess["wav"] = tree->get_theme_icon(SNAME("AudioStreamSample"), SNAME("EditorIcons")); - extension_guess["ogg"] = tree->get_theme_icon(SNAME("AudioStreamOGGVorbis"), SNAME("EditorIcons")); + extension_guess["wav"] = tree->get_theme_icon(SNAME("AudioStreamWAV"), SNAME("EditorIcons")); + extension_guess["ogg"] = tree->get_theme_icon(SNAME("AudioStreamOggVorbis"), SNAME("EditorIcons")); extension_guess["mp3"] = tree->get_theme_icon(SNAME("AudioStreamMP3"), SNAME("EditorIcons")); extension_guess["scn"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")); @@ -112,6 +112,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { extension_guess["glb"] = tree->get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")); extension_guess["gdshader"] = tree->get_theme_icon(SNAME("Shader"), SNAME("EditorIcons")); + extension_guess["gdshaderinc"] = tree->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")); extension_guess["gd"] = tree->get_theme_icon(SNAME("GDScript"), SNAME("EditorIcons")); if (Engine::get_singleton()->has_singleton("GodotSharp")) { extension_guess["cs"] = tree->get_theme_icon(SNAME("CSharpScript"), SNAME("EditorIcons")); diff --git a/editor/editor_asset_installer.h b/editor/editor_asset_installer.h index c44f4c5d22..9c88116336 100644 --- a/editor/editor_asset_installer.h +++ b/editor/editor_asset_installer.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITORASSETINSTALLER_H -#define EDITORASSETINSTALLER_H +#ifndef EDITOR_ASSET_INSTALLER_H +#define EDITOR_ASSET_INSTALLER_H #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" @@ -59,4 +59,4 @@ public: EditorAssetInstaller(); }; -#endif // EDITORASSETINSTALLER_H +#endif // EDITOR_ASSET_INSTALLER_H diff --git a/editor/editor_autoload_settings.h b/editor/editor_autoload_settings.h index e1e0bb0a64..0eda7016d3 100644 --- a/editor/editor_autoload_settings.h +++ b/editor/editor_autoload_settings.h @@ -112,4 +112,4 @@ public: ~EditorAutoloadSettings(); }; -#endif +#endif // EDITOR_AUTOLOAD_SETTINGS_H diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp new file mode 100644 index 0000000000..6a5604290f --- /dev/null +++ b/editor/editor_build_profile.cpp @@ -0,0 +1,797 @@ +/*************************************************************************/ +/* editor_build_profile.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "editor_build_profile.h" + +#include "core/io/dir_access.h" +#include "core/io/json.h" +#include "editor/editor_file_dialog.h" +#include "editor/editor_file_system.h" +#include "editor/editor_node.h" +#include "editor/editor_property_name_processor.h" +#include "editor/editor_scale.h" +#include "editor/editor_settings.h" + +const char *EditorBuildProfile::build_option_identifiers[BUILD_OPTION_MAX] = { + // This maps to SCons build options. + "disable_3d", + "disable_2d_physics", + "disable_3d_physics", + "disable_navigation", + "openxr", + "opengl3", + "vulkan", +}; + +const bool EditorBuildProfile::build_option_disable_values[BUILD_OPTION_MAX] = { + // This maps to SCons build options. + true, + true, + true, + true, + false, + false, + false +}; + +void EditorBuildProfile::set_disable_class(const StringName &p_class, bool p_disabled) { + if (p_disabled) { + disabled_classes.insert(p_class); + } else { + disabled_classes.erase(p_class); + } +} + +bool EditorBuildProfile::is_class_disabled(const StringName &p_class) const { + if (p_class == StringName()) { + return false; + } + return disabled_classes.has(p_class) || is_class_disabled(ClassDB::get_parent_class_nocheck(p_class)); +} + +void EditorBuildProfile::set_item_collapsed(const StringName &p_class, bool p_collapsed) { + if (p_collapsed) { + collapsed_classes.insert(p_class); + } else { + collapsed_classes.erase(p_class); + } +} + +bool EditorBuildProfile::is_item_collapsed(const StringName &p_class) const { + return collapsed_classes.has(p_class); +} + +void EditorBuildProfile::set_disable_build_option(BuildOption p_build_option, bool p_disable) { + ERR_FAIL_INDEX(p_build_option, BUILD_OPTION_MAX); + build_options_disabled[p_build_option] = p_disable; +} + +void EditorBuildProfile::clear_disabled_classes() { + disabled_classes.clear(); + collapsed_classes.clear(); +} + +bool EditorBuildProfile::is_build_option_disabled(BuildOption p_build_option) const { + ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, false); + return build_options_disabled[p_build_option]; +} + +bool EditorBuildProfile::get_build_option_disable_value(BuildOption p_build_option) { + ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, false); + return build_option_disable_values[p_build_option]; +} + +void EditorBuildProfile::set_force_detect_classes(const String &p_classes) { + force_detect_classes = p_classes; +} + +String EditorBuildProfile::get_force_detect_classes() const { + return force_detect_classes; +} + +String EditorBuildProfile::get_build_option_name(BuildOption p_build_option) { + ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, String()); + const char *build_option_names[BUILD_OPTION_MAX] = { + TTRC("3D Engine"), + TTRC("2D Physics"), + TTRC("3D Physics"), + TTRC("Navigation"), + TTRC("XR"), + TTRC("RenderingDevice"), + TTRC("OpenGL"), + TTRC("Vulkan"), + }; + return TTRGET(build_option_names[p_build_option]); +} + +String EditorBuildProfile::get_build_option_description(BuildOption p_build_option) { + ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, String()); + + const char *build_option_descriptions[BUILD_OPTION_MAX] = { + TTRC("3D Nodes as well as RenderingServer access to 3D features."), + TTRC("2D Physics nodes and PhysicsServer2D."), + TTRC("3D Physics nodes and PhysicsServer3D."), + TTRC("Navigation, both 2D and 3D."), + TTRC("XR (AR and VR)."), + TTRC("RenderingDevice based rendering (if disabled, the OpenGL back-end is required)."), + TTRC("OpenGL back-end (if disabled, the RenderingDevice back-end is required)."), + TTRC("Vulkan back-end of RenderingDevice."), + }; + + return TTRGET(build_option_descriptions[p_build_option]); +} + +Error EditorBuildProfile::save_to_file(const String &p_path) { + Dictionary data; + data["type"] = "build_profile"; + Array dis_classes; + for (const StringName &E : disabled_classes) { + dis_classes.push_back(String(E)); + } + dis_classes.sort(); + data["disabled_classes"] = dis_classes; + + Dictionary dis_build_options; + for (int i = 0; i < BUILD_OPTION_MAX; i++) { + if (build_options_disabled[i]) { + dis_build_options[build_option_identifiers[i]] = build_option_disable_values[i]; + } + } + + data["disabled_build_options"] = dis_build_options; + + if (!force_detect_classes.is_empty()) { + data["force_detect_classes"] = force_detect_classes; + } + + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE); + ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_CREATE, "Cannot create file '" + p_path + "'."); + + JSON json; + String text = json.stringify(data, "\t"); + f->store_string(text); + return OK; +} + +Error EditorBuildProfile::load_from_file(const String &p_path) { + Error err; + String text = FileAccess::get_file_as_string(p_path, &err); + if (err != OK) { + return err; + } + + JSON json; + err = json.parse(text); + if (err != OK) { + ERR_PRINT("Error parsing '" + p_path + "' on line " + itos(json.get_error_line()) + ": " + json.get_error_message()); + return ERR_PARSE_ERROR; + } + + Dictionary data = json.get_data(); + + if (!data.has("type") || String(data["type"]) != "build_profile") { + ERR_PRINT("Error parsing '" + p_path + "', it's not a build profile."); + return ERR_PARSE_ERROR; + } + + disabled_classes.clear(); + + if (data.has("disabled_classes")) { + Array disabled_classes_arr = data["disabled_classes"]; + for (int i = 0; i < disabled_classes_arr.size(); i++) { + disabled_classes.insert(disabled_classes_arr[i]); + } + } + + for (int i = 0; i < BUILD_OPTION_MAX; i++) { + build_options_disabled[i] = false; + } + + if (data.has("disabled_build_options")) { + Dictionary disabled_build_options_arr = data["disabled_build_options"]; + List<Variant> keys; + disabled_build_options_arr.get_key_list(&keys); + + for (const Variant &K : keys) { + String key = K; + + for (int i = 0; i < BUILD_OPTION_MAX; i++) { + String f = build_option_identifiers[i]; + if (f == key) { + build_options_disabled[i] = true; + break; + } + } + } + } + + if (data.has("force_detect_classes")) { + force_detect_classes = data["force_detect_classes"]; + } + + return OK; +} + +void EditorBuildProfile::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_disable_class", "class_name", "disable"), &EditorBuildProfile::set_disable_class); + ClassDB::bind_method(D_METHOD("is_class_disabled", "class_name"), &EditorBuildProfile::is_class_disabled); + + ClassDB::bind_method(D_METHOD("set_disable_build_option", "build_option", "disable"), &EditorBuildProfile::set_disable_build_option); + ClassDB::bind_method(D_METHOD("is_build_option_disabled", "build_option"), &EditorBuildProfile::is_build_option_disabled); + + ClassDB::bind_method(D_METHOD("get_build_option_name", "build_option"), &EditorBuildProfile::_get_build_option_name); + + ClassDB::bind_method(D_METHOD("save_to_file", "path"), &EditorBuildProfile::save_to_file); + ClassDB::bind_method(D_METHOD("load_from_file", "path"), &EditorBuildProfile::load_from_file); + + BIND_ENUM_CONSTANT(BUILD_OPTION_3D); + BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_2D); + BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_3D); + BIND_ENUM_CONSTANT(BUILD_OPTION_NAVIGATION); + BIND_ENUM_CONSTANT(BUILD_OPTION_XR); + BIND_ENUM_CONSTANT(BUILD_OPTION_RENDERING_DEVICE); + BIND_ENUM_CONSTANT(BUILD_OPTION_OPENGL); + BIND_ENUM_CONSTANT(BUILD_OPTION_VULKAN); + BIND_ENUM_CONSTANT(BUILD_OPTION_MAX); +} + +EditorBuildProfile::EditorBuildProfile() {} + +////////////////////////// + +void EditorBuildProfileManager::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + String last_file = EditorSettings::get_singleton()->get_project_metadata("build_profile", "last_file_path", ""); + if (!last_file.is_empty()) { + _import_profile(last_file); + } + if (edited.is_null()) { + edited.instantiate(); + _update_edited_profile(); + } + + } break; + } +} + +void EditorBuildProfileManager::_profile_action(int p_action) { + last_action = Action(p_action); + + switch (p_action) { + case ACTION_RESET: { + confirm_dialog->set_text("Reset the edited profile?"); + confirm_dialog->popup_centered(); + } break; + case ACTION_LOAD: { + import_profile->popup_file_dialog(); + } break; + case ACTION_SAVE: { + if (!profile_path->get_text().is_empty()) { + Error err = edited->save_to_file(profile_path->get_text()); + if (err != OK) { + EditorNode::get_singleton()->show_warning(TTR("File saving failed.")); + } + break; + } + [[fallthrough]]; + } + case ACTION_SAVE_AS: { + export_profile->popup_file_dialog(); + export_profile->set_current_file(profile_path->get_text()); + } break; + case ACTION_NEW: { + confirm_dialog->set_text("Create a new profile?"); + confirm_dialog->popup_centered(); + } break; + case ACTION_DETECT: { + confirm_dialog->set_text("This will scan all files in the current project to detect used classes."); + confirm_dialog->popup_centered(); + } break; + case ACTION_MAX: { + } break; + } +} + +void EditorBuildProfileManager::_find_files(EditorFileSystemDirectory *p_dir, const HashMap<String, DetectedFile> &p_cache, HashMap<String, DetectedFile> &r_detected) { + if (p_dir == nullptr) { + return; + } + + for (int i = 0; i < p_dir->get_file_count(); i++) { + String p = p_dir->get_file_path(i); + + uint64_t timestamp = 0; + String md5; + + if (p_cache.has(p)) { + const DetectedFile &cache = p_cache[p]; + // Check if timestamp and MD5 match. + timestamp = FileAccess::get_modified_time(p); + bool cache_valid = true; + if (cache.timestamp != timestamp) { + md5 = FileAccess::get_md5(p); + if (md5 != cache.md5) { + cache_valid = false; + } + } + + if (cache_valid) { + r_detected.insert(p, cache); + continue; + } + } + + // Not cached, or cache invalid. + + DetectedFile cache; + + HashSet<StringName> classes; + ResourceLoader::get_classes_used(p, &classes); + + for (const StringName &E : classes) { + cache.classes.push_back(E); + } + + if (md5.is_empty()) { + cache.timestamp = FileAccess::get_modified_time(p); + cache.md5 = FileAccess::get_md5(p); + } else { + cache.timestamp = timestamp; + cache.md5 = md5; + } + + r_detected.insert(p, cache); + } + + for (int i = 0; i < p_dir->get_subdir_count(); i++) { + _find_files(p_dir->get_subdir(i), p_cache, r_detected); + } +} + +void EditorBuildProfileManager::_detect_classes() { + HashMap<String, DetectedFile> previous_file_cache; + + Ref<FileAccess> f = FileAccess::open("res://.godot/editor/used_class_cache", FileAccess::READ); + if (f.is_valid()) { + while (!f->eof_reached()) { + String l = f->get_line(); + Vector<String> fields = l.split("::"); + if (fields.size() == 4) { + String path = fields[0]; + DetectedFile df; + df.timestamp = fields[1].to_int(); + df.md5 = fields[2]; + df.classes = fields[3].split(","); + previous_file_cache.insert(path, df); + } + } + f.unref(); + } + + HashMap<String, DetectedFile> updated_file_cache; + + _find_files(EditorFileSystem::get_singleton()->get_filesystem(), previous_file_cache, updated_file_cache); + + HashSet<StringName> used_classes; + + // Find classes and update the disk cache in the process. + f = FileAccess::open("res://.godot/editor/used_class_cache", FileAccess::WRITE); + + for (const KeyValue<String, DetectedFile> &E : updated_file_cache) { + String l = E.key + "::" + itos(E.value.timestamp) + "::" + E.value.md5 + "::"; + for (int i = 0; i < E.value.classes.size(); i++) { + String c = E.value.classes[i]; + if (i > 0) { + l += ","; + } + l += c; + used_classes.insert(c); + } + f->store_line(l); + } + + f.unref(); + + // Add forced ones. + + Vector<String> force_detect = edited->get_force_detect_classes().split(","); + for (int i = 0; i < force_detect.size(); i++) { + String c = force_detect[i].strip_edges(); + if (c.is_empty()) { + continue; + } + used_classes.insert(c); + } + + // Filter all classes to discard inherited ones. + + HashSet<StringName> all_used_classes; + + for (const StringName &E : used_classes) { + StringName c = E; + if (!ClassDB::class_exists(c)) { + // Maybe this is an old class that got replaced? try getting compat class. + c = ClassDB::get_compatibility_class(c); + if (!c) { + // No luck, skip. + continue; + } + } + while (c) { + all_used_classes.insert(c); + c = ClassDB::get_parent_class(c); + } + } + + edited->clear_disabled_classes(); + + List<StringName> all_classes; + ClassDB::get_class_list(&all_classes); + + for (const StringName &E : all_classes) { + if (all_used_classes.has(E)) { + // This class is valid, do nothing. + continue; + } + + StringName p = ClassDB::get_parent_class(E); + if (!p || all_used_classes.has(p)) { + // If no parent, or if the parent is enabled, then add to disabled classes. + // This way we avoid disabling redundant classes. + edited->set_disable_class(E, true); + } + } +} + +void EditorBuildProfileManager::_action_confirm() { + switch (last_action) { + case ACTION_RESET: { + edited.instantiate(); + _update_edited_profile(); + } break; + case ACTION_LOAD: { + } break; + case ACTION_SAVE: { + } break; + case ACTION_SAVE_AS: { + } break; + case ACTION_NEW: { + profile_path->set_text(""); + edited.instantiate(); + _update_edited_profile(); + } break; + case ACTION_DETECT: { + _detect_classes(); + _update_edited_profile(); + } break; + case ACTION_MAX: { + } break; + } +} + +void EditorBuildProfileManager::_fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected) { + TreeItem *class_item = class_list->create_item(p_parent); + class_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + class_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_class, "Node")); + String text = p_class; + + bool disabled = edited->is_class_disabled(p_class); + if (disabled) { + class_item->set_custom_color(0, class_list->get_theme_color(SNAME("disabled_font_color"), SNAME("Editor"))); + } + + class_item->set_text(0, text); + class_item->set_editable(0, true); + class_item->set_selectable(0, true); + class_item->set_metadata(0, p_class); + + bool collapsed = edited->is_item_collapsed(p_class); + class_item->set_collapsed(collapsed); + + if (p_class == p_selected) { + class_item->select(0); + } + if (disabled) { + // Class disabled, do nothing else (do not show further). + return; + } + + class_item->set_checked(0, true); // If it's not disabled, its checked. + + List<StringName> child_classes; + ClassDB::get_direct_inheriters_from_class(p_class, &child_classes); + child_classes.sort_custom<StringName::AlphCompare>(); + + for (const StringName &name : child_classes) { + if (String(name).begins_with("Editor") || ClassDB::get_api_type(name) != ClassDB::API_CORE) { + continue; + } + _fill_classes_from(class_item, name, p_selected); + } +} + +void EditorBuildProfileManager::_class_list_item_selected() { + if (updating_build_options) { + return; + } + + TreeItem *item = class_list->get_selected(); + if (!item) { + return; + } + + Variant md = item->get_metadata(0); + if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) { + String class_name = md; + String class_description; + + DocTools *dd = EditorHelp::get_doc_data(); + HashMap<String, DocData::ClassDoc>::Iterator E = dd->class_list.find(class_name); + if (E) { + class_description = DTR(E->value.brief_description); + } + + description_bit->set_text(class_description); + } else if (md.get_type() == Variant::INT) { + int build_option_id = md; + String build_option_description = EditorBuildProfile::get_build_option_description(EditorBuildProfile::BuildOption(build_option_id)); + + description_bit->set_text(TTRGET(build_option_description)); + return; + } else { + return; + } +} + +void EditorBuildProfileManager::_class_list_item_edited() { + if (updating_build_options) { + return; + } + + TreeItem *item = class_list->get_edited(); + if (!item) { + return; + } + + bool checked = item->is_checked(0); + + Variant md = item->get_metadata(0); + if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) { + String class_selected = md; + edited->set_disable_class(class_selected, !checked); + _update_edited_profile(); + } else if (md.get_type() == Variant::INT) { + int build_option_selected = md; + edited->set_disable_build_option(EditorBuildProfile::BuildOption(build_option_selected), !checked); + } +} + +void EditorBuildProfileManager::_class_list_item_collapsed(Object *p_item) { + if (updating_build_options) { + return; + } + + TreeItem *item = Object::cast_to<TreeItem>(p_item); + if (!item) { + return; + } + + Variant md = item->get_metadata(0); + if (md.get_type() != Variant::STRING && md.get_type() != Variant::STRING_NAME) { + return; + } + + String class_name = md; + bool collapsed = item->is_collapsed(); + edited->set_item_collapsed(class_name, collapsed); +} + +void EditorBuildProfileManager::_update_edited_profile() { + String class_selected; + int build_option_selected = -1; + + if (class_list->get_selected()) { + Variant md = class_list->get_selected()->get_metadata(0); + if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) { + class_selected = md; + } else if (md.get_type() == Variant::INT) { + build_option_selected = md; + } + } + + class_list->clear(); + + updating_build_options = true; + + TreeItem *root = class_list->create_item(); + + TreeItem *build_options = class_list->create_item(root); + build_options->set_text(0, TTR("General Features:")); + for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) { + TreeItem *build_option; + build_option = class_list->create_item(build_options); + + build_option->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); + build_option->set_text(0, EditorBuildProfile::get_build_option_name(EditorBuildProfile::BuildOption(i))); + build_option->set_selectable(0, true); + build_option->set_editable(0, true); + build_option->set_metadata(0, i); + if (!edited->is_build_option_disabled(EditorBuildProfile::BuildOption(i))) { + build_option->set_checked(0, true); + } + + if (i == build_option_selected) { + build_option->select(0); + } + } + + TreeItem *classes = class_list->create_item(root); + classes->set_text(0, TTR("Nodes and Classes:")); + + _fill_classes_from(classes, "Node", class_selected); + _fill_classes_from(classes, "Resource", class_selected); + + force_detect_classes->set_text(edited->get_force_detect_classes()); + + updating_build_options = false; + + _class_list_item_selected(); +} + +void EditorBuildProfileManager::_force_detect_classes_changed(const String &p_text) { + if (updating_build_options) { + return; + } + edited->set_force_detect_classes(force_detect_classes->get_text()); +} + +void EditorBuildProfileManager::_import_profile(const String &p_path) { + Ref<EditorBuildProfile> profile; + profile.instantiate(); + Error err = profile->load_from_file(p_path); + String basefile = p_path.get_file(); + if (err != OK) { + EditorNode::get_singleton()->show_warning(vformat(TTR("File '%s' format is invalid, import aborted."), basefile)); + return; + } + + profile_path->set_text(p_path); + EditorSettings::get_singleton()->set_project_metadata("build_profile", "last_file_path", p_path); + + edited = profile; + _update_edited_profile(); +} + +void EditorBuildProfileManager::_export_profile(const String &p_path) { + ERR_FAIL_COND(edited.is_null()); + Error err = edited->save_to_file(p_path); + if (err != OK) { + EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving profile to path: '%s'."), p_path)); + } else { + profile_path->set_text(p_path); + EditorSettings::get_singleton()->set_project_metadata("build_profile", "last_file_path", p_path); + } +} + +Ref<EditorBuildProfile> EditorBuildProfileManager::get_current_profile() { + return edited; +} + +EditorBuildProfileManager *EditorBuildProfileManager::singleton = nullptr; + +void EditorBuildProfileManager::_bind_methods() { + ClassDB::bind_method("_update_selected_profile", &EditorBuildProfileManager::_update_edited_profile); +} + +EditorBuildProfileManager::EditorBuildProfileManager() { + VBoxContainer *main_vbc = memnew(VBoxContainer); + add_child(main_vbc); + + HBoxContainer *path_hbc = memnew(HBoxContainer); + profile_path = memnew(LineEdit); + path_hbc->add_child(profile_path); + profile_path->set_editable(true); + profile_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); + + profile_actions[ACTION_NEW] = memnew(Button(TTR("New"))); + path_hbc->add_child(profile_actions[ACTION_NEW]); + profile_actions[ACTION_NEW]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_NEW)); + + profile_actions[ACTION_LOAD] = memnew(Button(TTR("Load"))); + path_hbc->add_child(profile_actions[ACTION_LOAD]); + profile_actions[ACTION_LOAD]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_LOAD)); + + profile_actions[ACTION_SAVE] = memnew(Button(TTR("Save"))); + path_hbc->add_child(profile_actions[ACTION_SAVE]); + profile_actions[ACTION_SAVE]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_SAVE)); + + profile_actions[ACTION_SAVE_AS] = memnew(Button(TTR("Save As"))); + path_hbc->add_child(profile_actions[ACTION_SAVE_AS]); + profile_actions[ACTION_SAVE_AS]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_SAVE_AS)); + + main_vbc->add_margin_child(TTR("Profile:"), path_hbc); + + main_vbc->add_child(memnew(HSeparator)); + + HBoxContainer *profiles_hbc = memnew(HBoxContainer); + + profile_actions[ACTION_RESET] = memnew(Button(TTR("Reset to Defaults"))); + profiles_hbc->add_child(profile_actions[ACTION_RESET]); + profile_actions[ACTION_RESET]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_RESET)); + + profile_actions[ACTION_DETECT] = memnew(Button(TTR("Detect from Project"))); + profiles_hbc->add_child(profile_actions[ACTION_DETECT]); + profile_actions[ACTION_DETECT]->connect("pressed", callable_mp(this, &EditorBuildProfileManager::_profile_action), varray(ACTION_DETECT)); + + main_vbc->add_margin_child(TTR("Actions:"), profiles_hbc); + + class_list = memnew(Tree); + class_list->set_hide_root(true); + class_list->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); + class_list->connect("cell_selected", callable_mp(this, &EditorBuildProfileManager::_class_list_item_selected)); + class_list->connect("item_edited", callable_mp(this, &EditorBuildProfileManager::_class_list_item_edited), varray(), CONNECT_DEFERRED); + class_list->connect("item_collapsed", callable_mp(this, &EditorBuildProfileManager::_class_list_item_collapsed)); + // It will be displayed once the user creates or chooses a profile. + main_vbc->add_margin_child(TTR("Configure Engine Build Profile:"), class_list, true); + + description_bit = memnew(EditorHelpBit); + description_bit->set_custom_minimum_size(Size2(0, 80) * EDSCALE); + main_vbc->add_margin_child(TTR("Description:"), description_bit, false); + + confirm_dialog = memnew(ConfirmationDialog); + add_child(confirm_dialog); + confirm_dialog->set_title(TTR("Please Confirm:")); + confirm_dialog->connect("confirmed", callable_mp(this, &EditorBuildProfileManager::_action_confirm)); + + import_profile = memnew(EditorFileDialog); + add_child(import_profile); + import_profile->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); + import_profile->add_filter("*.build", TTR("Egine Build Profile")); + import_profile->connect("files_selected", callable_mp(this, &EditorBuildProfileManager::_import_profile)); + import_profile->set_title(TTR("Load Profile")); + import_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + + export_profile = memnew(EditorFileDialog); + add_child(export_profile); + export_profile->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); + export_profile->add_filter("*.build", TTR("Egine Build Profile")); + export_profile->connect("file_selected", callable_mp(this, &EditorBuildProfileManager::_export_profile)); + export_profile->set_title(TTR("Export Profile")); + export_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + + force_detect_classes = memnew(LineEdit); + main_vbc->add_margin_child(TTR("Forced classes on detect:"), force_detect_classes); + force_detect_classes->connect("text_changed", callable_mp(this, &EditorBuildProfileManager::_force_detect_classes_changed)); + + set_title(TTR("Edit Build Configuration Profile")); + + singleton = this; +} diff --git a/editor/editor_build_profile.h b/editor/editor_build_profile.h new file mode 100644 index 0000000000..bb6494b8c9 --- /dev/null +++ b/editor/editor_build_profile.h @@ -0,0 +1,173 @@ +/*************************************************************************/ +/* editor_build_profile.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 EDITOR_BUILD_PROFILE_H +#define EDITOR_BUILD_PROFILE_H + +#include "core/io/file_access.h" +#include "core/object/ref_counted.h" +#include "editor/editor_help.h" +#include "scene/gui/dialogs.h" +#include "scene/gui/option_button.h" +#include "scene/gui/separator.h" +#include "scene/gui/split_container.h" +#include "scene/gui/tree.h" + +class EditorBuildProfile : public RefCounted { + GDCLASS(EditorBuildProfile, RefCounted); + +public: + enum BuildOption { + BUILD_OPTION_3D, + BUILD_OPTION_PHYSICS_2D, + BUILD_OPTION_PHYSICS_3D, + BUILD_OPTION_NAVIGATION, + BUILD_OPTION_XR, + BUILD_OPTION_RENDERING_DEVICE, + BUILD_OPTION_OPENGL, + BUILD_OPTION_VULKAN, + BUILD_OPTION_MAX + }; + +private: + HashSet<StringName> disabled_classes; + + HashSet<StringName> collapsed_classes; + + String force_detect_classes; + + bool build_options_disabled[BUILD_OPTION_MAX] = {}; + static const char *build_option_identifiers[BUILD_OPTION_MAX]; + static const bool build_option_disable_values[BUILD_OPTION_MAX]; + + String _get_build_option_name(BuildOption p_build_option) { return get_build_option_name(p_build_option); } + +protected: + static void _bind_methods(); + +public: + void set_disable_class(const StringName &p_class, bool p_disabled); + bool is_class_disabled(const StringName &p_class) const; + + void set_item_collapsed(const StringName &p_class, bool p_collapsed); + bool is_item_collapsed(const StringName &p_class) const; + + void set_disable_build_option(BuildOption p_build_option, bool p_disable); + bool is_build_option_disabled(BuildOption p_build_option) const; + + void set_force_detect_classes(const String &p_classes); + String get_force_detect_classes() const; + + void clear_disabled_classes(); + + Error save_to_file(const String &p_path); + Error load_from_file(const String &p_path); + + static String get_build_option_name(BuildOption p_build_option); + static String get_build_option_description(BuildOption p_build_option); + static bool get_build_option_disable_value(BuildOption p_build_option); + + EditorBuildProfile(); +}; + +VARIANT_ENUM_CAST(EditorBuildProfile::BuildOption) + +class EditorFileSystemDirectory; + +class EditorBuildProfileManager : public AcceptDialog { + GDCLASS(EditorBuildProfileManager, AcceptDialog); + + enum Action { + ACTION_NEW, + ACTION_RESET, + ACTION_LOAD, + ACTION_SAVE, + ACTION_SAVE_AS, + ACTION_DETECT, + ACTION_MAX + }; + + Action last_action = ACTION_NEW; + + ConfirmationDialog *confirm_dialog = nullptr; + Button *profile_actions[ACTION_MAX]; + + Tree *class_list = nullptr; + EditorHelpBit *description_bit = nullptr; + + EditorFileDialog *import_profile = nullptr; + EditorFileDialog *export_profile = nullptr; + + LineEdit *profile_path = nullptr; + + LineEdit *force_detect_classes = nullptr; + + void _profile_action(int p_action); + void _action_confirm(); + + void _update_edited_profile(); + void _fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected); + + Ref<EditorBuildProfile> edited; + + void _import_profile(const String &p_path); + void _export_profile(const String &p_path); + + bool updating_build_options = false; + + void _class_list_item_selected(); + void _class_list_item_edited(); + void _class_list_item_collapsed(Object *p_item); + void _detect_classes(); + + void _force_detect_classes_changed(const String &p_text); + + struct DetectedFile { + uint32_t timestamp = 0; + String md5; + Vector<String> classes; + }; + + void _find_files(EditorFileSystemDirectory *p_dir, const HashMap<String, DetectedFile> &p_cache, HashMap<String, DetectedFile> &r_detected); + + static EditorBuildProfileManager *singleton; + +protected: + static void _bind_methods(); + void _notification(int p_what); + +public: + Ref<EditorBuildProfile> get_current_profile(); + + static EditorBuildProfileManager *get_singleton() { return singleton; } + EditorBuildProfileManager(); +}; + +#endif // EDITOR_BUILD_PROFILE_H diff --git a/editor/editor_command_palette.h b/editor/editor_command_palette.h index 124703cca4..b3e84771d0 100644 --- a/editor/editor_command_palette.h +++ b/editor/editor_command_palette.h @@ -101,4 +101,4 @@ public: Ref<Shortcut> ED_SHORTCUT_AND_COMMAND(const String &p_path, const String &p_name, Key p_keycode = Key::NONE, String p_command = ""); -#endif //EDITOR_COMMAND_PALETTE_H +#endif // EDITOR_COMMAND_PALETTE_H diff --git a/editor/editor_export.h b/editor/editor_export.h deleted file mode 100644 index 6f41736d2d..0000000000 --- a/editor/editor_export.h +++ /dev/null @@ -1,532 +0,0 @@ -/*************************************************************************/ -/* editor_export.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 EDITOR_EXPORT_H -#define EDITOR_EXPORT_H - -#include "core/io/dir_access.h" -#include "core/io/resource.h" -#include "scene/gui/rich_text_label.h" -#include "scene/main/node.h" -#include "scene/main/timer.h" -#include "scene/resources/texture.h" - -class FileAccess; -class EditorExportPlatform; -class EditorFileSystemDirectory; -struct EditorProgress; - -class EditorExportPreset : public RefCounted { - GDCLASS(EditorExportPreset, RefCounted); - -public: - enum ExportFilter { - EXPORT_ALL_RESOURCES, - EXPORT_SELECTED_SCENES, - EXPORT_SELECTED_RESOURCES, - EXCLUDE_SELECTED_RESOURCES, - }; - - enum ScriptExportMode { - MODE_SCRIPT_TEXT, - MODE_SCRIPT_COMPILED, - }; - -private: - Ref<EditorExportPlatform> platform; - ExportFilter export_filter = EXPORT_ALL_RESOURCES; - String include_filter; - String exclude_filter; - String export_path; - - String exporter; - HashSet<String> selected_files; - bool runnable = false; - - friend class EditorExport; - friend class EditorExportPlatform; - - List<PropertyInfo> properties; - HashMap<StringName, Variant> values; - - String name; - - String custom_features; - - String enc_in_filters; - String enc_ex_filters; - bool enc_pck = false; - bool enc_directory = false; - - int script_mode = MODE_SCRIPT_COMPILED; - String script_key; - -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; - -public: - Ref<EditorExportPlatform> get_platform() const; - - bool has(const StringName &p_property) const { return values.has(p_property); } - - void update_files_to_export(); - - Vector<String> get_files_to_export() const; - - void add_export_file(const String &p_path); - void remove_export_file(const String &p_path); - bool has_export_file(const String &p_path); - - void set_name(const String &p_name); - String get_name() const; - - void set_runnable(bool p_enable); - bool is_runnable() const; - - void set_export_filter(ExportFilter p_filter); - ExportFilter get_export_filter() const; - - void set_include_filter(const String &p_include); - String get_include_filter() const; - - void set_exclude_filter(const String &p_exclude); - String get_exclude_filter() const; - - void set_custom_features(const String &p_custom_features); - String get_custom_features() const; - - void set_export_path(const String &p_path); - String get_export_path() const; - - void set_enc_in_filter(const String &p_filter); - String get_enc_in_filter() const; - - void set_enc_ex_filter(const String &p_filter); - String get_enc_ex_filter() const; - - void set_enc_pck(bool p_enabled); - bool get_enc_pck() const; - - void set_enc_directory(bool p_enabled); - bool get_enc_directory() const; - - void set_script_export_mode(int p_mode); - int get_script_export_mode() const; - - void set_script_encryption_key(const String &p_key); - String get_script_encryption_key() const; - - const List<PropertyInfo> &get_properties() const { return properties; } - - EditorExportPreset() {} -}; - -struct SharedObject { - String path; - Vector<String> tags; - String target; - - SharedObject(const String &p_path, const Vector<String> &p_tags, const String &p_target) : - path(p_path), - tags(p_tags), - target(p_target) { - } - - SharedObject() {} -}; - -class EditorExportPlatform : public RefCounted { - GDCLASS(EditorExportPlatform, RefCounted); - -public: - typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); - typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so); - - enum ExportMessageType { - EXPORT_MESSAGE_NONE, - EXPORT_MESSAGE_INFO, - EXPORT_MESSAGE_WARNING, - EXPORT_MESSAGE_ERROR, - }; - - struct ExportMessage { - ExportMessageType msg_type; - String category; - String text; - }; - -private: - struct SavedData { - uint64_t ofs = 0; - uint64_t size = 0; - bool encrypted = false; - Vector<uint8_t> md5; - CharString path_utf8; - - bool operator<(const SavedData &p_data) const { - return path_utf8 < p_data.path_utf8; - } - }; - - struct PackData { - Ref<FileAccess> f; - Vector<SavedData> file_ofs; - EditorProgress *ep = nullptr; - Vector<SharedObject> *so_files = nullptr; - }; - - struct ZipData { - void *zip = nullptr; - EditorProgress *ep = nullptr; - }; - - struct FeatureContainers { - HashSet<String> features; - Vector<String> features_pv; - }; - - Vector<ExportMessage> messages; - - void _export_find_resources(EditorFileSystemDirectory *p_dir, HashSet<String> &p_paths); - void _export_find_dependencies(const String &p_path, HashSet<String> &p_paths); - - void gen_debug_flags(Vector<String> &r_flags, int p_flags); - static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); - static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); - - void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude); - void _edit_filter_list(HashSet<String> &r_list, const String &p_filter, bool exclude); - - static Error _add_shared_object(void *p_userdata, const SharedObject &p_so); - -protected: - struct ExportNotifier { - ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); - ~ExportNotifier(); - }; - - FeatureContainers get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug); - - bool exists_export_template(String template_file_name, String *err) const; - String find_export_template(String template_file_name, String *err = nullptr) const; - void gen_export_flags(Vector<String> &r_flags, int p_flags); - -public: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) = 0; - - struct ExportOption { - PropertyInfo option; - Variant default_value; - - ExportOption(const PropertyInfo &p_info, const Variant &p_default) : - option(p_info), - default_value(p_default) { - } - ExportOption() {} - }; - - virtual Ref<EditorExportPreset> create_preset(); - - virtual void clear_messages() { messages.clear(); } - virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) { - ExportMessage msg; - msg.category = p_category; - msg.text = p_message; - msg.msg_type = p_type; - messages.push_back(msg); - switch (p_type) { - case EXPORT_MESSAGE_INFO: { - print_line(vformat("%s: %s\n", msg.category, msg.text)); - } break; - case EXPORT_MESSAGE_WARNING: { - WARN_PRINT(vformat("%s: %s\n", msg.category, msg.text)); - } break; - case EXPORT_MESSAGE_ERROR: { - ERR_PRINT(vformat("%s: %s\n", msg.category, msg.text)); - } break; - default: - break; - } - } - - virtual int get_message_count() const { - return messages.size(); - } - - virtual ExportMessage get_message(int p_index) const { - ERR_FAIL_INDEX_V(p_index, messages.size(), ExportMessage()); - return messages[p_index]; - } - - virtual ExportMessageType get_worst_message_type() const { - ExportMessageType worst_type = EXPORT_MESSAGE_NONE; - for (int i = 0; i < messages.size(); i++) { - worst_type = MAX(worst_type, messages[i].msg_type); - } - return worst_type; - } - - virtual bool fill_log_messages(RichTextLabel *p_log, Error p_err); - - virtual void get_export_options(List<ExportOption> *r_options) = 0; - virtual bool should_update_export_options() { return false; } - virtual bool get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const { return true; } - - virtual String get_os_name() const = 0; - virtual String get_name() const = 0; - virtual Ref<Texture2D> get_logo() const = 0; - - Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr); - - Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr); - Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); - - virtual bool poll_export() { return false; } - virtual int get_options_count() const { return 0; } - virtual String get_options_tooltip() const { return ""; } - virtual Ref<ImageTexture> get_option_icon(int p_index) const; - virtual String get_option_label(int p_device) const { return ""; } - virtual String get_option_tooltip(int p_device) const { return ""; } - - enum DebugFlags { - DEBUG_FLAG_DUMB_CLIENT = 1, - DEBUG_FLAG_REMOTE_DEBUG = 2, - DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST = 4, - DEBUG_FLAG_VIEW_COLLISONS = 8, - DEBUG_FLAG_VIEW_NAVIGATION = 16, - }; - - virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; } - virtual Ref<Texture2D> get_run_icon() const { return get_logo(); } - - String test_etc2() const; - virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0; - - virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0; - virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) = 0; - virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); - virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); - virtual void get_platform_features(List<String> *r_features) = 0; - virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) = 0; - virtual String get_debug_protocol() const { return "tcp://"; } - - EditorExportPlatform(); -}; - -class EditorExportPlugin : public RefCounted { - GDCLASS(EditorExportPlugin, RefCounted); - - friend class EditorExportPlatform; - - Ref<EditorExportPreset> export_preset; - - Vector<SharedObject> shared_objects; - struct ExtraFile { - String path; - Vector<uint8_t> data; - bool remap = false; - }; - Vector<ExtraFile> extra_files; - bool skipped = false; - - Vector<String> ios_frameworks; - Vector<String> ios_embedded_frameworks; - Vector<String> ios_project_static_libs; - String ios_plist_content; - String ios_linker_flags; - Vector<String> ios_bundle_files; - String ios_cpp_code; - - Vector<String> osx_plugin_files; - - _FORCE_INLINE_ void _clear() { - shared_objects.clear(); - extra_files.clear(); - skipped = false; - } - - _FORCE_INLINE_ void _export_end() { - ios_frameworks.clear(); - ios_embedded_frameworks.clear(); - ios_bundle_files.clear(); - ios_plist_content = ""; - ios_linker_flags = ""; - ios_cpp_code = ""; - osx_plugin_files.clear(); - } - - void _export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features); - void _export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags); - void _export_end_script(); - -protected: - void set_export_preset(const Ref<EditorExportPreset> &p_preset); - Ref<EditorExportPreset> get_export_preset() const; - - void add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap); - void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String()); - - void add_ios_framework(const String &p_path); - void add_ios_embedded_framework(const String &p_path); - void add_ios_project_static_lib(const String &p_path); - void add_ios_plist_content(const String &p_plist_content); - void add_ios_linker_flags(const String &p_flags); - void add_ios_bundle_file(const String &p_path); - void add_ios_cpp_code(const String &p_code); - void add_osx_plugin_file(const String &p_path); - - void skip(); - - virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features); - virtual void _export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags); - - static void _bind_methods(); - - GDVIRTUAL3(_export_file, String, String, Vector<String>) - GDVIRTUAL4(_export_begin, Vector<String>, bool, String, uint32_t) - GDVIRTUAL0(_export_end) - -public: - Vector<String> get_ios_frameworks() const; - Vector<String> get_ios_embedded_frameworks() const; - Vector<String> get_ios_project_static_libs() const; - String get_ios_plist_content() const; - String get_ios_linker_flags() const; - Vector<String> get_ios_bundle_files() const; - String get_ios_cpp_code() const; - const Vector<String> &get_osx_plugin_files() const; - - EditorExportPlugin(); -}; - -class EditorExport : public Node { - GDCLASS(EditorExport, Node); - - Vector<Ref<EditorExportPlatform>> export_platforms; - Vector<Ref<EditorExportPreset>> export_presets; - Vector<Ref<EditorExportPlugin>> export_plugins; - - StringName _export_presets_updated; - - Timer *save_timer = nullptr; - bool block_save = false; - - static EditorExport *singleton; - - void _save(); - -protected: - friend class EditorExportPreset; - void save_presets(); - - void _notification(int p_what); - static void _bind_methods(); - -public: - static EditorExport *get_singleton() { return singleton; } - - void add_export_platform(const Ref<EditorExportPlatform> &p_platform); - int get_export_platform_count(); - Ref<EditorExportPlatform> get_export_platform(int p_idx); - - void add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos = -1); - int get_export_preset_count() const; - Ref<EditorExportPreset> get_export_preset(int p_idx); - void remove_export_preset(int p_idx); - - void add_export_plugin(const Ref<EditorExportPlugin> &p_plugin); - void remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin); - Vector<Ref<EditorExportPlugin>> get_export_plugins(); - - void load_config(); - void update_export_presets(); - bool poll_export_platforms(); - - EditorExport(); - ~EditorExport(); -}; - -class EditorExportPlatformPC : public EditorExportPlatform { - GDCLASS(EditorExportPlatformPC, EditorExportPlatform); - -private: - Ref<ImageTexture> logo; - String name; - String os_name; - - int chmod_flags = -1; - -public: - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; - - virtual void get_export_options(List<ExportOption> *r_options) override; - - virtual String get_name() const override; - virtual String get_os_name() const override; - virtual Ref<Texture2D> get_logo() const override; - - virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; - virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; - virtual Error sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); - virtual String get_template_file_name(const String &p_target, const String &p_arch) const = 0; - - virtual Error prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); - virtual Error modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { return OK; }; - virtual Error export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); - - void set_extension(const String &p_extension, const String &p_feature_key = "default"); - void set_name(const String &p_name); - void set_os_name(const String &p_name); - - void set_logo(const Ref<Texture2D> &p_logo); - - void add_platform_feature(const String &p_feature); - virtual void get_platform_features(List<String> *r_features) override; - virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override; - - int get_chmod_flags() const; - void set_chmod_flags(int p_flags); - - virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { - return Error::OK; - } -}; - -class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin { - GDCLASS(EditorExportTextSceneToBinaryPlugin, EditorExportPlugin); - -public: - virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) override; - EditorExportTextSceneToBinaryPlugin(); -}; - -#endif // EDITOR_IMPORT_EXPORT_H diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index adbba98897..56046a07d7 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -36,6 +36,7 @@ #include "core/io/resource_importer.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" +#include "core/object/worker_thread_pool.h" #include "core/os/os.h" #include "core/variant/variant_parser.h" #include "editor/editor_node.h" @@ -872,7 +873,7 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, Ref<DirAc fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path); fi->modified_time = 0; fi->import_modified_time = 0; - fi->import_valid = ResourceLoader::is_import_valid(path); + fi->import_valid = fi->type == "TextFile" ? true : ResourceLoader::is_import_valid(path); ItemAction ia; ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT; @@ -1023,7 +1024,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const fi->type = "TextFile"; } fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path); - fi->import_valid = ResourceLoader::is_import_valid(path); + fi->import_valid = fi->type == "TextFile" ? true : ResourceLoader::is_import_valid(path); fi->import_group_file = ResourceLoader::get_import_group_file(path); { @@ -2024,7 +2025,7 @@ void EditorFileSystem::_reimport_file(const String &p_file, const HashMap<String fs->files[cpos]->deps = _get_dependencies(p_file); fs->files[cpos]->type = importer->get_resource_type(); fs->files[cpos]->uid = uid; - fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); + fs->files[cpos]->import_valid = fs->files[cpos]->type == "TextFile" ? true : ResourceLoader::is_import_valid(p_file); if (ResourceUID::get_singleton()->has_id(uid)) { ResourceUID::get_singleton()->set_id(uid, p_file); @@ -2137,7 +2138,7 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { data.reimport_from = from; data.reimport_files = reimport_files.ptr(); - import_threads.begin_work(i - from + 1, this, &EditorFileSystem::_reimport_thread, &data); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &EditorFileSystem::_reimport_thread, &data, i - from + 1, -1, false, vformat(TTR("Import resources of type: %s"), reimport_files[from].importer)); int current_index = from - 1; do { if (current_index < data.max_index) { @@ -2145,9 +2146,9 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) { pr.step(reimport_files[current_index].path.get_file(), current_index); } OS::get_singleton()->delay_usec(1); - } while (!import_threads.is_done_dispatching()); + } while (!WorkerThreadPool::get_singleton()->is_group_task_completed(group_task)); - import_threads.end_work(); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); importer->import_threaded_end(); } @@ -2430,12 +2431,10 @@ EditorFileSystem::EditorFileSystem() { scan_total = 0; update_script_classes_queued.clear(); - import_threads.init(); ResourceUID::get_singleton()->clear(); //will be updated on scan ResourceSaver::set_get_resource_id_for_path(_resource_saver_get_resource_id_for_path); } EditorFileSystem::~EditorFileSystem() { - import_threads.finish(); ResourceSaver::set_get_resource_id_for_path(nullptr); } diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index 07b1132046..f4e69b95e7 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -36,7 +36,6 @@ #include "core/os/thread_safe.h" #include "core/templates/hash_set.h" #include "core/templates/safe_refcount.h" -#include "core/templates/thread_work_pool.h" #include "scene/main/node.h" class FileAccess; @@ -275,8 +274,6 @@ class EditorFileSystem : public Node { HashSet<String> group_file_cache; - ThreadWorkPool import_threads; - struct ImportThreadData { const ImportFile *reimport_files; int reimport_from; diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index d58dc98f07..a02051c8ee 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -102,7 +102,7 @@ void editor_register_fonts(Ref<Theme> p_theme) { // - macOS doesn't use font hinting. // - Windows uses ClearType, which is in between "Light" and "Normal" hinting. // - Linux has configurable font hinting, but most distributions including Ubuntu default to "Light". -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED font_hinting = TextServer::HINTING_NONE; #else font_hinting = TextServer::HINTING_LIGHT; diff --git a/editor/editor_fonts.h b/editor/editor_fonts.h index e450af00da..c8b60b0198 100644 --- a/editor/editor_fonts.h +++ b/editor/editor_fonts.h @@ -35,4 +35,4 @@ void editor_register_fonts(Ref<Theme> p_theme); -#endif +#endif // EDITOR_FONTS_H diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 1711b23547..387d461461 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2026,8 +2026,8 @@ void EditorInspectorArray::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { Color color = get_theme_color(SNAME("dark_color_1"), SNAME("Editor")); - odd_style->set_bg_color(color.lightened(0.15)); - even_style->set_bg_color(color.darkened(0.15)); + odd_style->set_bg_color(color.darkened(-0.08)); + even_style->set_bg_color(color.darkened(0.08)); for (int i = 0; i < (int)array_elements.size(); i++) { ArrayElement &ae = array_elements[i]; @@ -3558,7 +3558,7 @@ void EditorInspector::_notification(int p_what) { if (refresh_countdown <= 0) { for (const KeyValue<StringName, List<EditorProperty *>> &F : editor_property_map) { for (EditorProperty *E : F.value) { - if (!E->is_cache_valid()) { + if (E && !E->is_cache_valid()) { E->update_property(); E->update_revert_and_pin_status(); E->update_cache(); @@ -3704,20 +3704,25 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li added.insert(pi.name); r_list.insert_before(insert_here, pi); + + List<PropertyInfo>::Element *prop_below = bottom->next(); + while (prop_below) { + if (prop_below->get() == pi) { + List<PropertyInfo>::Element *to_delete = prop_below; + prop_below = prop_below->next(); + r_list.erase(to_delete); + } else { + prop_below = prop_below->next(); + } + } } // Script Variables -> NodeA (insert_here) -> A props... -> bottom insert_here = category; } - // NodeC -> C props... -> NodeB..C.. if (script_variables) { r_list.erase(script_variables); - List<PropertyInfo>::Element *to_delete = bottom->next(); - while (to_delete && !(to_delete->get().usage & PROPERTY_USAGE_CATEGORY)) { - r_list.erase(to_delete); - to_delete = bottom->next(); - } r_list.erase(bottom); } } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 9542f102cb..4ec3513da5 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -602,4 +602,4 @@ public: EditorInspector(); }; -#endif // INSPECTOR_H +#endif // EDITOR_INSPECTOR_H diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 166dcf19c8..8294e2229a 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -75,9 +75,9 @@ #include "editor/dependency_editor.h" #include "editor/editor_about.h" #include "editor/editor_audio_buses.h" +#include "editor/editor_build_profile.h" #include "editor/editor_command_palette.h" #include "editor/editor_data.h" -#include "editor/editor_export.h" #include "editor/editor_feature_profile.h" #include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" @@ -90,6 +90,7 @@ #include "editor/editor_plugin.h" #include "editor/editor_properties.h" #include "editor/editor_property_name_processor.h" +#include "editor/editor_quick_open.h" #include "editor/editor_resource_picker.h" #include "editor/editor_resource_preview.h" #include "editor/editor_run.h" @@ -102,8 +103,11 @@ #include "editor/editor_themes.h" #include "editor/editor_toaster.h" #include "editor/editor_translation_parser.h" -#include "editor/export_template_manager.h" +#include "editor/export/editor_export.h" +#include "editor/export/export_template_manager.h" +#include "editor/export/project_export.h" #include "editor/filesystem_dock.h" +#include "editor/import/audio_stream_import_settings.h" #include "editor/import/dynamic_font_import_settings.h" #include "editor/import/editor_import_collada.h" #include "editor/import/resource_importer_bitmask.h" @@ -131,7 +135,6 @@ #include "editor/plugins/animation_state_machine_editor.h" #include "editor/plugins/animation_tree_editor_plugin.h" #include "editor/plugins/asset_library_editor_plugin.h" -#include "editor/plugins/audio_stream_editor_plugin.h" #include "editor/plugins/audio_stream_randomizer_editor_plugin.h" #include "editor/plugins/bit_map_editor_plugin.h" #include "editor/plugins/bone_map_editor_plugin.h" @@ -172,7 +175,6 @@ #include "editor/plugins/polygon_2d_editor_plugin.h" #include "editor/plugins/polygon_3d_editor_plugin.h" #include "editor/plugins/ray_cast_2d_editor_plugin.h" -#include "editor/plugins/replication_editor_plugin.h" #include "editor/plugins/resource_preloader_editor_plugin.h" #include "editor/plugins/root_motion_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h" @@ -197,9 +199,7 @@ #include "editor/plugins/visual_shader_editor_plugin.h" #include "editor/plugins/voxel_gi_editor_plugin.h" #include "editor/progress_dialog.h" -#include "editor/project_export.h" #include "editor/project_settings_editor.h" -#include "editor/quick_open.h" #include "editor/register_exporters.h" #include "editor/scene_tree_dock.h" @@ -923,6 +923,7 @@ void EditorNode::_fs_changed() { // FIXME: Move this to a cleaner location, it's hacky to do this in _fs_changed. String export_error; + Error err = OK; if (!export_defer.preset.is_empty() && !EditorFileSystem::get_singleton()->is_scanning()) { String preset_name = export_defer.preset; // Ensures export_project does not loop infinitely, because notifications may @@ -940,6 +941,7 @@ void EditorNode::_fs_changed() { if (export_preset.is_null()) { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (da->file_exists("res://export_presets.cfg")) { + err = FAILED; export_error = vformat( "Invalid export preset name: %s.\nThe following presets were detected in this project's `export_presets.cfg`:\n\n", preset_name); @@ -948,17 +950,19 @@ void EditorNode::_fs_changed() { export_error += vformat(" \"%s\"\n", EditorExport::get_singleton()->get_export_preset(i)->get_name()); } } else { + err = FAILED; export_error = "This project doesn't have an `export_presets.cfg` file at its root.\nCreate an export preset from the \"Project > Export\" dialog and try again."; } } else { Ref<EditorExportPlatform> platform = export_preset->get_platform(); const String export_path = export_defer.path.is_empty() ? export_preset->get_export_path() : export_defer.path; if (export_path.is_empty()) { + err = FAILED; export_error = vformat("Export preset \"%s\" doesn't have a default export path, and none was specified.", preset_name); } else if (platform.is_null()) { + err = FAILED; export_error = vformat("Export preset \"%s\" doesn't have a matching platform.", preset_name); } else { - Error err = OK; if (export_defer.pack_only) { // Only export .pck or .zip data pack. if (export_path.ends_with(".zip")) { err = platform->export_zip(export_preset, export_defer.debug, export_path); @@ -979,17 +983,18 @@ void EditorNode::_fs_changed() { if (err != OK) { export_error = vformat("Project export for preset \"%s\" failed.", preset_name); } else if (platform->get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) { - export_error = vformat("Project export for preset \"%s\" completed with errors.", preset_name); + export_error = vformat("Project export for preset \"%s\" completed with warnings.", preset_name); } } } - if (!export_error.is_empty()) { + if (err != OK) { ERR_PRINT(export_error); _exit_editor(EXIT_FAILURE); - } else { - _exit_editor(EXIT_SUCCESS); + } else if (!export_error.is_empty()) { + WARN_PRINT(export_error); } + _exit_editor(EXIT_SUCCESS); } } @@ -1029,7 +1034,7 @@ void EditorNode::_sources_changed(bool p_exist) { // Reload the global shader variables, but this time // loading textures, as they are now properly imported. - RenderingServer::get_singleton()->global_variables_load_settings(true); + RenderingServer::get_singleton()->global_shader_uniforms_load_settings(true); // Start preview thread now that it's safe. if (!singleton->cmdline_export_mode) { @@ -1794,9 +1799,16 @@ void EditorNode::restart_editor() { _exit_editor(EXIT_SUCCESS); List<String> args; + args.push_back("--path"); args.push_back(ProjectSettings::get_singleton()->get_resource_path()); + args.push_back("-e"); + + if (OS::get_singleton()->is_disable_crash_handler()) { + args.push_back("--disable-crash-handler"); + } + if (!to_reopen.is_empty()) { args.push_back(to_reopen); } @@ -2175,6 +2187,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { Object *prev_inspected_object = InspectorDock::get_inspector_singleton()->get_edited_object(); bool disable_folding = bool(EDITOR_GET("interface/inspector/disable_folding")); + bool stay_in_script_editor_on_node_selected = bool(EDITOR_GET("text_editor/behavior/navigation/stay_in_script_editor_on_node_selected")); bool is_resource = current_obj->is_class("Resource"); bool is_node = current_obj->is_class("Node"); @@ -2213,6 +2226,9 @@ void EditorNode::_edit_current(bool p_skip_foreign) { NodeDock::get_singleton()->set_node(current_node); SceneTreeDock::get_singleton()->set_selected(current_node); InspectorDock::get_singleton()->update(current_node); + if (!inspector_only) { + inspector_only = stay_in_script_editor_on_node_selected && ScriptEditor::get_singleton()->is_visible_in_tree(); + } } else { NodeDock::get_singleton()->set_node(nullptr); SceneTreeDock::get_singleton()->set_selected(nullptr); @@ -2805,6 +2821,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } } } break; + case TOOLS_BUILD_PROFILE_MANAGER: { + build_profile_manager->popup_centered_clamped(Size2(700, 800) * EDSCALE, 0.8); + } break; case RUN_USER_DATA_FOLDER: { // Ensure_user_data_dir() to prevent the edge case: "Open User Data Folder" won't work after the project was renamed in ProjectSettingsEditor unless the project is saved. OS::get_singleton()->ensure_user_data_dir(); @@ -3588,6 +3607,13 @@ void EditorNode::set_current_scene(int p_idx) { call_deferred(SNAME("_set_main_scene_state"), state, get_edited_scene()); // Do after everything else is done setting up. } +void EditorNode::setup_color_picker(ColorPicker *picker) { + int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode"); + int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape"); + picker->set_color_mode((ColorPicker::ColorModeType)default_color_mode); + picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape); +} + bool EditorNode::is_scene_open(const String &p_path) { for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { if (editor_data.get_scene_path(i) == p_path) { @@ -5899,6 +5925,8 @@ EditorNode::EditorNode() { RenderingServer::get_singleton()->set_debug_generate_wireframes(true); + AudioServer::get_singleton()->set_enable_tagging_used_audio_streams(true); + // No navigation server by default if in editor. NavigationServer3D::get_singleton()->set_active(false); @@ -6443,6 +6471,9 @@ EditorNode::EditorNode() { scene_import_settings = memnew(SceneImportSettings); gui_base->add_child(scene_import_settings); + audio_stream_import_settings = memnew(AudioStreamImportSettings); + gui_base->add_child(audio_stream_import_settings); + fontdata_import_settings = memnew(DynamicFontImportSettings); gui_base->add_child(fontdata_import_settings); @@ -6451,6 +6482,10 @@ EditorNode::EditorNode() { feature_profile_manager = memnew(EditorFeatureProfileManager); gui_base->add_child(feature_profile_manager); + + build_profile_manager = memnew(EditorBuildProfileManager); + gui_base->add_child(build_profile_manager); + about = memnew(EditorAbout); gui_base->add_child(about); feature_profile_manager->connect("current_feature_profile_changed", callable_mp(this, &EditorNode::_feature_profile_changed)); @@ -6543,6 +6578,10 @@ EditorNode::EditorNode() { p->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE); p->add_item(TTR("Open User Data Folder"), RUN_USER_DATA_FOLDER); + p->add_separator(); + p->add_item(TTR("Customize Engine Build Configuration..."), TOOLS_BUILD_PROFILE_MANAGER); + p->add_separator(); + plugin_config_dialog = memnew(PluginConfigDialog); plugin_config_dialog->connect("plugin_ready", callable_mp(this, &EditorNode::_on_plugin_ready)); gui_base->add_child(plugin_config_dialog); @@ -7079,7 +7118,6 @@ EditorNode::EditorNode() { // This list is alphabetized, and plugins that depend on Node2D are in their own section below. add_editor_plugin(memnew(AnimationTreeEditorPlugin)); add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); - add_editor_plugin(memnew(AudioStreamEditorPlugin)); add_editor_plugin(memnew(AudioStreamRandomizerEditorPlugin)); add_editor_plugin(memnew(BitMapEditorPlugin)); add_editor_plugin(memnew(BoneMapEditorPlugin)); @@ -7103,7 +7141,6 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(Path3DEditorPlugin)); add_editor_plugin(memnew(PhysicalBone3DEditorPlugin)); add_editor_plugin(memnew(Polygon3DEditorPlugin)); - add_editor_plugin(memnew(ReplicationEditorPlugin)); add_editor_plugin(memnew(ResourcePreloaderEditorPlugin)); add_editor_plugin(memnew(ShaderEditorPlugin)); add_editor_plugin(memnew(ShaderFileEditorPlugin)); @@ -7190,6 +7227,7 @@ EditorNode::EditorNode() { vshader_convert.instantiate(); resource_conversion_plugins.push_back(vshader_convert); } + update_spinner_step_msec = OS::get_singleton()->get_ticks_msec(); update_spinner_step_frame = Engine::get_singleton()->get_frames_drawn(); diff --git a/editor/editor_node.h b/editor/editor_node.h index 07d565314d..c521c0fb04 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -32,10 +32,10 @@ #define EDITOR_NODE_H #include "core/templates/safe_refcount.h" -#include "editor/editor_export.h" #include "editor/editor_folding.h" #include "editor/editor_native_shader_source_visualizer.h" #include "editor/editor_run.h" +#include "editor/export/editor_export.h" #include "editor/inspector_dock.h" #include "editor/property_editor.h" @@ -88,6 +88,7 @@ class ProjectExportDialog; class ProjectSettingsEditor; class RunSettingsDialog; class SceneImportSettings; +class AudioStreamImportSettings; class ScriptCreateDialog; class SubViewport; class TabBar; @@ -95,6 +96,7 @@ class TabContainer; class TextureProgressBar; class VSplitContainer; class Window; +class EditorBuildProfileManager; class EditorNode : public Node { GDCLASS(EditorNode, Node); @@ -163,6 +165,7 @@ private: EDIT_REDO, EDIT_RELOAD_SAVED_SCENE, TOOLS_ORPHAN_RESOURCES, + TOOLS_BUILD_PROFILE_MANAGER, TOOLS_CUSTOM, RESOURCE_SAVE, RESOURCE_SAVE_AS, @@ -377,6 +380,7 @@ private: EditorFileDialog *file = nullptr; ExportTemplateManager *export_template_manager = nullptr; EditorFeatureProfileManager *feature_profile_manager = nullptr; + EditorBuildProfileManager *build_profile_manager = nullptr; EditorFileDialog *file_templates = nullptr; EditorFileDialog *file_export_lib = nullptr; EditorFileDialog *file_script = nullptr; @@ -468,6 +472,7 @@ private: DynamicFontImportSettings *fontdata_import_settings = nullptr; SceneImportSettings *scene_import_settings = nullptr; + AudioStreamImportSettings *audio_stream_import_settings = nullptr; String import_reload_fn; @@ -783,6 +788,8 @@ public: void set_current_version(uint64_t p_version); void set_current_scene(int p_idx); + void setup_color_picker(ColorPicker *picker); + void request_instance_scene(const String &p_path); void request_instantiate_scenes(const Vector<String> &p_files); diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp index a5c2fe093c..977af3cfae 100644 --- a/editor/editor_paths.cpp +++ b/editor/editor_paths.cpp @@ -153,8 +153,8 @@ EditorPaths::EditorPaths() { } } - if (!dir->dir_exists("templates")) { - dir->make_dir("templates"); + if (!dir->dir_exists("export_templates")) { + dir->make_dir("export_templates"); } } diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index d9c2a42114..566c22f5a9 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -31,11 +31,11 @@ #include "editor_plugin.h" #include "editor/editor_command_palette.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_resource_preview.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" #include "editor/filesystem_dock.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "editor/plugins/node_3d_editor_plugin.h" diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index c666b4639d..84c63d1021 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -346,4 +346,4 @@ public: } }; -#endif +#endif // EDITOR_PLUGIN_H diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h index 4903a02c4d..7c6d93e6f4 100644 --- a/editor/editor_plugin_settings.h +++ b/editor/editor_plugin_settings.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITORPLUGINSETTINGS_H -#define EDITORPLUGINSETTINGS_H +#ifndef EDITOR_PLUGIN_SETTINGS_H +#define EDITOR_PLUGIN_SETTINGS_H #include "core/object/undo_redo.h" #include "editor/editor_data.h" @@ -65,4 +65,4 @@ public: EditorPluginSettings(); }; -#endif // EDITORPLUGINSETTINGS_H +#endif // EDITOR_PLUGIN_SETTINGS_H diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index aaa518362c..d145a1e820 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2623,6 +2623,186 @@ EditorPropertyQuaternion::EditorPropertyQuaternion() { set_label_reference(spin[0]); //show text and buttons around this } } +///////////////////// VECTOR4 ///////////////////////// + +void EditorPropertyVector4::_set_read_only(bool p_read_only) { + for (int i = 0; i < 4; i++) { + spin[i]->set_read_only(p_read_only); + } +}; + +void EditorPropertyVector4::_value_changed(double val, const String &p_name) { + if (setting) { + return; + } + + Vector4 p; + p.x = spin[0]->get_value(); + p.y = spin[1]->get_value(); + p.z = spin[2]->get_value(); + p.w = spin[3]->get_value(); + emit_changed(get_edited_property(), p, p_name); +} + +void EditorPropertyVector4::update_property() { + Vector4 val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.x); + spin[1]->set_value(val.y); + spin[2]->set_value(val.z); + spin[3]->set_value(val.w); + setting = false; +} + +void EditorPropertyVector4::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + const Color *colors = _get_property_colors(); + for (int i = 0; i < 4; i++) { + spin[i]->add_theme_color_override("label_color", colors[i]); + } + } break; + } +} + +void EditorPropertyVector4::_bind_methods() { +} + +void EditorPropertyVector4::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { + for (int i = 0; i < 4; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(p_step); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + // Vector4 is inherently unitless, however someone may want to use it as + // a generic way to store 4 values, so we'll still respect the suffix. + spin[i]->set_suffix(p_suffix); + } +} + +EditorPropertyVector4::EditorPropertyVector4() { + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + + if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[4] = { "x", "y", "z", "w" }; + for (int i = 0; i < 4; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); + spin[i]->set_label(desc[i]); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector4::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } +} + +///////////////////// VECTOR4I ///////////////////////// + +void EditorPropertyVector4i::_set_read_only(bool p_read_only) { + for (int i = 0; i < 4; i++) { + spin[i]->set_read_only(p_read_only); + } +}; + +void EditorPropertyVector4i::_value_changed(double val, const String &p_name) { + if (setting) { + return; + } + + Vector4i p; + p.x = spin[0]->get_value(); + p.y = spin[1]->get_value(); + p.z = spin[2]->get_value(); + p.w = spin[3]->get_value(); + emit_changed(get_edited_property(), p, p_name); +} + +void EditorPropertyVector4i::update_property() { + Vector4i val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.x); + spin[1]->set_value(val.y); + spin[2]->set_value(val.z); + spin[3]->set_value(val.w); + setting = false; +} + +void EditorPropertyVector4i::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + const Color *colors = _get_property_colors(); + for (int i = 0; i < 4; i++) { + spin[i]->add_theme_color_override("label_color", colors[i]); + } + } break; + } +} + +void EditorPropertyVector4i::_bind_methods() { +} + +void EditorPropertyVector4i::setup(double p_min, double p_max, bool p_no_slider, const String &p_suffix) { + for (int i = 0; i < 4; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + spin[i]->set_suffix(p_suffix); + } +} + +EditorPropertyVector4i::EditorPropertyVector4i() { + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + + if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[4] = { "x", "y", "z", "w" }; + for (int i = 0; i < 4; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); + spin[i]->set_label(desc[i]); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector4i::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } +} ///////////////////// AABB ///////////////////////// @@ -2986,6 +3166,111 @@ EditorPropertyTransform3D::EditorPropertyTransform3D() { set_bottom_editor(g); } +///////////////////// PROJECTION ///////////////////////// + +void EditorPropertyProjection::_set_read_only(bool p_read_only) { + for (int i = 0; i < 12; i++) { + spin[i]->set_read_only(p_read_only); + } +}; + +void EditorPropertyProjection::_value_changed(double val, const String &p_name) { + if (setting) { + return; + } + + Projection p; + p.matrix[0][0] = spin[0]->get_value(); + p.matrix[0][1] = spin[1]->get_value(); + p.matrix[0][2] = spin[2]->get_value(); + p.matrix[0][3] = spin[3]->get_value(); + p.matrix[1][0] = spin[4]->get_value(); + p.matrix[1][1] = spin[5]->get_value(); + p.matrix[1][2] = spin[6]->get_value(); + p.matrix[1][3] = spin[7]->get_value(); + p.matrix[2][0] = spin[8]->get_value(); + p.matrix[2][1] = spin[9]->get_value(); + p.matrix[2][2] = spin[10]->get_value(); + p.matrix[2][3] = spin[11]->get_value(); + p.matrix[3][0] = spin[12]->get_value(); + p.matrix[3][1] = spin[13]->get_value(); + p.matrix[3][2] = spin[14]->get_value(); + p.matrix[3][3] = spin[15]->get_value(); + + emit_changed(get_edited_property(), p, p_name); +} + +void EditorPropertyProjection::update_property() { + update_using_transform(get_edited_object()->get(get_edited_property())); +} + +void EditorPropertyProjection::update_using_transform(Projection p_transform) { + setting = true; + spin[0]->set_value(p_transform.matrix[0][0]); + spin[1]->set_value(p_transform.matrix[0][1]); + spin[2]->set_value(p_transform.matrix[0][2]); + spin[3]->set_value(p_transform.matrix[0][3]); + spin[4]->set_value(p_transform.matrix[1][0]); + spin[5]->set_value(p_transform.matrix[1][1]); + spin[6]->set_value(p_transform.matrix[1][2]); + spin[7]->set_value(p_transform.matrix[1][3]); + spin[8]->set_value(p_transform.matrix[2][0]); + spin[9]->set_value(p_transform.matrix[2][1]); + spin[10]->set_value(p_transform.matrix[2][2]); + spin[11]->set_value(p_transform.matrix[2][3]); + spin[12]->set_value(p_transform.matrix[3][0]); + spin[13]->set_value(p_transform.matrix[3][1]); + spin[14]->set_value(p_transform.matrix[3][2]); + spin[15]->set_value(p_transform.matrix[3][3]); + setting = false; +} + +void EditorPropertyProjection::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + const Color *colors = _get_property_colors(); + for (int i = 0; i < 16; i++) { + spin[i]->add_theme_color_override("label_color", colors[i % 4]); + } + } break; + } +} + +void EditorPropertyProjection::_bind_methods() { +} + +void EditorPropertyProjection::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { + for (int i = 0; i < 16; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(p_step); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + if (i % 4 == 3) { + spin[i]->set_suffix(p_suffix); + } + } +} + +EditorPropertyProjection::EditorPropertyProjection() { + GridContainer *g = memnew(GridContainer); + g->set_columns(4); + add_child(g); + + static const char *desc[16] = { "xx", "xy", "xz", "xw", "yx", "yy", "yz", "yw", "zx", "zy", "zz", "zw", "wx", "wy", "wz", "ww" }; + for (int i = 0; i < 16; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); + g->add_child(spin[i]); + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyProjection::_value_changed), varray(desc[i])); + } + set_bottom_editor(g); +} ////////////// COLOR PICKER ////////////////////// void EditorPropertyColor::_set_read_only(bool p_read_only) { @@ -3007,14 +3292,6 @@ void EditorPropertyColor::_popup_closed() { } } -void EditorPropertyColor::_picker_created() { - // get default color picker mode from editor settings - int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode"); - picker->get_picker()->set_color_mode((ColorPicker::ColorModeType)default_color_mode); - int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape"); - picker->get_picker()->set_picker_shape((ColorPicker::PickerShapeType)picker_shape); -} - void EditorPropertyColor::_picker_opening() { last_color = picker->get_pick_color(); } @@ -3059,7 +3336,7 @@ EditorPropertyColor::EditorPropertyColor() { picker->set_flat(true); picker->connect("color_changed", callable_mp(this, &EditorPropertyColor::_color_changed)); picker->connect("popup_closed", callable_mp(this, &EditorPropertyColor::_popup_closed)); - picker->connect("picker_created", callable_mp(this, &EditorPropertyColor::_picker_created)); + picker->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(picker->get_picker())); picker->get_popup()->connect("about_to_popup", callable_mp(this, &EditorPropertyColor::_picker_opening)); } @@ -3177,6 +3454,11 @@ bool EditorPropertyNodePath::is_drop_valid(const Dictionary &p_drag_data) const Node *dropped_node = get_tree()->get_edited_scene_root()->get_node(nodes[0]); ERR_FAIL_NULL_V(dropped_node, false); + if (valid_types.is_empty()) { + // No type requirements specified so any type is valid. + return true; + } + for (const StringName &E : valid_types) { if (dropped_node->is_class(E)) { return true; @@ -3517,6 +3799,9 @@ void EditorPropertyResource::setup(Object *p_object, const String &p_path, const shader_picker->set_edited_material(Object::cast_to<ShaderMaterial>(p_object)); resource_picker = shader_picker; connect(SNAME("ready"), callable_mp(this, &EditorPropertyResource::_update_preferred_shader)); + } else if (p_base_type == "AudioStream") { + EditorAudioStreamPicker *astream_picker = memnew(EditorAudioStreamPicker); + resource_picker = astream_picker; } else { resource_picker = memnew(EditorResourcePicker); } @@ -3954,6 +4239,20 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ return editor; } break; + case Variant::VECTOR4: { + EditorPropertyVector4 *editor = memnew(EditorPropertyVector4); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.suffix); + return editor; + + } break; + case Variant::VECTOR4I: { + EditorPropertyVector4i *editor = memnew(EditorPropertyVector4i); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); + editor->setup(hint.min, hint.max, hint.hide_slider, hint.suffix); + return editor; + + } break; case Variant::TRANSFORM2D: { EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); @@ -3991,6 +4290,13 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ return editor; } break; + case Variant::PROJECTION: { + EditorPropertyProjection *editor = memnew(EditorPropertyProjection); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.suffix); + return editor; + + } break; // misc types case Variant::COLOR: { diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 7bec2d0013..b3aac6e8ca 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -636,6 +636,40 @@ public: EditorPropertyQuaternion(); }; +class EditorPropertyVector4 : public EditorProperty { + GDCLASS(EditorPropertyVector4, EditorProperty); + EditorSpinSlider *spin[4]; + bool setting = false; + void _value_changed(double p_val, const String &p_name); + +protected: + virtual void _set_read_only(bool p_read_only) override; + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property() override; + void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + EditorPropertyVector4(); +}; + +class EditorPropertyVector4i : public EditorProperty { + GDCLASS(EditorPropertyVector4i, EditorProperty); + EditorSpinSlider *spin[4]; + bool setting = false; + void _value_changed(double p_val, const String &p_name); + +protected: + virtual void _set_read_only(bool p_read_only) override; + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property() override; + void setup(double p_min, double p_max, bool p_no_slider, const String &p_suffix = String()); + EditorPropertyVector4i(); +}; + class EditorPropertyAABB : public EditorProperty { GDCLASS(EditorPropertyAABB, EditorProperty); EditorSpinSlider *spin[6]; @@ -705,6 +739,24 @@ public: EditorPropertyTransform3D(); }; +class EditorPropertyProjection : public EditorProperty { + GDCLASS(EditorPropertyProjection, EditorProperty); + EditorSpinSlider *spin[16]; + bool setting = false; + void _value_changed(double p_val, const String &p_name); + +protected: + virtual void _set_read_only(bool p_read_only) override; + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property() override; + virtual void update_using_transform(Projection p_transform); + void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + EditorPropertyProjection(); +}; + class EditorPropertyColor : public EditorProperty { GDCLASS(EditorPropertyColor, EditorProperty); ColorPickerButton *picker = nullptr; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 0b9004bbc4..e83b070f6b 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -949,6 +949,18 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::VECTOR4: { + EditorPropertyVector4 *editor = memnew(EditorPropertyVector4); + editor->setup(-100000, 100000, default_float_step, true); + prop = editor; + + } break; + case Variant::VECTOR4I: { + EditorPropertyVector4i *editor = memnew(EditorPropertyVector4i); + editor->setup(-100000, 100000, true); + prop = editor; + + } break; case Variant::TRANSFORM2D: { EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); editor->setup(-100000, 100000, default_float_step, true); @@ -985,6 +997,12 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::PROJECTION: { + EditorPropertyProjection *editor = memnew(EditorPropertyProjection); + editor->setup(-100000, 100000, default_float_step, true); + prop = editor; + + } break; // Miscellaneous types. case Variant::COLOR: { diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h index 44623149d0..82aeebe14a 100644 --- a/editor/editor_properties_array_dict.h +++ b/editor/editor_properties_array_dict.h @@ -81,10 +81,7 @@ class EditorPropertyArray : public EditorProperty { GDCLASS(EditorPropertyArray, EditorProperty); PopupMenu *change_type = nullptr; - bool updating = false; - bool dropping = false; - Ref<EditorPropertyArrayObject> object; int page_length = 20; int page_index = 0; int changing_type_index; @@ -106,29 +103,35 @@ class EditorPropertyArray : public EditorProperty { Button *reorder_selected_button = nullptr; void _page_changed(int p_page); - void _length_changed(double p_page); - void _add_element(); - void _edit_pressed(); - void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false); - void _change_type(Object *p_button, int p_index); - void _change_type_menu(int p_index); - - void _object_id_selected(const StringName &p_property, ObjectID p_id); - void _remove_pressed(int p_index); - - void _button_draw(); - bool _is_drop_valid(const Dictionary &p_drag_data) const; - bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; - void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); void _reorder_button_gui_input(const Ref<InputEvent> &p_event); void _reorder_button_down(int p_index); void _reorder_button_up(); protected: + Ref<EditorPropertyArrayObject> object; + + bool updating = false; + bool dropping = false; + static void _bind_methods(); void _notification(int p_what); + virtual void _add_element(); + virtual void _length_changed(double p_page); + virtual void _edit_pressed(); + virtual void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false); + virtual void _change_type(Object *p_button, int p_index); + virtual void _change_type_menu(int p_index); + + virtual void _object_id_selected(const StringName &p_property, ObjectID p_id); + virtual void _remove_pressed(int p_index); + + virtual void _button_draw(); + virtual bool _is_drop_valid(const Dictionary &p_drag_data) const; + virtual bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + virtual void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + public: void setup(Variant::Type p_array_type, const String &p_hint_string = ""); virtual void update_property() override; diff --git a/editor/quick_open.cpp b/editor/editor_quick_open.cpp index 4f7f9fc78c..539cb7cd8a 100644 --- a/editor/quick_open.cpp +++ b/editor/editor_quick_open.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* quick_open.cpp */ +/* editor_quick_open.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "quick_open.h" +#include "editor_quick_open.h" #include "core/os/keyboard.h" diff --git a/editor/quick_open.h b/editor/editor_quick_open.h index 843ef47711..e41a8c7e75 100644 --- a/editor/quick_open.h +++ b/editor/editor_quick_open.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* quick_open.h */ +/* editor_quick_open.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 40e16bf717..e0903ea5ce 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -30,14 +30,15 @@ #include "editor_resource_picker.h" +#include "editor/audio_stream_preview.h" #include "editor/editor_file_dialog.h" #include "editor/editor_node.h" +#include "editor/editor_quick_open.h" #include "editor/editor_resource_preview.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" #include "editor/plugins/script_editor_plugin.h" -#include "editor/quick_open.h" #include "editor/scene_tree_dock.h" HashMap<StringName, List<StringName>> EditorResourcePicker::allowed_types_cache; @@ -47,32 +48,37 @@ void EditorResourcePicker::clear_caches() { } void EditorResourcePicker::_update_resource() { - preview_rect->set_texture(Ref<Texture2D>()); - assign_button->set_custom_minimum_size(Size2(1, 1)); + String resource_path; + if (edited_resource.is_valid() && edited_resource->get_path().is_resource_file()) { + resource_path = edited_resource->get_path() + "\n"; + } - if (edited_resource == Ref<Resource>()) { - assign_button->set_icon(Ref<Texture2D>()); - assign_button->set_text(TTR("[empty]")); - assign_button->set_tooltip(""); - } else { - assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object")); + if (preview_rect) { + preview_rect->set_texture(Ref<Texture2D>()); + + assign_button->set_custom_minimum_size(assign_button_min_size); - if (!edited_resource->get_name().is_empty()) { - assign_button->set_text(edited_resource->get_name()); - } else if (edited_resource->get_path().is_resource_file()) { - assign_button->set_text(edited_resource->get_path().get_file()); + if (edited_resource == Ref<Resource>()) { + assign_button->set_icon(Ref<Texture2D>()); + assign_button->set_text(TTR("[empty]")); + assign_button->set_tooltip(""); } else { - assign_button->set_text(edited_resource->get_class()); - } + assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object")); - String resource_path; - if (edited_resource->get_path().is_resource_file()) { - resource_path = edited_resource->get_path() + "\n"; + if (!edited_resource->get_name().is_empty()) { + assign_button->set_text(edited_resource->get_name()); + } else if (edited_resource->get_path().is_resource_file()) { + assign_button->set_text(edited_resource->get_path().get_file()); + } else { + assign_button->set_text(edited_resource->get_class()); + } + assign_button->set_tooltip(resource_path + TTR("Type:") + " " + edited_resource->get_class()); + + // Preview will override the above, so called at the end. + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(edited_resource, this, "_update_resource_preview", edited_resource->get_instance_id()); } + } else if (edited_resource.is_valid()) { assign_button->set_tooltip(resource_path + TTR("Type:") + " " + edited_resource->get_class()); - - // Preview will override the above, so called at the end. - EditorResourcePreview::get_singleton()->queue_edited_resource_preview(edited_resource, this, "_update_resource_preview", edited_resource->get_instance_id()); } } @@ -81,28 +87,30 @@ void EditorResourcePicker::_update_resource_preview(const String &p_path, const return; } - Ref<Script> script = edited_resource; - if (script.is_valid()) { - assign_button->set_text(script->get_path().get_file()); - return; - } + if (preview_rect) { + Ref<Script> script = edited_resource; + if (script.is_valid()) { + assign_button->set_text(script->get_path().get_file()); + return; + } - if (p_preview.is_valid()) { - preview_rect->set_offset(SIDE_LEFT, assign_button->get_icon()->get_width() + assign_button->get_theme_stylebox(SNAME("normal"))->get_default_margin(SIDE_LEFT) + get_theme_constant(SNAME("h_separation"), SNAME("Button"))); + if (p_preview.is_valid()) { + preview_rect->set_offset(SIDE_LEFT, assign_button->get_icon()->get_width() + assign_button->get_theme_stylebox(SNAME("normal"))->get_default_margin(SIDE_LEFT) + get_theme_constant(SNAME("h_separation"), SNAME("Button"))); - // Resource-specific stretching. - if (Ref<GradientTexture1D>(edited_resource).is_valid() || Ref<Gradient>(edited_resource).is_valid()) { - preview_rect->set_stretch_mode(TextureRect::STRETCH_SCALE); - assign_button->set_custom_minimum_size(Size2(1, 1)); - } else { - preview_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); - int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); - thumbnail_size *= EDSCALE; - assign_button->set_custom_minimum_size(Size2(1, thumbnail_size)); - } + // Resource-specific stretching. + if (Ref<GradientTexture1D>(edited_resource).is_valid() || Ref<Gradient>(edited_resource).is_valid()) { + preview_rect->set_stretch_mode(TextureRect::STRETCH_SCALE); + assign_button->set_custom_minimum_size(assign_button_min_size); + } else { + preview_rect->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED); + int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); + thumbnail_size *= EDSCALE; + assign_button->set_custom_minimum_size(Size2(MIN(1, assign_button_min_size.x), MIN(thumbnail_size, assign_button_min_size.y))); + } - preview_rect->set_texture(p_preview); - assign_button->set_text(""); + preview_rect->set_texture(p_preview); + assign_button->set_text(""); + } } } @@ -866,7 +874,7 @@ void EditorResourcePicker::_ensure_resource_menu() { edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); } -EditorResourcePicker::EditorResourcePicker() { +EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) { assign_button = memnew(Button); assign_button->set_flat(true); assign_button->set_h_size_flags(SIZE_EXPAND_FILL); @@ -877,13 +885,15 @@ EditorResourcePicker::EditorResourcePicker() { assign_button->connect("draw", callable_mp(this, &EditorResourcePicker::_button_draw)); assign_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); - preview_rect = memnew(TextureRect); - preview_rect->set_ignore_texture_size(true); - preview_rect->set_anchors_and_offsets_preset(PRESET_FULL_RECT); - preview_rect->set_offset(SIDE_TOP, 1); - preview_rect->set_offset(SIDE_BOTTOM, -1); - preview_rect->set_offset(SIDE_RIGHT, -1); - assign_button->add_child(preview_rect); + if (!p_hide_assign_button_controls) { + preview_rect = memnew(TextureRect); + preview_rect->set_ignore_texture_size(true); + preview_rect->set_anchors_and_offsets_preset(PRESET_FULL_RECT); + preview_rect->set_offset(SIDE_TOP, 1); + preview_rect->set_offset(SIDE_BOTTOM, -1); + preview_rect->set_offset(SIDE_RIGHT, -1); + assign_button->add_child(preview_rect); + } edit_button = memnew(Button); edit_button->set_flat(true); @@ -993,3 +1003,176 @@ void EditorShaderPicker::set_preferred_mode(int p_mode) { EditorShaderPicker::EditorShaderPicker() { } + +////////////// + +void EditorAudioStreamPicker::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: + case NOTIFICATION_THEME_CHANGED: { + _update_resource(); + } break; + case NOTIFICATION_INTERNAL_PROCESS: { + Ref<AudioStream> audio_stream = get_edited_resource(); + if (audio_stream.is_valid()) { + if (audio_stream->get_length() > 0) { + Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(audio_stream); + if (preview.is_valid()) { + if (preview->get_version() != last_preview_version) { + stream_preview_rect->update(); + last_preview_version = preview->get_version(); + } + } + } + + uint64_t tagged_frame = audio_stream->get_tagged_frame(); + uint64_t diff_frames = AudioServer::get_singleton()->get_mixed_frames() - tagged_frame; + uint64_t diff_msec = diff_frames * 1000 / AudioServer::get_singleton()->get_mix_rate(); + + if (diff_msec < 300) { + uint32_t count = audio_stream->get_tagged_frame_count(); + + bool differ = false; + + if (count != tagged_frame_offset_count) { + differ = true; + } + float offsets[MAX_TAGGED_FRAMES]; + + for (uint32_t i = 0; i < MIN(count, uint32_t(MAX_TAGGED_FRAMES)); i++) { + offsets[i] = audio_stream->get_tagged_frame_offset(i); + if (offsets[i] != tagged_frame_offsets[i]) { + differ = true; + } + } + + if (differ) { + tagged_frame_offset_count = count; + for (uint32_t i = 0; i < count; i++) { + tagged_frame_offsets[i] = offsets[i]; + } + } + + stream_preview_rect->update(); + } else { + if (tagged_frame_offset_count != 0) { + stream_preview_rect->update(); + } + tagged_frame_offset_count = 0; + } + } + } break; + } +} + +void EditorAudioStreamPicker::_update_resource() { + EditorResourcePicker::_update_resource(); + + Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); + int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); + Ref<AudioStream> audio_stream = get_edited_resource(); + if (audio_stream.is_valid() && audio_stream->get_length() > 0.0) { + set_assign_button_min_size(Size2(1, font->get_height(font_size) * 3)); + } else { + set_assign_button_min_size(Size2(1, font->get_height(font_size) * 1.5)); + } + + stream_preview_rect->update(); +} + +void EditorAudioStreamPicker::_preview_draw() { + Ref<AudioStream> audio_stream = get_edited_resource(); + if (!audio_stream.is_valid()) { + get_assign_button()->set_text(TTR("[empty]")); + return; + } + + int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); + + get_assign_button()->set_text(""); + + Size2i size = stream_preview_rect->get_size(); + Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); + + Rect2 rect(Point2(), size); + + if (audio_stream->get_length() > 0) { + rect.size.height *= 0.5; + + stream_preview_rect->draw_rect(rect, Color(0, 0, 0, 1)); + + Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(audio_stream); + float preview_len = preview->get_length(); + + Vector<Vector2> lines; + lines.resize(size.width * 2); + + for (int i = 0; i < size.width; i++) { + float ofs = i * preview_len / size.width; + float ofs_n = (i + 1) * preview_len / size.width; + float max = preview->get_max(ofs, ofs_n) * 0.5 + 0.5; + float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5; + + int idx = i; + lines.write[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y); + lines.write[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y); + } + + Vector<Color> color; + color.push_back(get_theme_color(SNAME("contrast_color_2"), SNAME("Editor"))); + + RS::get_singleton()->canvas_item_add_multiline(stream_preview_rect->get_canvas_item(), lines, color); + + if (tagged_frame_offset_count) { + Color accent = get_theme_color(SNAME("accent_color"), SNAME("Editor")); + + for (uint32_t i = 0; i < tagged_frame_offset_count; i++) { + int x = CLAMP(tagged_frame_offsets[i] * size.width / preview_len, 0, size.width); + if (x == 0) { + continue; // Because some may always return 0, ignore offset 0. + } + stream_preview_rect->draw_rect(Rect2i(x, 0, 2, rect.size.height), accent); + } + } + rect.position.y += rect.size.height; + } + + Ref<Texture2D> icon; + Color icon_modulate(1, 1, 1, 1); + + if (tagged_frame_offset_count > 0) { + icon = get_theme_icon(SNAME("Play"), SNAME("EditorIcons")); + if ((OS::get_singleton()->get_ticks_msec() % 500) > 250) { + icon_modulate = Color(1, 0.5, 0.5, 1); // get_theme_color(SNAME("accent_color"), SNAME("Editor")); + } + } else { + icon = EditorNode::get_singleton()->get_object_icon(audio_stream.operator->(), "Object"); + } + String text; + if (!audio_stream->get_name().is_empty()) { + text = audio_stream->get_name(); + } else if (audio_stream->get_path().is_resource_file()) { + text = audio_stream->get_path().get_file(); + } else { + text = audio_stream->get_class().replace_first("AudioStream", ""); + } + + stream_preview_rect->draw_texture(icon, Point2i(EDSCALE * 2, rect.position.y + (rect.size.height - icon->get_height()) / 2), icon_modulate); + stream_preview_rect->draw_string(font, Point2i(EDSCALE * 2 + icon->get_width(), rect.position.y + font->get_ascent(font_size) + (rect.size.height - font->get_height(font_size)) / 2), text, HORIZONTAL_ALIGNMENT_CENTER, size.width - 4 * EDSCALE - icon->get_width()); +} + +EditorAudioStreamPicker::EditorAudioStreamPicker() : + EditorResourcePicker(true) { + stream_preview_rect = memnew(Control); + + stream_preview_rect->set_anchors_and_offsets_preset(PRESET_FULL_RECT); + stream_preview_rect->set_offset(SIDE_TOP, 1); + stream_preview_rect->set_offset(SIDE_BOTTOM, -1); + stream_preview_rect->set_offset(SIDE_RIGHT, -1); + stream_preview_rect->set_mouse_filter(MOUSE_FILTER_IGNORE); + stream_preview_rect->connect("draw", callable_mp(this, &EditorAudioStreamPicker::_preview_draw)); + + get_assign_button()->add_child(stream_preview_rect); + get_assign_button()->move_child(stream_preview_rect, 0); + set_process_internal(true); +} diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index 8e26e1f4c0..d36e742bcd 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -58,6 +58,8 @@ class EditorResourcePicker : public HBoxContainer { EditorFileDialog *file_dialog = nullptr; EditorQuickOpen *quick_open = nullptr; + Size2i assign_button_min_size = Size2i(1, 1); + enum MenuOption { OBJ_MENU_LOAD, OBJ_MENU_QUICKLOAD, @@ -75,7 +77,6 @@ class EditorResourcePicker : public HBoxContainer { PopupMenu *edit_menu = nullptr; - void _update_resource(); void _update_resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj); void _resource_selected(); @@ -100,9 +101,17 @@ class EditorResourcePicker : public HBoxContainer { void _ensure_resource_menu(); protected: + virtual void _update_resource(); + + Button *get_assign_button() { return assign_button; } static void _bind_methods(); void _notification(int p_what); + void set_assign_button_min_size(const Size2i &p_size) { + assign_button_min_size = p_size; + assign_button->set_custom_minimum_size(assign_button_min_size); + } + GDVIRTUAL1(_set_create_options, Object *) GDVIRTUAL1R(bool, _handle_menu_selected, int) @@ -126,7 +135,7 @@ public: virtual void set_create_options(Object *p_menu_node); virtual bool handle_menu_selected(int p_which); - EditorResourcePicker(); + EditorResourcePicker(bool p_hide_assign_button_controls = false); }; class EditorScriptPicker : public EditorResourcePicker { @@ -173,4 +182,26 @@ public: EditorShaderPicker(); }; +class EditorAudioStreamPicker : public EditorResourcePicker { + GDCLASS(EditorAudioStreamPicker, EditorResourcePicker); + + uint64_t last_preview_version = 0; + Control *stream_preview_rect = nullptr; + + enum { + MAX_TAGGED_FRAMES = 8 + }; + float tagged_frame_offsets[MAX_TAGGED_FRAMES]; + uint32_t tagged_frame_offset_count = 0; + + void _preview_draw(); + virtual void _update_resource() override; + +protected: + void _notification(int p_what); + +public: + EditorAudioStreamPicker(); +}; + #endif // EDITOR_RESOURCE_PICKER_H diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index 820e22bdc8..0413477d88 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITORRESOURCEPREVIEW_H -#define EDITORRESOURCEPREVIEW_H +#ifndef EDITOR_RESOURCE_PREVIEW_H +#define EDITOR_RESOURCE_PREVIEW_H #include "core/os/semaphore.h" #include "core/os/thread.h" @@ -124,4 +124,4 @@ public: ~EditorResourcePreview(); }; -#endif // EDITORRESOURCEPREVIEW_H +#endif // EDITOR_RESOURCE_PREVIEW_H diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index ba49c6dc5f..6ce8625daa 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -55,7 +55,7 @@ Error EditorRun::run(const String &p_scene, const String &p_write_movie) { args.push_back("--remote-debug"); args.push_back(EditorDebuggerNode::get_singleton()->get_server_uri()); - args.push_back("--allow_focus_steal_pid"); + args.push_back("--editor-pid"); args.push_back(itos(OS::get_singleton()->get_process_id())); bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false); diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 854885c707..efd6c67d7a 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -30,9 +30,9 @@ #include "editor_run_native.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/export/editor_export_platform.h" void EditorRunNative::_notification(int p_what) { switch (p_what) { diff --git a/editor/editor_scale.h b/editor/editor_scale.h index 918fde15fb..02e9b997f6 100644 --- a/editor/editor_scale.h +++ b/editor/editor_scale.h @@ -35,4 +35,5 @@ void editor_set_scale(float p_scale); float editor_get_scale(); #define EDSCALE (editor_get_scale()) + #endif // EDITOR_SCALE_H diff --git a/editor/editor_sectioned_inspector.h b/editor/editor_sectioned_inspector.h index babd11eb69..758efae31e 100644 --- a/editor/editor_sectioned_inspector.h +++ b/editor/editor_sectioned_inspector.h @@ -76,4 +76,5 @@ public: SectionedInspector(); ~SectionedInspector(); }; + #endif // EDITOR_SECTIONED_INSPECTOR_H diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index fa8643af86..c73caa78f3 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -414,7 +414,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("interface/editor/code_font_custom_opentype_features", ""); _initial_set("interface/editor/code_font_custom_variations", ""); _initial_set("interface/editor/font_antialiased", true); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_hinting", 0, "Auto (None),None,Light,Normal") #else EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/font_hinting", 0, "Auto (Light),None,Light,Normal") @@ -544,6 +544,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("text_editor/behavior/navigation/smooth_scrolling", true); EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "text_editor/behavior/navigation/v_scroll_speed", 80, "1,10000,1") _initial_set("text_editor/behavior/navigation/drag_and_drop_selection", true); + _initial_set("text_editor/behavior/navigation/stay_in_script_editor_on_node_selected", true); // Behavior: Indent EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "text_editor/behavior/indent/type", 0, "Tabs,Spaces") @@ -1105,8 +1106,8 @@ void EditorSettings::add_property_hint(const PropertyInfo &p_hint) { // Editor data and config directories // EditorPaths::create() is responsible for the creation of these directories. -String EditorSettings::get_templates_dir() const { - return EditorPaths::get_singleton()->get_data_dir().plus_file("templates"); +String EditorSettings::get_export_templates_dir() const { + return EditorPaths::get_singleton()->get_data_dir().plus_file("export_templates"); } String EditorSettings::get_project_settings_dir() const { @@ -1370,7 +1371,7 @@ String EditorSettings::get_editor_layouts_config() const { } float EditorSettings::get_auto_display_scale() const { -#if defined(OSX_ENABLED) || defined(ANDROID_ENABLED) +#if defined(MACOS_ENABLED) || defined(ANDROID_ENABLED) return DisplayServer::get_singleton()->screen_get_max_scale(); #else const int screen = DisplayServer::get_singleton()->window_get_current_screen(); @@ -1489,7 +1490,7 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c for (int i = 0; i < p_keycodes.size(); i++) { Key keycode = (Key)p_keycodes[i]; -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS if (keycode == Key::KEY_DELETE) { keycode = KeyModifierMask::CMD | Key::BACKSPACE; @@ -1519,7 +1520,7 @@ Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, cons for (int i = 0; i < p_keycodes.size(); i++) { Key keycode = (Key)p_keycodes[i]; -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED // Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS if (keycode == Key::KEY_DELETE) { keycode = KeyModifierMask::CMD | Key::BACKSPACE; diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 43f90f9258..56c73685bb 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -151,7 +151,7 @@ public: Ref<Resource> get_resource_clipboard() const { return clipboard; } String get_data_dir() const; - String get_templates_dir() const; + String get_export_templates_dir() const; String get_project_settings_dir() const; String get_text_editor_themes_dir() const; String get_script_templates_dir() const; diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 5c0ccd11f0..20e9d7a3df 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -37,7 +37,7 @@ String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const { if (grabber->is_visible()) { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED Key key = Key::META; #else Key key = Key::CTRL; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 13109478e4..5d60baf202 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -277,6 +277,14 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = exceptions.insert("StatusWarning"); exceptions.insert("OverbrightIndicator"); exceptions.insert("GuiMiniCheckerboard"); + + // Prevents Code Editor icons from changing + exceptions.insert("GuiTab"); + exceptions.insert("GuiSpace"); + exceptions.insert("CodeFoldedRightArrow"); + exceptions.insert("CodeFoldDownArrow"); + exceptions.insert("TextEditorPlay"); + exceptions.insert("Breakpoint"); } // These ones should be converted even if we are using a dark theme. @@ -1659,7 +1667,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const float mono_value = mono_color.r; const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.07); const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.14); - const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.7); + const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.27); // editor main color const Color main_color = dark_theme ? Color(0.34, 0.7, 1.0) : Color(0.02, 0.5, 1.0); @@ -1749,17 +1757,21 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Now theme is loaded, apply it to CodeEdit. theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), SNAME("EditorFonts"))); theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts"))); + Ref<StyleBoxFlat> code_edit_stylebox = make_flat_stylebox(EDITOR_GET("text_editor/theme/highlighting/background_color"), widget_default_margin.x, widget_default_margin.y, widget_default_margin.x, widget_default_margin.y, corner_radius); theme->set_stylebox("normal", "CodeEdit", code_edit_stylebox); theme->set_stylebox("read_only", "CodeEdit", code_edit_stylebox); theme->set_stylebox("focus", "CodeEdit", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); + theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); - theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); - theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); - theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); + theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("CodeFoldedRightArrow"), SNAME("EditorIcons"))); + theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("CodeFoldDownArrow"), SNAME("EditorIcons"))); + theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("TextEditorPlay"), SNAME("EditorIcons"))); theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons"))); + theme->set_constant("line_spacing", "CodeEdit", EDITOR_GET("text_editor/appearance/whitespace/line_spacing")); + theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0)); theme->set_color("completion_background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_background_color")); theme->set_color("completion_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_selected_color")); diff --git a/editor/editor_themes.h b/editor/editor_themes.h index 642558d774..95184b9d4a 100644 --- a/editor/editor_themes.h +++ b/editor/editor_themes.h @@ -40,4 +40,4 @@ Ref<Theme> create_custom_theme(Ref<Theme> p_theme = nullptr); Ref<ImageTexture> create_unscaled_default_project_icon(); -#endif +#endif // EDITOR_THEMES_H diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h index 487625e84c..6a6fca7eba 100644 --- a/editor/editor_vcs_interface.h +++ b/editor/editor_vcs_interface.h @@ -85,4 +85,4 @@ public: virtual ~EditorVCSInterface(); }; -#endif // !EDITOR_VCS_INTERFACE_H +#endif // EDITOR_VCS_INTERFACE_H diff --git a/editor/export/SCsub b/editor/export/SCsub new file mode 100644 index 0000000000..359d04e5df --- /dev/null +++ b/editor/export/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.editor_sources, "*.cpp") diff --git a/editor/export/editor_export.cpp b/editor/export/editor_export.cpp new file mode 100644 index 0000000000..31f408eedb --- /dev/null +++ b/editor/export/editor_export.cpp @@ -0,0 +1,355 @@ +/*************************************************************************/ +/* editor_export.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "editor_export.h" + +#include "core/config/project_settings.h" +#include "core/io/config_file.h" + +EditorExport *EditorExport::singleton = nullptr; + +void EditorExport::_save() { + Ref<ConfigFile> config; + config.instantiate(); + for (int i = 0; i < export_presets.size(); i++) { + Ref<EditorExportPreset> preset = export_presets[i]; + String section = "preset." + itos(i); + + config->set_value(section, "name", preset->get_name()); + config->set_value(section, "platform", preset->get_platform()->get_name()); + config->set_value(section, "runnable", preset->is_runnable()); + config->set_value(section, "custom_features", preset->get_custom_features()); + + bool save_files = false; + switch (preset->get_export_filter()) { + case EditorExportPreset::EXPORT_ALL_RESOURCES: { + config->set_value(section, "export_filter", "all_resources"); + } break; + case EditorExportPreset::EXPORT_SELECTED_SCENES: { + config->set_value(section, "export_filter", "scenes"); + save_files = true; + } break; + case EditorExportPreset::EXPORT_SELECTED_RESOURCES: { + config->set_value(section, "export_filter", "resources"); + save_files = true; + } break; + case EditorExportPreset::EXCLUDE_SELECTED_RESOURCES: { + config->set_value(section, "export_filter", "exclude"); + save_files = true; + } break; + } + + if (save_files) { + Vector<String> export_files = preset->get_files_to_export(); + config->set_value(section, "export_files", export_files); + } + config->set_value(section, "include_filter", preset->get_include_filter()); + config->set_value(section, "exclude_filter", preset->get_exclude_filter()); + config->set_value(section, "export_path", preset->get_export_path()); + config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter()); + config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter()); + config->set_value(section, "encrypt_pck", preset->get_enc_pck()); + config->set_value(section, "encrypt_directory", preset->get_enc_directory()); + config->set_value(section, "script_export_mode", preset->get_script_export_mode()); + config->set_value(section, "script_encryption_key", preset->get_script_encryption_key()); + + String option_section = "preset." + itos(i) + ".options"; + + for (const PropertyInfo &E : preset->get_properties()) { + config->set_value(option_section, E.name, preset->get(E.name)); + } + } + + config->save("res://export_presets.cfg"); +} + +void EditorExport::save_presets() { + if (block_save) { + return; + } + save_timer->start(); +} + +void EditorExport::_bind_methods() { + ADD_SIGNAL(MethodInfo("export_presets_updated")); +} + +void EditorExport::add_export_platform(const Ref<EditorExportPlatform> &p_platform) { + export_platforms.push_back(p_platform); +} + +int EditorExport::get_export_platform_count() { + return export_platforms.size(); +} + +Ref<EditorExportPlatform> EditorExport::get_export_platform(int p_idx) { + ERR_FAIL_INDEX_V(p_idx, export_platforms.size(), Ref<EditorExportPlatform>()); + + return export_platforms[p_idx]; +} + +void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos) { + if (p_at_pos < 0) { + export_presets.push_back(p_preset); + } else { + export_presets.insert(p_at_pos, p_preset); + } +} + +String EditorExportPlatform::test_etc2() const { + const bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2"); + + if (!etc2_supported) { + return TTR("Target platform requires 'ETC2' texture compression. Enable 'Import Etc 2' in Project Settings."); + } + + return String(); +} + +int EditorExport::get_export_preset_count() const { + return export_presets.size(); +} + +Ref<EditorExportPreset> EditorExport::get_export_preset(int p_idx) { + ERR_FAIL_INDEX_V(p_idx, export_presets.size(), Ref<EditorExportPreset>()); + return export_presets[p_idx]; +} + +void EditorExport::remove_export_preset(int p_idx) { + export_presets.remove_at(p_idx); + save_presets(); +} + +void EditorExport::add_export_plugin(const Ref<EditorExportPlugin> &p_plugin) { + if (!export_plugins.has(p_plugin)) { + export_plugins.push_back(p_plugin); + } +} + +void EditorExport::remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin) { + export_plugins.erase(p_plugin); +} + +Vector<Ref<EditorExportPlugin>> EditorExport::get_export_plugins() { + return export_plugins; +} + +void EditorExport::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + load_config(); + } break; + + case NOTIFICATION_PROCESS: { + update_export_presets(); + } break; + } +} + +void EditorExport::load_config() { + Ref<ConfigFile> config; + config.instantiate(); + Error err = config->load("res://export_presets.cfg"); + if (err != OK) { + return; + } + + block_save = true; + + int index = 0; + while (true) { + String section = "preset." + itos(index); + if (!config->has_section(section)) { + break; + } + + String platform = config->get_value(section, "platform"); + + Ref<EditorExportPreset> preset; + + for (int i = 0; i < export_platforms.size(); i++) { + if (export_platforms[i]->get_name() == platform) { + preset = export_platforms.write[i]->create_preset(); + break; + } + } + + if (!preset.is_valid()) { + index++; + ERR_CONTINUE(!preset.is_valid()); + } + + preset->set_name(config->get_value(section, "name")); + preset->set_runnable(config->get_value(section, "runnable")); + + if (config->has_section_key(section, "custom_features")) { + preset->set_custom_features(config->get_value(section, "custom_features")); + } + + String export_filter = config->get_value(section, "export_filter"); + + bool get_files = false; + + if (export_filter == "all_resources") { + preset->set_export_filter(EditorExportPreset::EXPORT_ALL_RESOURCES); + } else if (export_filter == "scenes") { + preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_SCENES); + get_files = true; + } else if (export_filter == "resources") { + preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_RESOURCES); + get_files = true; + } else if (export_filter == "exclude") { + preset->set_export_filter(EditorExportPreset::EXCLUDE_SELECTED_RESOURCES); + get_files = true; + } + + if (get_files) { + Vector<String> files = config->get_value(section, "export_files"); + + for (int i = 0; i < files.size(); i++) { + if (!FileAccess::exists(files[i])) { + preset->remove_export_file(files[i]); + } else { + preset->add_export_file(files[i]); + } + } + } + + preset->set_include_filter(config->get_value(section, "include_filter")); + preset->set_exclude_filter(config->get_value(section, "exclude_filter")); + preset->set_export_path(config->get_value(section, "export_path", "")); + + if (config->has_section_key(section, "encrypt_pck")) { + preset->set_enc_pck(config->get_value(section, "encrypt_pck")); + } + if (config->has_section_key(section, "encrypt_directory")) { + preset->set_enc_directory(config->get_value(section, "encrypt_directory")); + } + if (config->has_section_key(section, "encryption_include_filters")) { + preset->set_enc_in_filter(config->get_value(section, "encryption_include_filters")); + } + if (config->has_section_key(section, "encryption_exclude_filters")) { + preset->set_enc_ex_filter(config->get_value(section, "encryption_exclude_filters")); + } + if (config->has_section_key(section, "script_export_mode")) { + preset->set_script_export_mode(config->get_value(section, "script_export_mode")); + } + if (config->has_section_key(section, "script_encryption_key")) { + preset->set_script_encryption_key(config->get_value(section, "script_encryption_key")); + } + + String option_section = "preset." + itos(index) + ".options"; + + List<String> options; + + config->get_section_keys(option_section, &options); + + for (const String &E : options) { + Variant value = config->get_value(option_section, E); + + preset->set(E, value); + } + + add_export_preset(preset); + index++; + } + + block_save = false; +} + +void EditorExport::update_export_presets() { + HashMap<StringName, List<EditorExportPlatform::ExportOption>> platform_options; + + for (int i = 0; i < export_platforms.size(); i++) { + Ref<EditorExportPlatform> platform = export_platforms[i]; + + if (platform->should_update_export_options()) { + List<EditorExportPlatform::ExportOption> options; + platform->get_export_options(&options); + + platform_options[platform->get_name()] = options; + } + } + + bool export_presets_updated = false; + for (int i = 0; i < export_presets.size(); i++) { + Ref<EditorExportPreset> preset = export_presets[i]; + if (platform_options.has(preset->get_platform()->get_name())) { + export_presets_updated = true; + + List<EditorExportPlatform::ExportOption> options = platform_options[preset->get_platform()->get_name()]; + + // Copy the previous preset values + HashMap<StringName, Variant> previous_values = preset->values; + + // Clear the preset properties and values prior to reloading + preset->properties.clear(); + preset->values.clear(); + + for (const EditorExportPlatform::ExportOption &E : options) { + preset->properties.push_back(E.option); + + StringName option_name = E.option.name; + preset->values[option_name] = previous_values.has(option_name) ? previous_values[option_name] : E.default_value; + } + } + } + + if (export_presets_updated) { + emit_signal(_export_presets_updated); + } +} + +bool EditorExport::poll_export_platforms() { + bool changed = false; + for (int i = 0; i < export_platforms.size(); i++) { + if (export_platforms.write[i]->poll_export()) { + changed = true; + } + } + + return changed; +} + +EditorExport::EditorExport() { + save_timer = memnew(Timer); + add_child(save_timer); + save_timer->set_wait_time(0.8); + save_timer->set_one_shot(true); + save_timer->connect("timeout", callable_mp(this, &EditorExport::_save)); + + _export_presets_updated = "export_presets_updated"; + + singleton = this; + set_process(true); +} + +EditorExport::~EditorExport() { +} diff --git a/editor/export/editor_export.h b/editor/export/editor_export.h new file mode 100644 index 0000000000..13c3c34cea --- /dev/null +++ b/editor/export/editor_export.h @@ -0,0 +1,84 @@ +/*************************************************************************/ +/* editor_export.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 EDITOR_EXPORT_H +#define EDITOR_EXPORT_H + +#include "editor_export_platform.h" +#include "editor_export_plugin.h" + +class EditorExport : public Node { + GDCLASS(EditorExport, Node); + + Vector<Ref<EditorExportPlatform>> export_platforms; + Vector<Ref<EditorExportPreset>> export_presets; + Vector<Ref<EditorExportPlugin>> export_plugins; + + StringName _export_presets_updated; + + Timer *save_timer = nullptr; + bool block_save = false; + + static EditorExport *singleton; + + void _save(); + +protected: + friend class EditorExportPreset; + void save_presets(); + + void _notification(int p_what); + static void _bind_methods(); + +public: + static EditorExport *get_singleton() { return singleton; } + + void add_export_platform(const Ref<EditorExportPlatform> &p_platform); + int get_export_platform_count(); + Ref<EditorExportPlatform> get_export_platform(int p_idx); + + void add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos = -1); + int get_export_preset_count() const; + Ref<EditorExportPreset> get_export_preset(int p_idx); + void remove_export_preset(int p_idx); + + void add_export_plugin(const Ref<EditorExportPlugin> &p_plugin); + void remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin); + Vector<Ref<EditorExportPlugin>> get_export_plugins(); + + void load_config(); + void update_export_presets(); + bool poll_export_platforms(); + + EditorExport(); + ~EditorExport(); +}; + +#endif // EDITOR_EXPORT_H diff --git a/editor/editor_export.cpp b/editor/export/editor_export_platform.cpp index bb9d930cf5..9f64b241c6 100644 --- a/editor/editor_export.cpp +++ b/editor/export/editor_export_platform.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* editor_export.cpp */ +/* editor_export_platform.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,28 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "editor_export.h" +#include "editor_export_platform.h" #include "core/config/project_settings.h" #include "core/crypto/crypto_core.h" #include "core/extension/native_extension.h" -#include "core/io/config_file.h" -#include "core/io/dir_access.h" -#include "core/io/file_access.h" #include "core/io/file_access_encrypted.h" #include "core/io/file_access_pack.h" // PACK_HEADER_MAGIC, PACK_FORMAT_VERSION -#include "core/io/resource_loader.h" -#include "core/io/resource_saver.h" #include "core/io/zip_io.h" -#include "core/object/script_language.h" #include "core/version.h" #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" -#include "editor/editor_settings.h" #include "editor/plugins/script_editor_plugin.h" -#include "scene/resources/resource_format_text.h" +#include "editor_export_plugin.h" static int _get_pad(int p_alignment, int p_n) { int rest = p_n % p_alignment; @@ -63,196 +56,6 @@ static int _get_pad(int p_alignment, int p_n) { #define PCK_PADDING 16 -bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value) { - if (values.has(p_name)) { - values[p_name] = p_value; - EditorExport::singleton->save_presets(); - return true; - } - - return false; -} - -bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const { - if (values.has(p_name)) { - r_ret = values[p_name]; - return true; - } - - return false; -} - -void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const { - for (const PropertyInfo &E : properties) { - if (platform->get_export_option_visibility(E.name, values)) { - p_list->push_back(E); - } - } -} - -Ref<EditorExportPlatform> EditorExportPreset::get_platform() const { - return platform; -} - -void EditorExportPreset::update_files_to_export() { - Vector<String> to_remove; - for (const String &E : selected_files) { - if (!FileAccess::exists(E)) { - to_remove.push_back(E); - } - } - for (int i = 0; i < to_remove.size(); ++i) { - selected_files.erase(to_remove[i]); - } -} - -Vector<String> EditorExportPreset::get_files_to_export() const { - Vector<String> files; - for (const String &E : selected_files) { - files.push_back(E); - } - return files; -} - -void EditorExportPreset::set_name(const String &p_name) { - name = p_name; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_name() const { - return name; -} - -void EditorExportPreset::set_runnable(bool p_enable) { - runnable = p_enable; - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::is_runnable() const { - return runnable; -} - -void EditorExportPreset::set_export_filter(ExportFilter p_filter) { - export_filter = p_filter; - EditorExport::singleton->save_presets(); -} - -EditorExportPreset::ExportFilter EditorExportPreset::get_export_filter() const { - return export_filter; -} - -void EditorExportPreset::set_include_filter(const String &p_include) { - include_filter = p_include; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_include_filter() const { - return include_filter; -} - -void EditorExportPreset::set_export_path(const String &p_path) { - export_path = p_path; - /* NOTE(SonerSound): if there is a need to implement a PropertyHint that specifically indicates a relative path, - * this should be removed. */ - if (export_path.is_absolute_path()) { - String res_path = OS::get_singleton()->get_resource_dir(); - export_path = res_path.path_to_file(export_path); - } - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_export_path() const { - return export_path; -} - -void EditorExportPreset::set_exclude_filter(const String &p_exclude) { - exclude_filter = p_exclude; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_exclude_filter() const { - return exclude_filter; -} - -void EditorExportPreset::add_export_file(const String &p_path) { - selected_files.insert(p_path); - EditorExport::singleton->save_presets(); -} - -void EditorExportPreset::remove_export_file(const String &p_path) { - selected_files.erase(p_path); - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::has_export_file(const String &p_path) { - return selected_files.has(p_path); -} - -void EditorExportPreset::set_custom_features(const String &p_custom_features) { - custom_features = p_custom_features; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_custom_features() const { - return custom_features; -} - -void EditorExportPreset::set_enc_in_filter(const String &p_filter) { - enc_in_filters = p_filter; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_enc_in_filter() const { - return enc_in_filters; -} - -void EditorExportPreset::set_enc_ex_filter(const String &p_filter) { - enc_ex_filters = p_filter; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_enc_ex_filter() const { - return enc_ex_filters; -} - -void EditorExportPreset::set_enc_pck(bool p_enabled) { - enc_pck = p_enabled; - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::get_enc_pck() const { - return enc_pck; -} - -void EditorExportPreset::set_enc_directory(bool p_enabled) { - enc_directory = p_enabled; - EditorExport::singleton->save_presets(); -} - -bool EditorExportPreset::get_enc_directory() const { - return enc_directory; -} - -void EditorExportPreset::set_script_export_mode(int p_mode) { - script_mode = p_mode; - EditorExport::singleton->save_presets(); -} - -int EditorExportPreset::get_script_export_mode() const { - return script_mode; -} - -void EditorExportPreset::set_script_encryption_key(const String &p_key) { - script_key = p_key; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_script_encryption_key() const { - return script_key; -} - -/////////////////////////////////// - bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) { bool has_messages = false; @@ -491,7 +294,7 @@ Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const { String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { String current_version = VERSION_FULL_CONFIG; - String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(current_version).plus_file(template_file_name); + String template_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(current_version).plus_file(template_file_name); if (FileAccess::exists(template_path)) { return template_path; @@ -625,138 +428,6 @@ void EditorExportPlatform::_edit_filter_list(HashSet<String> &r_list, const Stri _edit_files_with_filter(da, filters, r_list, exclude); } -void EditorExportPlugin::set_export_preset(const Ref<EditorExportPreset> &p_preset) { - if (p_preset.is_valid()) { - export_preset = p_preset; - } -} - -Ref<EditorExportPreset> EditorExportPlugin::get_export_preset() const { - return export_preset; -} - -void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap) { - ExtraFile ef; - ef.data = p_file; - ef.path = p_path; - ef.remap = p_remap; - extra_files.push_back(ef); -} - -void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &p_tags, const String &p_target) { - shared_objects.push_back(SharedObject(p_path, p_tags, p_target)); -} - -void EditorExportPlugin::add_ios_framework(const String &p_path) { - ios_frameworks.push_back(p_path); -} - -void EditorExportPlugin::add_ios_embedded_framework(const String &p_path) { - ios_embedded_frameworks.push_back(p_path); -} - -Vector<String> EditorExportPlugin::get_ios_frameworks() const { - return ios_frameworks; -} - -Vector<String> EditorExportPlugin::get_ios_embedded_frameworks() const { - return ios_embedded_frameworks; -} - -void EditorExportPlugin::add_ios_plist_content(const String &p_plist_content) { - ios_plist_content += p_plist_content + "\n"; -} - -String EditorExportPlugin::get_ios_plist_content() const { - return ios_plist_content; -} - -void EditorExportPlugin::add_ios_linker_flags(const String &p_flags) { - if (ios_linker_flags.length() > 0) { - ios_linker_flags += ' '; - } - ios_linker_flags += p_flags; -} - -String EditorExportPlugin::get_ios_linker_flags() const { - return ios_linker_flags; -} - -void EditorExportPlugin::add_ios_bundle_file(const String &p_path) { - ios_bundle_files.push_back(p_path); -} - -Vector<String> EditorExportPlugin::get_ios_bundle_files() const { - return ios_bundle_files; -} - -void EditorExportPlugin::add_ios_cpp_code(const String &p_code) { - ios_cpp_code += p_code; -} - -String EditorExportPlugin::get_ios_cpp_code() const { - return ios_cpp_code; -} - -void EditorExportPlugin::add_osx_plugin_file(const String &p_path) { - osx_plugin_files.push_back(p_path); -} - -const Vector<String> &EditorExportPlugin::get_osx_plugin_files() const { - return osx_plugin_files; -} - -void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) { - ios_project_static_libs.push_back(p_path); -} - -Vector<String> EditorExportPlugin::get_ios_project_static_libs() const { - return ios_project_static_libs; -} - -void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) { - GDVIRTUAL_CALL(_export_file, p_path, p_type, p_features); -} - -void EditorExportPlugin::_export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags) { - GDVIRTUAL_CALL(_export_begin, p_features, p_debug, p_path, p_flags); -} - -void EditorExportPlugin::_export_end_script() { - GDVIRTUAL_CALL(_export_end); -} - -void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { -} - -void EditorExportPlugin::_export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags) { -} - -void EditorExportPlugin::skip() { - skipped = true; -} - -void EditorExportPlugin::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags", "target"), &EditorExportPlugin::add_shared_object); - ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib); - ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file); - ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_ios_framework); - ClassDB::bind_method(D_METHOD("add_ios_embedded_framework", "path"), &EditorExportPlugin::add_ios_embedded_framework); - ClassDB::bind_method(D_METHOD("add_ios_plist_content", "plist_content"), &EditorExportPlugin::add_ios_plist_content); - ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags); - ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file); - ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code); - ClassDB::bind_method(D_METHOD("add_osx_plugin_file", "path"), &EditorExportPlugin::add_osx_plugin_file); - ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip); - - GDVIRTUAL_BIND(_export_file, "path", "type", "features"); - GDVIRTUAL_BIND(_export_begin, "features", "is_debug", "path", "flags"); - GDVIRTUAL_BIND(_export_end); -} - -EditorExportPlugin::EditorExportPlugin() { -} - EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug) { Ref<EditorExportPlatform> platform = p_preset->get_platform(); List<String> feature_list; @@ -1504,573 +1175,3 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags EditorExportPlatform::EditorExportPlatform() { } - -//// - -EditorExport *EditorExport::singleton = nullptr; - -void EditorExport::_save() { - Ref<ConfigFile> config; - config.instantiate(); - for (int i = 0; i < export_presets.size(); i++) { - Ref<EditorExportPreset> preset = export_presets[i]; - String section = "preset." + itos(i); - - config->set_value(section, "name", preset->get_name()); - config->set_value(section, "platform", preset->get_platform()->get_name()); - config->set_value(section, "runnable", preset->is_runnable()); - config->set_value(section, "custom_features", preset->get_custom_features()); - - bool save_files = false; - switch (preset->get_export_filter()) { - case EditorExportPreset::EXPORT_ALL_RESOURCES: { - config->set_value(section, "export_filter", "all_resources"); - } break; - case EditorExportPreset::EXPORT_SELECTED_SCENES: { - config->set_value(section, "export_filter", "scenes"); - save_files = true; - } break; - case EditorExportPreset::EXPORT_SELECTED_RESOURCES: { - config->set_value(section, "export_filter", "resources"); - save_files = true; - } break; - case EditorExportPreset::EXCLUDE_SELECTED_RESOURCES: { - config->set_value(section, "export_filter", "exclude"); - save_files = true; - } break; - } - - if (save_files) { - Vector<String> export_files = preset->get_files_to_export(); - config->set_value(section, "export_files", export_files); - } - config->set_value(section, "include_filter", preset->get_include_filter()); - config->set_value(section, "exclude_filter", preset->get_exclude_filter()); - config->set_value(section, "export_path", preset->get_export_path()); - config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter()); - config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter()); - config->set_value(section, "encrypt_pck", preset->get_enc_pck()); - config->set_value(section, "encrypt_directory", preset->get_enc_directory()); - config->set_value(section, "script_export_mode", preset->get_script_export_mode()); - config->set_value(section, "script_encryption_key", preset->get_script_encryption_key()); - - String option_section = "preset." + itos(i) + ".options"; - - for (const PropertyInfo &E : preset->get_properties()) { - config->set_value(option_section, E.name, preset->get(E.name)); - } - } - - config->save("res://export_presets.cfg"); -} - -void EditorExport::save_presets() { - if (block_save) { - return; - } - save_timer->start(); -} - -void EditorExport::_bind_methods() { - ADD_SIGNAL(MethodInfo("export_presets_updated")); -} - -void EditorExport::add_export_platform(const Ref<EditorExportPlatform> &p_platform) { - export_platforms.push_back(p_platform); -} - -int EditorExport::get_export_platform_count() { - return export_platforms.size(); -} - -Ref<EditorExportPlatform> EditorExport::get_export_platform(int p_idx) { - ERR_FAIL_INDEX_V(p_idx, export_platforms.size(), Ref<EditorExportPlatform>()); - - return export_platforms[p_idx]; -} - -void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos) { - if (p_at_pos < 0) { - export_presets.push_back(p_preset); - } else { - export_presets.insert(p_at_pos, p_preset); - } -} - -String EditorExportPlatform::test_etc2() const { - const bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/textures/vram_compression/import_etc2"); - - if (!etc2_supported) { - return TTR("Target platform requires 'ETC2' texture compression. Enable 'Import Etc 2' in Project Settings."); - } - - return String(); -} - -int EditorExport::get_export_preset_count() const { - return export_presets.size(); -} - -Ref<EditorExportPreset> EditorExport::get_export_preset(int p_idx) { - ERR_FAIL_INDEX_V(p_idx, export_presets.size(), Ref<EditorExportPreset>()); - return export_presets[p_idx]; -} - -void EditorExport::remove_export_preset(int p_idx) { - export_presets.remove_at(p_idx); - save_presets(); -} - -void EditorExport::add_export_plugin(const Ref<EditorExportPlugin> &p_plugin) { - if (!export_plugins.has(p_plugin)) { - export_plugins.push_back(p_plugin); - } -} - -void EditorExport::remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin) { - export_plugins.erase(p_plugin); -} - -Vector<Ref<EditorExportPlugin>> EditorExport::get_export_plugins() { - return export_plugins; -} - -void EditorExport::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - load_config(); - } break; - - case NOTIFICATION_PROCESS: { - update_export_presets(); - } break; - } -} - -void EditorExport::load_config() { - Ref<ConfigFile> config; - config.instantiate(); - Error err = config->load("res://export_presets.cfg"); - if (err != OK) { - return; - } - - block_save = true; - - int index = 0; - while (true) { - String section = "preset." + itos(index); - if (!config->has_section(section)) { - break; - } - - String platform = config->get_value(section, "platform"); - - Ref<EditorExportPreset> preset; - - for (int i = 0; i < export_platforms.size(); i++) { - if (export_platforms[i]->get_name() == platform) { - preset = export_platforms.write[i]->create_preset(); - break; - } - } - - if (!preset.is_valid()) { - index++; - ERR_CONTINUE(!preset.is_valid()); - } - - preset->set_name(config->get_value(section, "name")); - preset->set_runnable(config->get_value(section, "runnable")); - - if (config->has_section_key(section, "custom_features")) { - preset->set_custom_features(config->get_value(section, "custom_features")); - } - - String export_filter = config->get_value(section, "export_filter"); - - bool get_files = false; - - if (export_filter == "all_resources") { - preset->set_export_filter(EditorExportPreset::EXPORT_ALL_RESOURCES); - } else if (export_filter == "scenes") { - preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_SCENES); - get_files = true; - } else if (export_filter == "resources") { - preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_RESOURCES); - get_files = true; - } else if (export_filter == "exclude") { - preset->set_export_filter(EditorExportPreset::EXCLUDE_SELECTED_RESOURCES); - get_files = true; - } - - if (get_files) { - Vector<String> files = config->get_value(section, "export_files"); - - for (int i = 0; i < files.size(); i++) { - if (!FileAccess::exists(files[i])) { - preset->remove_export_file(files[i]); - } else { - preset->add_export_file(files[i]); - } - } - } - - preset->set_include_filter(config->get_value(section, "include_filter")); - preset->set_exclude_filter(config->get_value(section, "exclude_filter")); - preset->set_export_path(config->get_value(section, "export_path", "")); - - if (config->has_section_key(section, "encrypt_pck")) { - preset->set_enc_pck(config->get_value(section, "encrypt_pck")); - } - if (config->has_section_key(section, "encrypt_directory")) { - preset->set_enc_directory(config->get_value(section, "encrypt_directory")); - } - if (config->has_section_key(section, "encryption_include_filters")) { - preset->set_enc_in_filter(config->get_value(section, "encryption_include_filters")); - } - if (config->has_section_key(section, "encryption_exclude_filters")) { - preset->set_enc_ex_filter(config->get_value(section, "encryption_exclude_filters")); - } - if (config->has_section_key(section, "script_export_mode")) { - preset->set_script_export_mode(config->get_value(section, "script_export_mode")); - } - if (config->has_section_key(section, "script_encryption_key")) { - preset->set_script_encryption_key(config->get_value(section, "script_encryption_key")); - } - - String option_section = "preset." + itos(index) + ".options"; - - List<String> options; - - config->get_section_keys(option_section, &options); - - for (const String &E : options) { - Variant value = config->get_value(option_section, E); - - preset->set(E, value); - } - - add_export_preset(preset); - index++; - } - - block_save = false; -} - -void EditorExport::update_export_presets() { - HashMap<StringName, List<EditorExportPlatform::ExportOption>> platform_options; - - for (int i = 0; i < export_platforms.size(); i++) { - Ref<EditorExportPlatform> platform = export_platforms[i]; - - if (platform->should_update_export_options()) { - List<EditorExportPlatform::ExportOption> options; - platform->get_export_options(&options); - - platform_options[platform->get_name()] = options; - } - } - - bool export_presets_updated = false; - for (int i = 0; i < export_presets.size(); i++) { - Ref<EditorExportPreset> preset = export_presets[i]; - if (platform_options.has(preset->get_platform()->get_name())) { - export_presets_updated = true; - - List<EditorExportPlatform::ExportOption> options = platform_options[preset->get_platform()->get_name()]; - - // Copy the previous preset values - HashMap<StringName, Variant> previous_values = preset->values; - - // Clear the preset properties and values prior to reloading - preset->properties.clear(); - preset->values.clear(); - - for (const EditorExportPlatform::ExportOption &E : options) { - preset->properties.push_back(E.option); - - StringName option_name = E.option.name; - preset->values[option_name] = previous_values.has(option_name) ? previous_values[option_name] : E.default_value; - } - } - } - - if (export_presets_updated) { - emit_signal(_export_presets_updated); - } -} - -bool EditorExport::poll_export_platforms() { - bool changed = false; - for (int i = 0; i < export_platforms.size(); i++) { - if (export_platforms.write[i]->poll_export()) { - changed = true; - } - } - - return changed; -} - -EditorExport::EditorExport() { - save_timer = memnew(Timer); - add_child(save_timer); - save_timer->set_wait_time(0.8); - save_timer->set_one_shot(true); - save_timer->connect("timeout", callable_mp(this, &EditorExport::_save)); - - _export_presets_updated = "export_presets_updated"; - - singleton = this; - set_process(true); -} - -EditorExport::~EditorExport() { -} - -////////// - -void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - if (p_preset->get("texture_format/s3tc")) { - r_features->push_back("s3tc"); - } - if (p_preset->get("texture_format/etc")) { - r_features->push_back("etc"); - } - if (p_preset->get("texture_format/etc2")) { - r_features->push_back("etc2"); - } - - if (p_preset->get("binary_format/64_bits")) { - r_features->push_back("64"); - } else { - r_features->push_back("32"); - } -} - -void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) { - String ext_filter = (get_os_name() == "Windows") ? "*.exe" : ""; - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); - - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "debug/export_console_script", PROPERTY_HINT_ENUM, "No,Debug Only,Debug and Release"), 1)); - - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/64_bits"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/embed_pck"), false)); - - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/bptc"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/no_bptc_fallbacks"), true)); -} - -String EditorExportPlatformPC::get_name() const { - return name; -} - -String EditorExportPlatformPC::get_os_name() const { - return os_name; -} - -Ref<Texture2D> EditorExportPlatformPC::get_logo() const { - return logo; -} - -bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { - String err; - bool valid = false; - - // Look for export templates (first official, and if defined custom templates). - - bool use64 = p_preset->get("binary_format/64_bits"); - bool dvalid = exists_export_template(get_template_file_name("debug", use64 ? "64" : "32"), &err); - bool rvalid = exists_export_template(get_template_file_name("release", use64 ? "64" : "32"), &err); - - if (p_preset->get("custom_template/debug") != "") { - dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); - if (!dvalid) { - err += TTR("Custom debug template not found.") + "\n"; - } - } - if (p_preset->get("custom_template/release") != "") { - rvalid = FileAccess::exists(p_preset->get("custom_template/release")); - if (!rvalid) { - err += TTR("Custom release template not found.") + "\n"; - } - } - - valid = dvalid || rvalid; - r_missing_templates = !valid; - - if (!err.is_empty()) { - r_error = err; - } - return valid; -} - -Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); - - Error err = prepare_template(p_preset, p_debug, p_path, p_flags); - if (err == OK) { - err = modify_template(p_preset, p_debug, p_path, p_flags); - } - if (err == OK) { - err = export_project_data(p_preset, p_debug, p_path, p_flags); - } - - return err; -} - -Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - if (!DirAccess::exists(p_path.get_base_dir())) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("The given export path doesn't exist.")); - return ERR_FILE_BAD_PATH; - } - - String custom_debug = p_preset->get("custom_template/debug"); - String custom_release = p_preset->get("custom_template/release"); - - String template_path = p_debug ? custom_debug : custom_release; - - template_path = template_path.strip_edges(); - - if (template_path.is_empty()) { - template_path = find_export_template(get_template_file_name(p_debug ? "debug" : "release", p_preset->get("binary_format/64_bits") ? "64" : "32")); - } - - if (!template_path.is_empty() && !FileAccess::exists(template_path)) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), vformat(TTR("Template file not found: \"%s\"."), template_path)); - return ERR_FILE_NOT_FOUND; - } - - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - da->make_dir_recursive(p_path.get_base_dir()); - Error err = da->copy(template_path, p_path, get_chmod_flags()); - if (err != OK) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template.")); - } - - return err; -} - -Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - String pck_path; - if (p_preset->get("binary_format/embed_pck")) { - pck_path = p_path; - } else { - pck_path = p_path.get_basename() + ".pck"; - } - - Vector<SharedObject> so_files; - - int64_t embedded_pos; - int64_t embedded_size; - Error err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size); - if (err == OK && p_preset->get("binary_format/embed_pck")) { - if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) { - add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); - return ERR_INVALID_PARAMETER; - } - - err = fixup_embedded_pck(p_path, embedded_pos, embedded_size); - } - - if (err == OK && !so_files.is_empty()) { - // If shared object files, copy them. - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - for (int i = 0; i < so_files.size() && err == OK; i++) { - String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path); - String target_path; - if (so_files[i].target.is_empty()) { - target_path = p_path.get_base_dir().plus_file(src_path.get_file()); - } else { - target_path = p_path.get_base_dir().plus_file(so_files[i].target).plus_file(src_path.get_file()); - } - - if (da->dir_exists(src_path)) { - err = da->make_dir_recursive(target_path); - if (err == OK) { - err = da->copy_dir(src_path, target_path, -1, true); - } - } else { - err = da->copy(src_path, target_path); - if (err == OK) { - err = sign_shared_object(p_preset, p_debug, target_path); - } - } - } - } - - return err; -} - -Error EditorExportPlatformPC::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) { - return OK; -} - -void EditorExportPlatformPC::set_name(const String &p_name) { - name = p_name; -} - -void EditorExportPlatformPC::set_os_name(const String &p_name) { - os_name = p_name; -} - -void EditorExportPlatformPC::set_logo(const Ref<Texture2D> &p_logo) { - logo = p_logo; -} - -void EditorExportPlatformPC::get_platform_features(List<String> *r_features) { - r_features->push_back("pc"); //all pcs support "pc" - r_features->push_back("s3tc"); //all pcs support "s3tc" compression - r_features->push_back(get_os_name().to_lower()); //OS name is a feature -} - -void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) { - if (p_features.has("bptc")) { - if (p_preset->has("texture_format/no_bptc_fallbacks")) { - p_features.erase("s3tc"); - } - } -} - -int EditorExportPlatformPC::get_chmod_flags() const { - return chmod_flags; -} - -void EditorExportPlatformPC::set_chmod_flags(int p_flags) { - chmod_flags = p_flags; -} - -/////////////////////// - -void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { - String extension = p_path.get_extension().to_lower(); - if (extension != "tres" && extension != "tscn") { - return; - } - - bool convert = GLOBAL_GET("editor/export/convert_text_resources_to_binary"); - if (!convert) { - return; - } - String tmp_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpfile.res"); - Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path); - if (err != OK) { - DirAccess::remove_file_or_error(tmp_path); - ERR_FAIL(); - } - Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path); - if (data.size() == 0) { - DirAccess::remove_file_or_error(tmp_path); - ERR_FAIL(); - } - DirAccess::remove_file_or_error(tmp_path); - add_file(p_path + ".converted.res", data, true); -} - -EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() { - GLOBAL_DEF("editor/export/convert_text_resources_to_binary", false); -} diff --git a/editor/export/editor_export_platform.h b/editor/export/editor_export_platform.h new file mode 100644 index 0000000000..2778a217b0 --- /dev/null +++ b/editor/export/editor_export_platform.h @@ -0,0 +1,221 @@ +/*************************************************************************/ +/* editor_export_platform.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 EDITOR_EXPORT_PLATFORM_H +#define EDITOR_EXPORT_PLATFORM_H + +class EditorFileSystemDirectory; +struct EditorProgress; + +#include "core/io/dir_access.h" +#include "editor_export_preset.h" +#include "editor_export_shared_object.h" +#include "scene/gui/rich_text_label.h" +#include "scene/main/node.h" + +class EditorExportPlatform : public RefCounted { + GDCLASS(EditorExportPlatform, RefCounted); + +public: + typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so); + + enum ExportMessageType { + EXPORT_MESSAGE_NONE, + EXPORT_MESSAGE_INFO, + EXPORT_MESSAGE_WARNING, + EXPORT_MESSAGE_ERROR, + }; + + struct ExportMessage { + ExportMessageType msg_type; + String category; + String text; + }; + +private: + struct SavedData { + uint64_t ofs = 0; + uint64_t size = 0; + bool encrypted = false; + Vector<uint8_t> md5; + CharString path_utf8; + + bool operator<(const SavedData &p_data) const { + return path_utf8 < p_data.path_utf8; + } + }; + + struct PackData { + Ref<FileAccess> f; + Vector<SavedData> file_ofs; + EditorProgress *ep = nullptr; + Vector<SharedObject> *so_files = nullptr; + }; + + struct ZipData { + void *zip = nullptr; + EditorProgress *ep = nullptr; + }; + + struct FeatureContainers { + HashSet<String> features; + Vector<String> features_pv; + }; + + Vector<ExportMessage> messages; + + void _export_find_resources(EditorFileSystemDirectory *p_dir, HashSet<String> &p_paths); + void _export_find_dependencies(const String &p_path, HashSet<String> &p_paths); + + void gen_debug_flags(Vector<String> &r_flags, int p_flags); + static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + + void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude); + void _edit_filter_list(HashSet<String> &r_list, const String &p_filter, bool exclude); + + static Error _add_shared_object(void *p_userdata, const SharedObject &p_so); + +protected: + struct ExportNotifier { + ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); + ~ExportNotifier(); + }; + + FeatureContainers get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug); + + bool exists_export_template(String template_file_name, String *err) const; + String find_export_template(String template_file_name, String *err = nullptr) const; + void gen_export_flags(Vector<String> &r_flags, int p_flags); + +public: + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) = 0; + + struct ExportOption { + PropertyInfo option; + Variant default_value; + + ExportOption(const PropertyInfo &p_info, const Variant &p_default) : + option(p_info), + default_value(p_default) { + } + ExportOption() {} + }; + + virtual Ref<EditorExportPreset> create_preset(); + + virtual void clear_messages() { messages.clear(); } + virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) { + ExportMessage msg; + msg.category = p_category; + msg.text = p_message; + msg.msg_type = p_type; + messages.push_back(msg); + switch (p_type) { + case EXPORT_MESSAGE_INFO: { + print_line(vformat("%s: %s\n", msg.category, msg.text)); + } break; + case EXPORT_MESSAGE_WARNING: { + WARN_PRINT(vformat("%s: %s\n", msg.category, msg.text)); + } break; + case EXPORT_MESSAGE_ERROR: { + ERR_PRINT(vformat("%s: %s\n", msg.category, msg.text)); + } break; + default: + break; + } + } + + virtual int get_message_count() const { + return messages.size(); + } + + virtual ExportMessage get_message(int p_index) const { + ERR_FAIL_INDEX_V(p_index, messages.size(), ExportMessage()); + return messages[p_index]; + } + + virtual ExportMessageType get_worst_message_type() const { + ExportMessageType worst_type = EXPORT_MESSAGE_NONE; + for (int i = 0; i < messages.size(); i++) { + worst_type = MAX(worst_type, messages[i].msg_type); + } + return worst_type; + } + + virtual bool fill_log_messages(RichTextLabel *p_log, Error p_err); + + virtual void get_export_options(List<ExportOption> *r_options) = 0; + virtual bool should_update_export_options() { return false; } + virtual bool get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const { return true; } + + virtual String get_os_name() const = 0; + virtual String get_name() const = 0; + virtual Ref<Texture2D> get_logo() const = 0; + + Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr); + + Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr); + Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); + + virtual bool poll_export() { return false; } + virtual int get_options_count() const { return 0; } + virtual String get_options_tooltip() const { return ""; } + virtual Ref<ImageTexture> get_option_icon(int p_index) const; + virtual String get_option_label(int p_device) const { return ""; } + virtual String get_option_tooltip(int p_device) const { return ""; } + + enum DebugFlags { + DEBUG_FLAG_DUMB_CLIENT = 1, + DEBUG_FLAG_REMOTE_DEBUG = 2, + DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST = 4, + DEBUG_FLAG_VIEW_COLLISONS = 8, + DEBUG_FLAG_VIEW_NAVIGATION = 16, + }; + + virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; } + virtual Ref<Texture2D> get_run_icon() const { return get_logo(); } + + String test_etc2() const; + virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0; + + virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const = 0; + virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) = 0; + virtual Error export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); + virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); + virtual void get_platform_features(List<String> *r_features) = 0; + virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) = 0; + virtual String get_debug_protocol() const { return "tcp://"; } + + EditorExportPlatform(); +}; + +#endif // EDITOR_EXPORT_PLATFORM_H diff --git a/editor/export/editor_export_platform_pc.cpp b/editor/export/editor_export_platform_pc.cpp new file mode 100644 index 0000000000..b60fba13ed --- /dev/null +++ b/editor/export/editor_export_platform_pc.cpp @@ -0,0 +1,247 @@ +/*************************************************************************/ +/* editor_export_platform_pc.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "editor_export_platform_pc.h" + +#include "core/config/project_settings.h" + +void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { + if (p_preset->get("texture_format/s3tc")) { + r_features->push_back("s3tc"); + } + if (p_preset->get("texture_format/etc")) { + r_features->push_back("etc"); + } + if (p_preset->get("texture_format/etc2")) { + r_features->push_back("etc2"); + } + + if (p_preset->get("binary_format/64_bits")) { + r_features->push_back("64"); + } else { + r_features->push_back("32"); + } +} + +void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) { + String ext_filter = (get_os_name() == "Windows") ? "*.exe" : ""; + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); + + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "debug/export_console_script", PROPERTY_HINT_ENUM, "No,Debug Only,Debug and Release"), 1)); + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/64_bits"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/embed_pck"), false)); + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/bptc"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/no_bptc_fallbacks"), true)); +} + +String EditorExportPlatformPC::get_name() const { + return name; +} + +String EditorExportPlatformPC::get_os_name() const { + return os_name; +} + +Ref<Texture2D> EditorExportPlatformPC::get_logo() const { + return logo; +} + +bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { + String err; + bool valid = false; + + // Look for export templates (first official, and if defined custom templates). + + bool use64 = p_preset->get("binary_format/64_bits"); + bool dvalid = exists_export_template(get_template_file_name("debug", use64 ? "x86_64" : "x86_32"), &err); + bool rvalid = exists_export_template(get_template_file_name("release", use64 ? "x86_64" : "x86_32"), &err); + + if (p_preset->get("custom_template/debug") != "") { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { + err += TTR("Custom debug template not found.") + "\n"; + } + } + if (p_preset->get("custom_template/release") != "") { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { + err += TTR("Custom release template not found.") + "\n"; + } + } + + valid = dvalid || rvalid; + r_missing_templates = !valid; + + if (!err.is_empty()) { + r_error = err; + } + return valid; +} + +Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { + ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); + + Error err = prepare_template(p_preset, p_debug, p_path, p_flags); + if (err == OK) { + err = modify_template(p_preset, p_debug, p_path, p_flags); + } + if (err == OK) { + err = export_project_data(p_preset, p_debug, p_path, p_flags); + } + + return err; +} + +Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { + if (!DirAccess::exists(p_path.get_base_dir())) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("The given export path doesn't exist.")); + return ERR_FILE_BAD_PATH; + } + + String custom_debug = p_preset->get("custom_template/debug"); + String custom_release = p_preset->get("custom_template/release"); + + String template_path = p_debug ? custom_debug : custom_release; + + template_path = template_path.strip_edges(); + + if (template_path.is_empty()) { + template_path = find_export_template(get_template_file_name(p_debug ? "debug" : "release", p_preset->get("binary_format/64_bits") ? "64" : "32")); + } + + if (!template_path.is_empty() && !FileAccess::exists(template_path)) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), vformat(TTR("Template file not found: \"%s\"."), template_path)); + return ERR_FILE_NOT_FOUND; + } + + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + da->make_dir_recursive(p_path.get_base_dir()); + Error err = da->copy(template_path, p_path, get_chmod_flags()); + if (err != OK) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template.")); + } + + return err; +} + +Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { + String pck_path; + if (p_preset->get("binary_format/embed_pck")) { + pck_path = p_path; + } else { + pck_path = p_path.get_basename() + ".pck"; + } + + Vector<SharedObject> so_files; + + int64_t embedded_pos; + int64_t embedded_size; + Error err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size); + if (err == OK && p_preset->get("binary_format/embed_pck")) { + if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) { + add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); + return ERR_INVALID_PARAMETER; + } + + err = fixup_embedded_pck(p_path, embedded_pos, embedded_size); + } + + if (err == OK && !so_files.is_empty()) { + // If shared object files, copy them. + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + for (int i = 0; i < so_files.size() && err == OK; i++) { + String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path); + String target_path; + if (so_files[i].target.is_empty()) { + target_path = p_path.get_base_dir().plus_file(src_path.get_file()); + } else { + target_path = p_path.get_base_dir().plus_file(so_files[i].target).plus_file(src_path.get_file()); + } + + if (da->dir_exists(src_path)) { + err = da->make_dir_recursive(target_path); + if (err == OK) { + err = da->copy_dir(src_path, target_path, -1, true); + } + } else { + err = da->copy(src_path, target_path); + if (err == OK) { + err = sign_shared_object(p_preset, p_debug, target_path); + } + } + } + } + + return err; +} + +Error EditorExportPlatformPC::sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) { + return OK; +} + +void EditorExportPlatformPC::set_name(const String &p_name) { + name = p_name; +} + +void EditorExportPlatformPC::set_os_name(const String &p_name) { + os_name = p_name; +} + +void EditorExportPlatformPC::set_logo(const Ref<Texture2D> &p_logo) { + logo = p_logo; +} + +void EditorExportPlatformPC::get_platform_features(List<String> *r_features) { + r_features->push_back("pc"); //all pcs support "pc" + r_features->push_back("s3tc"); //all pcs support "s3tc" compression + r_features->push_back(get_os_name().to_lower()); //OS name is a feature +} + +void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) { + if (p_features.has("bptc")) { + if (p_preset->has("texture_format/no_bptc_fallbacks")) { + p_features.erase("s3tc"); + } + } +} + +int EditorExportPlatformPC::get_chmod_flags() const { + return chmod_flags; +} + +void EditorExportPlatformPC::set_chmod_flags(int p_flags) { + chmod_flags = p_flags; +} diff --git a/editor/export/editor_export_platform_pc.h b/editor/export/editor_export_platform_pc.h new file mode 100644 index 0000000000..ae7d6f1082 --- /dev/null +++ b/editor/export/editor_export_platform_pc.h @@ -0,0 +1,82 @@ +/*************************************************************************/ +/* editor_export_platform_pc.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 EDITOR_EXPORT_PLATFORM_PC_H +#define EDITOR_EXPORT_PLATFORM_PC_H + +#include "editor_export_platform.h" + +class EditorExportPlatformPC : public EditorExportPlatform { + GDCLASS(EditorExportPlatformPC, EditorExportPlatform); + +private: + Ref<ImageTexture> logo; + String name; + String os_name; + + int chmod_flags = -1; + +public: + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) override; + + virtual void get_export_options(List<ExportOption> *r_options) override; + + virtual String get_name() const override; + virtual String get_os_name() const override; + virtual Ref<Texture2D> get_logo() const override; + + virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override; + virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; + virtual Error sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); + virtual String get_template_file_name(const String &p_target, const String &p_arch) const = 0; + + virtual Error prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); + virtual Error modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { return OK; }; + virtual Error export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags); + + void set_extension(const String &p_extension, const String &p_feature_key = "default"); + void set_name(const String &p_name); + void set_os_name(const String &p_name); + + void set_logo(const Ref<Texture2D> &p_logo); + + void add_platform_feature(const String &p_feature); + virtual void get_platform_features(List<String> *r_features) override; + virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override; + + int get_chmod_flags() const; + void set_chmod_flags(int p_flags); + + virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { + return Error::OK; + } +}; + +#endif // EDITOR_EXPORT_PLATFORM_PC_H diff --git a/editor/export/editor_export_plugin.cpp b/editor/export/editor_export_plugin.cpp new file mode 100644 index 0000000000..cf3a9b0810 --- /dev/null +++ b/editor/export/editor_export_plugin.cpp @@ -0,0 +1,201 @@ +/*************************************************************************/ +/* editor_export_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "editor_export_plugin.h" + +#include "core/config/project_settings.h" +#include "core/io/dir_access.h" +#include "core/io/file_access.h" +#include "editor/editor_paths.h" +#include "editor/export/editor_export_platform.h" +#include "scene/resources/resource_format_text.h" + +void EditorExportPlugin::set_export_preset(const Ref<EditorExportPreset> &p_preset) { + if (p_preset.is_valid()) { + export_preset = p_preset; + } +} + +Ref<EditorExportPreset> EditorExportPlugin::get_export_preset() const { + return export_preset; +} + +void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap) { + ExtraFile ef; + ef.data = p_file; + ef.path = p_path; + ef.remap = p_remap; + extra_files.push_back(ef); +} + +void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &p_tags, const String &p_target) { + shared_objects.push_back(SharedObject(p_path, p_tags, p_target)); +} + +void EditorExportPlugin::add_ios_framework(const String &p_path) { + ios_frameworks.push_back(p_path); +} + +void EditorExportPlugin::add_ios_embedded_framework(const String &p_path) { + ios_embedded_frameworks.push_back(p_path); +} + +Vector<String> EditorExportPlugin::get_ios_frameworks() const { + return ios_frameworks; +} + +Vector<String> EditorExportPlugin::get_ios_embedded_frameworks() const { + return ios_embedded_frameworks; +} + +void EditorExportPlugin::add_ios_plist_content(const String &p_plist_content) { + ios_plist_content += p_plist_content + "\n"; +} + +String EditorExportPlugin::get_ios_plist_content() const { + return ios_plist_content; +} + +void EditorExportPlugin::add_ios_linker_flags(const String &p_flags) { + if (ios_linker_flags.length() > 0) { + ios_linker_flags += ' '; + } + ios_linker_flags += p_flags; +} + +String EditorExportPlugin::get_ios_linker_flags() const { + return ios_linker_flags; +} + +void EditorExportPlugin::add_ios_bundle_file(const String &p_path) { + ios_bundle_files.push_back(p_path); +} + +Vector<String> EditorExportPlugin::get_ios_bundle_files() const { + return ios_bundle_files; +} + +void EditorExportPlugin::add_ios_cpp_code(const String &p_code) { + ios_cpp_code += p_code; +} + +String EditorExportPlugin::get_ios_cpp_code() const { + return ios_cpp_code; +} + +void EditorExportPlugin::add_macos_plugin_file(const String &p_path) { + macos_plugin_files.push_back(p_path); +} + +const Vector<String> &EditorExportPlugin::get_macos_plugin_files() const { + return macos_plugin_files; +} + +void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) { + ios_project_static_libs.push_back(p_path); +} + +Vector<String> EditorExportPlugin::get_ios_project_static_libs() const { + return ios_project_static_libs; +} + +void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) { + GDVIRTUAL_CALL(_export_file, p_path, p_type, p_features); +} + +void EditorExportPlugin::_export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags) { + GDVIRTUAL_CALL(_export_begin, p_features, p_debug, p_path, p_flags); +} + +void EditorExportPlugin::_export_end_script() { + GDVIRTUAL_CALL(_export_end); +} + +void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { +} + +void EditorExportPlugin::_export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags) { +} + +void EditorExportPlugin::skip() { + skipped = true; +} + +void EditorExportPlugin::_bind_methods() { + ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags", "target"), &EditorExportPlugin::add_shared_object); + ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib); + ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file); + ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_ios_framework); + ClassDB::bind_method(D_METHOD("add_ios_embedded_framework", "path"), &EditorExportPlugin::add_ios_embedded_framework); + ClassDB::bind_method(D_METHOD("add_ios_plist_content", "plist_content"), &EditorExportPlugin::add_ios_plist_content); + ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags); + ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file); + ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code); + ClassDB::bind_method(D_METHOD("add_macos_plugin_file", "path"), &EditorExportPlugin::add_macos_plugin_file); + ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip); + + GDVIRTUAL_BIND(_export_file, "path", "type", "features"); + GDVIRTUAL_BIND(_export_begin, "features", "is_debug", "path", "flags"); + GDVIRTUAL_BIND(_export_end); +} + +EditorExportPlugin::EditorExportPlugin() { +} + +/////////////////////// + +void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { + String extension = p_path.get_extension().to_lower(); + if (extension != "tres" && extension != "tscn") { + return; + } + + bool convert = GLOBAL_GET("editor/export/convert_text_resources_to_binary"); + if (!convert) { + return; + } + String tmp_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpfile.res"); + Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path); + if (err != OK) { + DirAccess::remove_file_or_error(tmp_path); + ERR_FAIL(); + } + Vector<uint8_t> data = FileAccess::get_file_as_array(tmp_path); + if (data.size() == 0) { + DirAccess::remove_file_or_error(tmp_path); + ERR_FAIL(); + } + DirAccess::remove_file_or_error(tmp_path); + add_file(p_path + ".converted.res", data, true); +} + +EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() { + GLOBAL_DEF("editor/export/convert_text_resources_to_binary", false); +} diff --git a/editor/export/editor_export_plugin.h b/editor/export/editor_export_plugin.h new file mode 100644 index 0000000000..04ebc1dfed --- /dev/null +++ b/editor/export/editor_export_plugin.h @@ -0,0 +1,132 @@ +/*************************************************************************/ +/* editor_export_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 EDITOR_EXPORT_PLUGIN_H +#define EDITOR_EXPORT_PLUGIN_H + +#include "core/extension/native_extension.h" +#include "editor_export_preset.h" +#include "editor_export_shared_object.h" + +class EditorExportPlugin : public RefCounted { + GDCLASS(EditorExportPlugin, RefCounted); + + friend class EditorExportPlatform; + + Ref<EditorExportPreset> export_preset; + + Vector<SharedObject> shared_objects; + struct ExtraFile { + String path; + Vector<uint8_t> data; + bool remap = false; + }; + Vector<ExtraFile> extra_files; + bool skipped = false; + + Vector<String> ios_frameworks; + Vector<String> ios_embedded_frameworks; + Vector<String> ios_project_static_libs; + String ios_plist_content; + String ios_linker_flags; + Vector<String> ios_bundle_files; + String ios_cpp_code; + + Vector<String> macos_plugin_files; + + _FORCE_INLINE_ void _clear() { + shared_objects.clear(); + extra_files.clear(); + skipped = false; + } + + _FORCE_INLINE_ void _export_end() { + ios_frameworks.clear(); + ios_embedded_frameworks.clear(); + ios_bundle_files.clear(); + ios_plist_content = ""; + ios_linker_flags = ""; + ios_cpp_code = ""; + macos_plugin_files.clear(); + } + + void _export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features); + void _export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags); + void _export_end_script(); + +protected: + void set_export_preset(const Ref<EditorExportPreset> &p_preset); + Ref<EditorExportPreset> get_export_preset() const; + + void add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap); + void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String()); + + void add_ios_framework(const String &p_path); + void add_ios_embedded_framework(const String &p_path); + void add_ios_project_static_lib(const String &p_path); + void add_ios_plist_content(const String &p_plist_content); + void add_ios_linker_flags(const String &p_flags); + void add_ios_bundle_file(const String &p_path); + void add_ios_cpp_code(const String &p_code); + void add_macos_plugin_file(const String &p_path); + + void skip(); + + virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features); + virtual void _export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags); + + static void _bind_methods(); + + GDVIRTUAL3(_export_file, String, String, Vector<String>) + GDVIRTUAL4(_export_begin, Vector<String>, bool, String, uint32_t) + GDVIRTUAL0(_export_end) + +public: + Vector<String> get_ios_frameworks() const; + Vector<String> get_ios_embedded_frameworks() const; + Vector<String> get_ios_project_static_libs() const; + String get_ios_plist_content() const; + String get_ios_linker_flags() const; + Vector<String> get_ios_bundle_files() const; + String get_ios_cpp_code() const; + const Vector<String> &get_macos_plugin_files() const; + + EditorExportPlugin(); +}; + +class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin { + GDCLASS(EditorExportTextSceneToBinaryPlugin, EditorExportPlugin); + +public: + virtual void _export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) override; + EditorExportTextSceneToBinaryPlugin(); +}; + +#endif // EDITOR_EXPORT_PLUGIN_H diff --git a/editor/export/editor_export_preset.cpp b/editor/export/editor_export_preset.cpp new file mode 100644 index 0000000000..cdf69e727d --- /dev/null +++ b/editor/export/editor_export_preset.cpp @@ -0,0 +1,221 @@ +/*************************************************************************/ +/* editor_export_preset.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "editor_export.h" + +bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value) { + if (values.has(p_name)) { + values[p_name] = p_value; + EditorExport::singleton->save_presets(); + return true; + } + + return false; +} + +bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const { + if (values.has(p_name)) { + r_ret = values[p_name]; + return true; + } + + return false; +} + +void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const { + for (const PropertyInfo &E : properties) { + if (platform->get_export_option_visibility(E.name, values)) { + p_list->push_back(E); + } + } +} + +Ref<EditorExportPlatform> EditorExportPreset::get_platform() const { + return platform; +} + +void EditorExportPreset::update_files_to_export() { + Vector<String> to_remove; + for (const String &E : selected_files) { + if (!FileAccess::exists(E)) { + to_remove.push_back(E); + } + } + for (int i = 0; i < to_remove.size(); ++i) { + selected_files.erase(to_remove[i]); + } +} + +Vector<String> EditorExportPreset::get_files_to_export() const { + Vector<String> files; + for (const String &E : selected_files) { + files.push_back(E); + } + return files; +} + +void EditorExportPreset::set_name(const String &p_name) { + name = p_name; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_name() const { + return name; +} + +void EditorExportPreset::set_runnable(bool p_enable) { + runnable = p_enable; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::is_runnable() const { + return runnable; +} + +void EditorExportPreset::set_export_filter(ExportFilter p_filter) { + export_filter = p_filter; + EditorExport::singleton->save_presets(); +} + +EditorExportPreset::ExportFilter EditorExportPreset::get_export_filter() const { + return export_filter; +} + +void EditorExportPreset::set_include_filter(const String &p_include) { + include_filter = p_include; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_include_filter() const { + return include_filter; +} + +void EditorExportPreset::set_export_path(const String &p_path) { + export_path = p_path; + /* NOTE(SonerSound): if there is a need to implement a PropertyHint that specifically indicates a relative path, + * this should be removed. */ + if (export_path.is_absolute_path()) { + String res_path = OS::get_singleton()->get_resource_dir(); + export_path = res_path.path_to_file(export_path); + } + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_export_path() const { + return export_path; +} + +void EditorExportPreset::set_exclude_filter(const String &p_exclude) { + exclude_filter = p_exclude; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_exclude_filter() const { + return exclude_filter; +} + +void EditorExportPreset::add_export_file(const String &p_path) { + selected_files.insert(p_path); + EditorExport::singleton->save_presets(); +} + +void EditorExportPreset::remove_export_file(const String &p_path) { + selected_files.erase(p_path); + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::has_export_file(const String &p_path) { + return selected_files.has(p_path); +} + +void EditorExportPreset::set_custom_features(const String &p_custom_features) { + custom_features = p_custom_features; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_custom_features() const { + return custom_features; +} + +void EditorExportPreset::set_enc_in_filter(const String &p_filter) { + enc_in_filters = p_filter; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_enc_in_filter() const { + return enc_in_filters; +} + +void EditorExportPreset::set_enc_ex_filter(const String &p_filter) { + enc_ex_filters = p_filter; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_enc_ex_filter() const { + return enc_ex_filters; +} + +void EditorExportPreset::set_enc_pck(bool p_enabled) { + enc_pck = p_enabled; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::get_enc_pck() const { + return enc_pck; +} + +void EditorExportPreset::set_enc_directory(bool p_enabled) { + enc_directory = p_enabled; + EditorExport::singleton->save_presets(); +} + +bool EditorExportPreset::get_enc_directory() const { + return enc_directory; +} + +void EditorExportPreset::set_script_export_mode(int p_mode) { + script_mode = p_mode; + EditorExport::singleton->save_presets(); +} + +int EditorExportPreset::get_script_export_mode() const { + return script_mode; +} + +void EditorExportPreset::set_script_encryption_key(const String &p_key) { + script_key = p_key; + EditorExport::singleton->save_presets(); +} + +String EditorExportPreset::get_script_encryption_key() const { + return script_key; +} + +EditorExportPreset::EditorExportPreset() {} diff --git a/editor/export/editor_export_preset.h b/editor/export/editor_export_preset.h new file mode 100644 index 0000000000..00109396b0 --- /dev/null +++ b/editor/export/editor_export_preset.h @@ -0,0 +1,145 @@ +/*************************************************************************/ +/* editor_export_preset.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 EDITOR_EXPORT_PRESET_H +#define EDITOR_EXPORT_PRESET_H + +class EditorExportPlatform; + +#include "core/object/ref_counted.h" + +class EditorExportPreset : public RefCounted { + GDCLASS(EditorExportPreset, RefCounted); + +public: + enum ExportFilter { + EXPORT_ALL_RESOURCES, + EXPORT_SELECTED_SCENES, + EXPORT_SELECTED_RESOURCES, + EXCLUDE_SELECTED_RESOURCES, + }; + + enum ScriptExportMode { + MODE_SCRIPT_TEXT, + MODE_SCRIPT_COMPILED, + }; + +private: + Ref<EditorExportPlatform> platform; + ExportFilter export_filter = EXPORT_ALL_RESOURCES; + String include_filter; + String exclude_filter; + String export_path; + + String exporter; + HashSet<String> selected_files; + bool runnable = false; + + friend class EditorExport; + friend class EditorExportPlatform; + + List<PropertyInfo> properties; + HashMap<StringName, Variant> values; + + String name; + + String custom_features; + + String enc_in_filters; + String enc_ex_filters; + bool enc_pck = false; + bool enc_directory = false; + + int script_mode = MODE_SCRIPT_COMPILED; + String script_key; + +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; + +public: + Ref<EditorExportPlatform> get_platform() const; + + bool has(const StringName &p_property) const { return values.has(p_property); } + + void update_files_to_export(); + + Vector<String> get_files_to_export() const; + + void add_export_file(const String &p_path); + void remove_export_file(const String &p_path); + bool has_export_file(const String &p_path); + + void set_name(const String &p_name); + String get_name() const; + + void set_runnable(bool p_enable); + bool is_runnable() const; + + void set_export_filter(ExportFilter p_filter); + ExportFilter get_export_filter() const; + + void set_include_filter(const String &p_include); + String get_include_filter() const; + + void set_exclude_filter(const String &p_exclude); + String get_exclude_filter() const; + + void set_custom_features(const String &p_custom_features); + String get_custom_features() const; + + void set_export_path(const String &p_path); + String get_export_path() const; + + void set_enc_in_filter(const String &p_filter); + String get_enc_in_filter() const; + + void set_enc_ex_filter(const String &p_filter); + String get_enc_ex_filter() const; + + void set_enc_pck(bool p_enabled); + bool get_enc_pck() const; + + void set_enc_directory(bool p_enabled); + bool get_enc_directory() const; + + void set_script_export_mode(int p_mode); + int get_script_export_mode() const; + + void set_script_encryption_key(const String &p_key); + String get_script_encryption_key() const; + + const List<PropertyInfo> &get_properties() const { return properties; } + + EditorExportPreset(); +}; + +#endif // EDITOR_EXPORT_PRESET_H diff --git a/editor/export/editor_export_shared_object.h b/editor/export/editor_export_shared_object.h new file mode 100644 index 0000000000..558f403ca1 --- /dev/null +++ b/editor/export/editor_export_shared_object.h @@ -0,0 +1,51 @@ +/*************************************************************************/ +/* editor_export_shared_object.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 EDITOR_EXPORT_SHARED_OBJECT_H +#define EDITOR_EXPORT_SHARED_OBJECT_H + +#include "core/string/ustring.h" +#include "core/templates/vector.h" + +struct SharedObject { + String path; + Vector<String> tags; + String target; + + SharedObject(const String &p_path, const Vector<String> &p_tags, const String &p_target) : + path(p_path), + tags(p_tags), + target(p_target) { + } + + SharedObject() {} +}; + +#endif // EDITOR_EXPORT_SHARED_OBJECT_H diff --git a/editor/export_template_manager.cpp b/editor/export/export_template_manager.cpp index af9c918360..e02066e956 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export/export_template_manager.cpp @@ -30,23 +30,22 @@ #include "export_template_manager.h" -#include "core/input/input.h" #include "core/io/dir_access.h" #include "core/io/json.h" #include "core/io/zip_io.h" -#include "core/os/keyboard.h" -#include "core/templates/rb_set.h" #include "core/version.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" -#include "progress_dialog.h" -#include "scene/gui/link_button.h" +#include "editor/progress_dialog.h" +#include "scene/gui/file_dialog.h" +#include "scene/gui/tree.h" +#include "scene/main/http_request.h" void ExportTemplateManager::_update_template_status() { // Fetch installed templates from the file system. Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir(); + const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir(); Error err = da->change_dir(templates_dir); ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'."); @@ -439,7 +438,7 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_ } Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(version); + String template_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(version); Error err = d->make_dir_recursive(template_path); if (err != OK) { EditorNode::get_singleton()->show_warning(TTR("Error creating path for extracting templates:") + "\n" + template_path); @@ -538,7 +537,7 @@ void ExportTemplateManager::_uninstall_template(const String &p_version) { void ExportTemplateManager::_uninstall_template_confirmed() { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir(); + const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir(); Error err = da->change_dir(templates_dir); ERR_FAIL_COND_MSG(err != OK, "Could not access templates directory at '" + templates_dir + "'."); @@ -616,7 +615,7 @@ void ExportTemplateManager::_installed_table_button_cbk(Object *p_item, int p_co } void ExportTemplateManager::_open_template_folder(const String &p_version) { - const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir(); + const String &templates_dir = EditorSettings::get_singleton()->get_export_templates_dir(); OS::get_singleton()->shell_open("file://" + templates_dir.plus_file(p_version)); } @@ -640,12 +639,12 @@ void ExportTemplateManager::_hide_dialog() { } bool ExportTemplateManager::can_install_android_template() { - const String templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG); + const String templates_dir = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); return FileAccess::exists(templates_dir.plus_file("android_source.zip")); } Error ExportTemplateManager::install_android_template() { - const String &templates_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG); + const String &templates_path = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); const String &source_zip = templates_path.plus_file("android_source.zip"); ERR_FAIL_COND_V(!FileAccess::exists(source_zip), ERR_CANT_OPEN); return install_android_template_from_file(source_zip); diff --git a/editor/export_template_manager.h b/editor/export/export_template_manager.h index 3494e11d5e..f01da15832 100644 --- a/editor/export_template_manager.h +++ b/editor/export/export_template_manager.h @@ -31,15 +31,15 @@ #ifndef EXPORT_TEMPLATE_MANAGER_H #define EXPORT_TEMPLATE_MANAGER_H -#include "editor/editor_settings.h" #include "scene/gui/dialogs.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/progress_bar.h" -#include "scene/gui/scroll_container.h" -#include "scene/main/http_request.h" class ExportTemplateVersion; +class FileDialog; +class HTTPRequest; +class MenuButton; +class OptionButton; +class ProgressBar; +class Tree; class ExportTemplateManager : public AcceptDialog { GDCLASS(ExportTemplateManager, AcceptDialog); diff --git a/editor/project_export.cpp b/editor/export/project_export.cpp index 209c997d58..a20f19efc8 100644 --- a/editor/project_export.cpp +++ b/editor/export/project_export.cpp @@ -31,23 +31,15 @@ #include "project_export.h" #include "core/config/project_settings.h" -#include "core/io/dir_access.h" -#include "core/io/file_access.h" -#include "core/io/image_loader.h" -#include "core/io/resource_loader.h" -#include "core/io/resource_saver.h" -#include "core/os/os.h" -#include "core/string/optimized_translation.h" -#include "core/version_generated.gen.h" +#include "core/version.h" #include "editor/editor_file_dialog.h" +#include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "editor/editor_properties.h" #include "editor/editor_scale.h" -#include "editor/editor_settings.h" -#include "scene/gui/box_container.h" -#include "scene/gui/margin_container.h" -#include "scene/gui/scroll_container.h" -#include "scene/gui/tab_container.h" -#include "servers/display_server.h" +#include "editor/export/editor_export.h" +#include "scene/gui/link_button.h" +#include "scene/gui/tree.h" void ProjectExportDialog::_theme_changed() { duplicate_preset->set_icon(presets->get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons"))); diff --git a/editor/project_export.h b/editor/export/project_export.h index 6b10642495..96dd765a2c 100644 --- a/editor/project_export.h +++ b/editor/export/project_export.h @@ -28,31 +28,25 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PROJECT_EXPORT_SETTINGS_H -#define PROJECT_EXPORT_SETTINGS_H - -#include "core/io/dir_access.h" -#include "core/os/thread.h" -#include "editor/editor_export.h" -#include "editor/editor_file_system.h" -#include "editor/editor_inspector.h" -#include "editor/editor_properties.h" -#include "scene/gui/button.h" -#include "scene/gui/check_button.h" -#include "scene/gui/control.h" +#ifndef PROJECT_EXPORT_H +#define PROJECT_EXPORT_H + #include "scene/gui/dialogs.h" -#include "scene/gui/file_dialog.h" -#include "scene/gui/label.h" -#include "scene/gui/link_button.h" -#include "scene/gui/menu_button.h" -#include "scene/gui/option_button.h" -#include "scene/gui/rich_text_label.h" -#include "scene/gui/slider.h" -#include "scene/gui/tab_container.h" -#include "scene/gui/tree.h" -#include "scene/main/timer.h" +class CheckBox; +class CheckButton; +class EditorExportPreset; class EditorFileDialog; +class EditorFileSystemDirectory; +class EditorInspector; +class EditorPropertyPath; +class ItemList; +class MenuButton; +class OptionButton; +class RichTextLabel; +class TabContainer; +class Tree; +class TreeItem; class ProjectExportDialog : public ConfirmationDialog { GDCLASS(ProjectExportDialog, ConfirmationDialog); @@ -183,4 +177,4 @@ public: ~ProjectExportDialog(); }; -#endif // PROJECT_EXPORT_SETTINGS_H +#endif // PROJECT_EXPORT_H diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index fe6e6044a4..e025cedf02 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -985,7 +985,9 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit } } - if (ResourceLoader::get_resource_type(fpath) == "PackedScene") { + String resource_type = ResourceLoader::get_resource_type(fpath); + + if (resource_type == "PackedScene") { bool is_imported = false; { @@ -1005,7 +1007,7 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit } else { EditorNode::get_singleton()->open_request(fpath); } - } else if (ResourceLoader::get_resource_type(fpath) == "AnimationLibrary") { + } else if (resource_type == "AnimationLibrary") { bool is_imported = false; { @@ -1025,6 +1027,25 @@ void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorit } else { EditorNode::get_singleton()->open_request(fpath); } + } else if (ResourceLoader::is_imported(fpath)) { + // If the importer has advanced settings, show them. + int order; + bool can_threads; + String name; + Error err = ResourceFormatImporter::get_singleton()->get_import_order_threads_and_importer(fpath, order, can_threads, name); + bool used_advanced_settings = false; + if (err == OK) { + Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(name); + if (importer.is_valid() && importer->has_advanced_options()) { + importer->show_advanced_options(fpath); + used_advanced_settings = true; + } + } + + if (!used_advanced_settings) { + EditorNode::get_singleton()->load_resource(fpath); + } + } else { EditorNode::get_singleton()->load_resource(fpath); } @@ -2034,6 +2055,10 @@ void FileSystemDock::_resource_created() { make_shader_dialog->config(fpath.plus_file("new_shader"), false, false, 1); make_shader_dialog->popup_centered(); return; + } else if (type_name == "ShaderInclude") { + make_shader_dialog->config(fpath.plus_file("new_shader_include"), false, false, 2); + make_shader_dialog->popup_centered(); + return; } Variant c = new_resource_dialog->instance_selected(); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index f73e076ac0..c38b3f8a47 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -342,4 +342,4 @@ public: ~FileSystemDock(); }; -#endif // SCENES_DOCK_H +#endif // FILESYSTEM_DOCK_H diff --git a/editor/groups_editor.h b/editor/groups_editor.h index 75cbfd01a4..fec8913e31 100644 --- a/editor/groups_editor.h +++ b/editor/groups_editor.h @@ -144,4 +144,4 @@ public: ~GroupsEditor(); }; -#endif +#endif // GROUPS_EDITOR_H diff --git a/editor/icons/AudioStreamOGGVorbis.svg b/editor/icons/AudioStreamOggVorbis.svg index 2e54de9faa..2e54de9faa 100644 --- a/editor/icons/AudioStreamOGGVorbis.svg +++ b/editor/icons/AudioStreamOggVorbis.svg diff --git a/editor/icons/AudioStreamSample.svg b/editor/icons/AudioStreamWAV.svg index 2e54de9faa..2e54de9faa 100644 --- a/editor/icons/AudioStreamSample.svg +++ b/editor/icons/AudioStreamWAV.svg diff --git a/editor/icons/CodeFoldDownArrow.svg b/editor/icons/CodeFoldDownArrow.svg new file mode 100644 index 0000000000..0024a1256b --- /dev/null +++ b/editor/icons/CodeFoldDownArrow.svg @@ -0,0 +1 @@ +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="m3 5 3 3 3-3" fill="none" stroke="#fff" stroke-width="2"/></svg> diff --git a/editor/icons/CodeFoldedRightArrow.svg b/editor/icons/CodeFoldedRightArrow.svg new file mode 100644 index 0000000000..f2a4bd44e0 --- /dev/null +++ b/editor/icons/CodeFoldedRightArrow.svg @@ -0,0 +1 @@ +<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="m4 9 3-3-3-3" fill="none" stroke="#fff" stroke-width="2"/></svg> diff --git a/editor/icons/FontFile.svg b/editor/icons/FontFile.svg index 4b94fd0d74..c014299783 100644 --- a/editor/icons/FontFile.svg +++ b/editor/icons/FontFile.svg @@ -1 +1 @@ -<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1.5 1v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V3h2a1 1 0 0 1 1 1h1V1h-6Z" fill="#e0e0e0"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6Z" fill="#ff5f5f"/></svg> +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M7.5 7.5h-1a.519.519 0 0 0-.281.084A.491.491 0 0 0 6 8v.5h-.5V9a1 1 0 0 1-1 1v1H8V9.854A1 1 0 0 1 7.5 9V7.5zM1.5 1v3h1a1 1 0 0 1 1-1h2v1.5h2V3h2a1 1 0 0 1 1 1h1V1h-10z" style="fill:#e0e0e0;fill-opacity:1"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/FontVariation.svg b/editor/icons/FontVariation.svg index eaad049fce..39917bcba9 100644 --- a/editor/icons/FontVariation.svg +++ b/editor/icons/FontVariation.svg @@ -1 +1 @@ -<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M2.437 1 1.379 4h1A.84 1.192 50 0 1 3.73 3h2L3.615 9a.84 1.192 50 0 1-1.352 1l-.353 1h4l.353-1a.84 1.192 50 0 1-.648-1l2.116-6h2a.84 1.192 50 0 1 .648 1h1l1.058-3h-6Z" fill="#e0e0e0"/><path d="m4.621 5-.705 2-.353 1h1a.84 1.192 49.998 0 1 1.353-1h2L5.8 13a.84 1.192 49.998 0 1-1.353 1l-.353 1h4l.353-1a.84 1.192 49.998 0 1-.647-1l2.116-6h2a.84 1.192 49.998 0 1 .647 1h1l.353-1 .705-2h-6Z" fill="#ff5f5f"/></svg> +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M5.975 11 7.21 7.5H5.916a.478.478 0 0 0-.113.016.837.837 0 0 0-.127.043c-.044.018-.089.04-.133.066l-.043.027V9a1 1 0 0 1-1 1v1h1.475zM1.5 1v3h1a1 1 0 0 1 1-1h2v1.5h2V3h2a1 1 0 0 1 1 1h1V1h-10z" style="fill:#e0e0e0;fill-opacity:1"/><path d="m4.621 5-.705 2-.353 1h1a.84 1.192 49.998 0 1 1.353-1h2L5.8 13a.84 1.192 49.998 0 1-1.353 1l-.353 1h4l.353-1a.84 1.192 49.998 0 1-.647-1l2.116-6h2a.84 1.192 49.998 0 1 .647 1h1l.353-1 .705-2h-6z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/LabelSettings.svg b/editor/icons/LabelSettings.svg new file mode 100644 index 0000000000..4dc3b9e86e --- /dev/null +++ b/editor/icons/LabelSettings.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="M6 3a1 1 0 0 0-.707.293l-4 4a1 1 0 0 0 0 1.414l4 4A1 1 0 0 0 6 13h2.076a3.766 3.766 0 0 1-.058-.496c-.003-.058-.006-.115-.006-.174a2.606 2.606 0 0 1 .05-.508 3.212 3.212 0 0 1 .133-.496 5.104 5.104 0 0 1 .451-.982 8.303 8.303 0 0 1 .422-.656 14.41 14.41 0 0 1 .489-.667c.172-.223.351-.45.535-.68.163-.203.327-.408.492-.618a27.639 27.639 0 0 0 .732-.977 16.04 16.04 0 0 0 .465-.697c.075-.12.147-.242.219-.365a12.399 12.399 0 0 0 .684 1.062 27.555 27.555 0 0 0 .73.977c.165.21.331.415.494.619a43.298 43.298 0 0 1 .787 1.013c.082.111.16.222.237.332L15 9.79V4a1 1 0 0 0-1-1H6zM5 7a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1z" style="fill:#8eef97;fill-opacity:1"/><path d="M9.184 13A2.99 2.99 0 0 0 12 15a2.99 2.99 0 0 0 2.816-2z" fill="#ff4596"/><path d="M9.23 11c-.136.326-.23.656-.23 1 0 .352.072.686.184 1h5.632c.112-.314.184-.648.184-1 0-.344-.094-.674-.23-1H9.23z" fill="#8045ff"/><path d="M10.564 9c-.552.69-1.058 1.342-1.334 2h5.54c-.276-.658-.782-1.31-1.335-2Z" fill="#45d7ff"/><path d="M12 7c-.43.746-.945 1.387-1.435 2h2.87c-.49-.613-1.005-1.254-1.435-2Z" fill="#45ffa2"/></svg> diff --git a/editor/icons/SystemFont.svg b/editor/icons/SystemFont.svg new file mode 100644 index 0000000000..a6f62d56d3 --- /dev/null +++ b/editor/icons/SystemFont.svg @@ -0,0 +1 @@ +<svg height="16" width="16" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path style="fill:#e0e0e0;fill-opacity:1;stroke-width:.714755" d="m5.787 1-.402 1.613c-.352.265-.71.122-1.012-.111l-.904-.541L2.46 2.973l.853 1.425c-.058.438-.412.586-.79.635-.343.065-.674.216-1.024.213V6.72c.367 0 .715.157 1.074.224.371.032.716.243.727.65l-.84 1.4 1.008 1.01c.443-.266.895-.53 1.33-.802.349-.044.675.139.674.506l.314 1.258c.459-.059 1.099.115 1.45-.082.117-.475.242-.954.35-1.428A.67.67 0 0 1 8 9.195V7.5H6.5a.519.519 0 0 0-.281.084A.491.491 0 0 0 6 8v.5H4v-4h5.75c-.005-.22.107-.434.254-.625l.543-.902L9.535 1.96l-1.426.853c-.437-.058-.588-.412-.636-.79L7.217 1h-1.43z"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/TextEditorPlay.svg b/editor/icons/TextEditorPlay.svg new file mode 100644 index 0000000000..5a1d195530 --- /dev/null +++ b/editor/icons/TextEditorPlay.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 1048.4v-8l7 4z" fill="#e0e0e0" fill-rule="evenodd" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg> diff --git a/editor/import/audio_stream_import_settings.cpp b/editor/import/audio_stream_import_settings.cpp new file mode 100644 index 0000000000..f3709efab6 --- /dev/null +++ b/editor/import/audio_stream_import_settings.cpp @@ -0,0 +1,650 @@ +/*************************************************************************/ +/* audio_stream_import_settings.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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_stream_import_settings.h" +#include "editor/audio_stream_preview.h" +#include "editor/editor_file_system.h" +#include "editor/editor_scale.h" + +AudioStreamImportSettings *AudioStreamImportSettings::singleton = nullptr; + +void AudioStreamImportSettings::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_READY: { + AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", callable_mp(this, &AudioStreamImportSettings::_preview_changed)); + connect("confirmed", callable_mp(this, &AudioStreamImportSettings::_reimport)); + } break; + + case NOTIFICATION_THEME_CHANGED: + case NOTIFICATION_ENTER_TREE: { + _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); + _stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); + _preview->set_color(get_theme_color(SNAME("dark_color_2"), SNAME("Editor"))); + color_rect->set_color(get_theme_color(SNAME("dark_color_1"), SNAME("Editor"))); + _current_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + _current_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + _duration_label->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); + _duration_label->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); + + zoom_in->set_icon(get_theme_icon(SNAME("ZoomMore"), SNAME("EditorIcons"))); + zoom_out->set_icon(get_theme_icon(SNAME("ZoomLess"), SNAME("EditorIcons"))); + zoom_reset->set_icon(get_theme_icon(SNAME("ZoomReset"), SNAME("EditorIcons"))); + + _indicator->update(); + _preview->update(); + } break; + + case NOTIFICATION_PROCESS: { + _current = _player->get_playback_position(); + _indicator->update(); + } break; + + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible()) { + _stop(); + } + } break; + } +} + +void AudioStreamImportSettings::_draw_preview() { + Rect2 rect = _preview->get_rect(); + Size2 size = rect.size; + + Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream); + float preview_offset = zoom_bar->get_value(); + float preview_len = zoom_bar->get_page(); + + Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts")); + int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")); + Vector<Vector2> lines; + lines.resize(size.width * 2); + Color color_active = get_theme_color(SNAME("contrast_color_2"), SNAME("Editor")); + Color color_inactive = color_active; + color_inactive.a *= 0.5; + Vector<Color> color; + color.resize(lines.size()); + + float inactive_from = 1e20; + float beat_size = 0; + int last_beat = 0; + if (stream->get_bpm() > 0) { + beat_size = 60 / float(stream->get_bpm()); + int y_ofs = beat_font->get_height(main_size) + 4 * EDSCALE; + rect.position.y += y_ofs; + rect.size.y -= y_ofs; + + if (stream->get_beat_count() > 0) { + last_beat = stream->get_beat_count(); + inactive_from = last_beat * beat_size; + } + } + + for (int i = 0; i < size.width; i++) { + float ofs = preview_offset + i * preview_len / size.width; + float ofs_n = preview_offset + (i + 1) * preview_len / size.width; + float max = preview->get_max(ofs, ofs_n) * 0.5 + 0.5; + float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5; + + int idx = i; + lines.write[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y); + lines.write[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y); + + Color c = ofs > inactive_from ? color_inactive : color_active; + + color.write[idx * 2 + 0] = c; + color.write[idx * 2 + 1] = c; + } + + RS::get_singleton()->canvas_item_add_multiline(_preview->get_canvas_item(), lines, color); + + if (beat_size) { + Color beat_color = Color(1, 1, 1, 1); + Color final_beat_color = beat_color; + Color bar_color = beat_color; + beat_color.a *= 0.4; + bar_color.a *= 0.6; + + int prev_beat = 0; // Do not draw beat zero + Color color_bg = color_active; + color_bg.a *= 0.2; + _preview->draw_rect(Rect2(0, 0, rect.size.width, rect.position.y), color_bg); + int bar_beats = stream->get_bar_beats(); + + int last_text_end_x = 0; + for (int i = 0; i < size.width; i++) { + float ofs = preview_offset + i * preview_len / size.width; + int beat = int(ofs / beat_size); + if (beat != prev_beat) { + String text = itos(beat); + int text_w = beat_font->get_string_size(text).width; + if (i - text_w / 2 > last_text_end_x + 2 * EDSCALE) { + int x_ofs = i - text_w / 2; + _preview->draw_string(beat_font, Point2(x_ofs, 2 * EDSCALE + beat_font->get_ascent(main_size)), text, HORIZONTAL_ALIGNMENT_LEFT, rect.size.width - x_ofs, Font::DEFAULT_FONT_SIZE, color_active); + last_text_end_x = i + text_w / 2; + } + + if (beat == last_beat) { + _preview->draw_rect(Rect2i(i, rect.position.y, 2, rect.size.height), final_beat_color); + // Darken subsequent beats + beat_color.a *= 0.3; + color_active.a *= 0.3; + } else { + _preview->draw_rect(Rect2i(i, rect.position.y, 1, rect.size.height), (beat % bar_beats) == 0 ? bar_color : beat_color); + } + prev_beat = beat; + } + } + } +} + +void AudioStreamImportSettings::_preview_changed(ObjectID p_which) { + if (stream.is_valid() && stream->get_instance_id() == p_which) { + _preview->update(); + } +} + +void AudioStreamImportSettings::_preview_zoom_in() { + if (!stream.is_valid()) { + return; + } + float page_size = zoom_bar->get_page(); + zoom_bar->set_page(page_size * 0.5); + zoom_bar->set_value(zoom_bar->get_value() + page_size * 0.25); + + _preview->update(); + _indicator->update(); +} + +void AudioStreamImportSettings::_preview_zoom_out() { + if (!stream.is_valid()) { + return; + } + float page_size = zoom_bar->get_page(); + zoom_bar->set_page(MIN(zoom_bar->get_max(), page_size * 2.0)); + zoom_bar->set_value(zoom_bar->get_value() - page_size * 0.5); + + _preview->update(); + _indicator->update(); +} + +void AudioStreamImportSettings::_preview_zoom_reset() { + if (!stream.is_valid()) { + return; + } + zoom_bar->set_max(stream->get_length()); + zoom_bar->set_page(zoom_bar->get_max()); + zoom_bar->set_value(0); + _preview->update(); + _indicator->update(); +} + +void AudioStreamImportSettings::_preview_zoom_offset_changed(double) { + _preview->update(); + _indicator->update(); +} + +void AudioStreamImportSettings::_audio_changed() { + if (!is_visible()) { + return; + } + _preview->update(); + _indicator->update(); + color_rect->update(); +} + +void AudioStreamImportSettings::_play() { + if (_player->is_playing()) { + // '_pausing' variable indicates that we want to pause the audio player, not stop it. See '_on_finished()'. + _pausing = true; + _player->stop(); + _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); + set_process(false); + } else { + _player->play(_current); + _play_button->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons"))); + set_process(true); + } +} + +void AudioStreamImportSettings::_stop() { + _player->stop(); + _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); + _current = 0; + _indicator->update(); + set_process(false); +} + +void AudioStreamImportSettings::_on_finished() { + _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); + if (!_pausing) { + _current = 0; + _indicator->update(); + } else { + _pausing = false; + } + set_process(false); +} + +void AudioStreamImportSettings::_draw_indicator() { + if (!stream.is_valid()) { + return; + } + + Rect2 rect = _preview->get_rect(); + + Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts")); + int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")); + + if (stream->get_bpm() > 0) { + int y_ofs = beat_font->get_height(main_size) + 4 * EDSCALE; + rect.position.y += y_ofs; + rect.size.height -= y_ofs; + } + + float ofs_x = (_current - zoom_bar->get_value()) * rect.size.width / zoom_bar->get_page(); + if (ofs_x < 0 || ofs_x >= rect.size.width) { + return; + } + + const Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); + _indicator->draw_line(Point2(ofs_x, rect.position.y), Point2(ofs_x, rect.position.y + rect.size.height), color, Math::round(2 * EDSCALE)); + _indicator->draw_texture( + get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons")), + Point2(ofs_x - get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons"))->get_width() * 0.5, rect.position.y), + color); + + if (stream->get_bpm() > 0 && _hovering_beat != -1) { + // Draw hovered beat. + float preview_offset = zoom_bar->get_value(); + float preview_len = zoom_bar->get_page(); + float beat_size = 60 / float(stream->get_bpm()); + int prev_beat = 0; + int last_text_end_x = 0; + for (int i = 0; i < rect.size.width; i++) { + float ofs = preview_offset + i * preview_len / rect.size.width; + int beat = int(ofs / beat_size); + if (beat != prev_beat) { + String text = itos(beat); + int text_w = beat_font->get_string_size(text).width; + if (i - text_w / 2 > last_text_end_x + 2 * EDSCALE && beat == _hovering_beat) { + int x_ofs = i - text_w / 2; + _indicator->draw_string(beat_font, Point2(x_ofs, 2 * EDSCALE + beat_font->get_ascent(main_size)), text, HORIZONTAL_ALIGNMENT_LEFT, rect.size.width - x_ofs, Font::DEFAULT_FONT_SIZE, color); + last_text_end_x = i + text_w / 2; + break; + } + prev_beat = beat; + } + } + } + + _current_label->set_text(String::num(_current, 2).pad_decimals(2) + " /"); +} + +void AudioStreamImportSettings::_on_indicator_mouse_exited() { + _hovering_beat = -1; + _indicator->update(); +} + +void AudioStreamImportSettings::_on_input_indicator(Ref<InputEvent> p_event) { + const Ref<InputEventMouseButton> mb = p_event; + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) { + if (stream->get_bpm() > 0) { + int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")); + Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts")); + int y_ofs = beat_font->get_height(main_size) + 4 * EDSCALE; + if ((!_dragging && mb->get_position().y < y_ofs) || _beat_len_dragging) { + if (mb->is_pressed()) { + _set_beat_len_to(mb->get_position().x); + _beat_len_dragging = true; + } else { + _beat_len_dragging = false; + } + return; + } + } + + if (mb->is_pressed()) { + _seek_to(mb->get_position().x); + } + _dragging = mb->is_pressed(); + } + + const Ref<InputEventMouseMotion> mm = p_event; + if (mm.is_valid()) { + if (_dragging) { + _seek_to(mm->get_position().x); + } + if (_beat_len_dragging) { + _set_beat_len_to(mm->get_position().x); + } + if (stream->get_bpm() > 0) { + int main_size = get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts")); + Ref<Font> beat_font = get_theme_font(SNAME("main"), SNAME("EditorFonts")); + int y_ofs = beat_font->get_height(main_size) + 4 * EDSCALE; + if (mm->get_position().y < y_ofs) { + int new_hovering_beat = _get_beat_at_pos(mm->get_position().x); + if (new_hovering_beat != _hovering_beat) { + _hovering_beat = new_hovering_beat; + _indicator->update(); + } + } else if (_hovering_beat != -1) { + _hovering_beat = -1; + _indicator->update(); + } + } + } +} + +int AudioStreamImportSettings::_get_beat_at_pos(real_t p_x) { + float ofs_sec = zoom_bar->get_value() + p_x * zoom_bar->get_page() / _preview->get_size().width; + ofs_sec = CLAMP(ofs_sec, 0, stream->get_length()); + float beat_size = 60 / float(stream->get_bpm()); + int beat = int(ofs_sec / beat_size + 0.5); + + if (beat * beat_size > stream->get_length() + 0.001) { // Stream may end few audio frames before but may still want to use full loop. + beat--; + } + return beat; +} + +void AudioStreamImportSettings::_set_beat_len_to(real_t p_x) { + int beat = _get_beat_at_pos(p_x); + if (beat < 1) { + beat = 1; // Because 0 is disable. + } + updating_settings = true; + beats_enabled->set_pressed(true); + beats_edit->set_value(beat); + updating_settings = false; + _settings_changed(); +} + +void AudioStreamImportSettings::_seek_to(real_t p_x) { + _current = zoom_bar->get_value() + p_x / _preview->get_rect().size.x * zoom_bar->get_page(); + _current = CLAMP(_current, 0, stream->get_length()); + _player->seek(_current); + _indicator->update(); +} + +void AudioStreamImportSettings::edit(const String &p_path, const String &p_importer, const Ref<AudioStream> &p_stream) { + if (!stream.is_null()) { + stream->disconnect("changed", callable_mp(this, &AudioStreamImportSettings::_audio_changed)); + } + + importer = p_importer; + path = p_path; + + stream = p_stream; + _player->set_stream(stream); + _current = 0; + String text = String::num(stream->get_length(), 2).pad_decimals(2) + "s"; + _duration_label->set_text(text); + + if (!stream.is_null()) { + stream->connect("changed", callable_mp(this, &AudioStreamImportSettings::_audio_changed)); + _preview->update(); + _indicator->update(); + color_rect->update(); + } else { + hide(); + } + params.clear(); + + if (stream.is_valid()) { + Ref<ConfigFile> config_file; + config_file.instantiate(); + Error err = config_file->load(p_path + ".import"); + updating_settings = true; + if (err == OK) { + double bpm = config_file->get_value("params", "bpm", 0); + int beats = config_file->get_value("params", "beat_count", 0); + bpm_edit->set_value(bpm > 0 ? bpm : 120); + bpm_enabled->set_pressed(bpm > 0); + beats_edit->set_value(beats); + beats_enabled->set_pressed(beats > 0); + loop->set_pressed(config_file->get_value("params", "loop", false)); + loop_offset->set_value(config_file->get_value("params", "loop_offset", 0)); + bar_beats_edit->set_value(config_file->get_value("params", "bar_beats", 4)); + + List<String> keys; + config_file->get_section_keys("params", &keys); + for (const String &K : keys) { + params[K] = config_file->get_value("params", K); + } + } else { + bpm_edit->set_value(false); + bpm_enabled->set_pressed(false); + beats_edit->set_value(0); + beats_enabled->set_pressed(false); + bar_beats_edit->set_value(4); + loop->set_pressed(false); + loop_offset->set_value(0); + } + + _preview_zoom_reset(); + updating_settings = false; + _settings_changed(); + + set_title(vformat(TTR("Audio Stream Importer: %s"), p_path.get_file())); + popup_centered(); + } +} + +void AudioStreamImportSettings::_settings_changed() { + if (updating_settings) { + return; + } + + updating_settings = true; + stream->call("set_loop", loop->is_pressed()); + stream->call("set_loop_offset", loop_offset->get_value()); + if (bpm_enabled->is_pressed()) { + stream->call("set_bpm", bpm_edit->get_value()); + beats_enabled->show(); + beats_edit->show(); + bar_beats_label->show(); + bar_beats_edit->show(); + double bpm = bpm_edit->get_value(); + if (bpm > 0) { + float beat_size = 60 / float(bpm); + int beat_max = int((stream->get_length() + 0.001) / beat_size); + int current_beat = beats_edit->get_value(); + beats_edit->set_max(beat_max); + if (current_beat > beat_max) { + beats_edit->set_value(beat_max); + stream->call("set_beat_count", beat_max); + } + } + stream->call("set_bar_beats", bar_beats_edit->get_value()); + } else { + stream->call("set_bpm", 0); + stream->call("set_bar_beats", 4); + beats_enabled->hide(); + beats_edit->hide(); + bar_beats_label->hide(); + bar_beats_edit->hide(); + } + if (bpm_enabled->is_pressed() && beats_enabled->is_pressed()) { + stream->call("set_beat_count", beats_edit->get_value()); + } else { + stream->call("set_beat_count", 0); + } + + updating_settings = false; + + _preview->update(); + _indicator->update(); + color_rect->update(); +} + +void AudioStreamImportSettings::_reimport() { + params["loop"] = loop->is_pressed(); + params["loop_offset"] = loop_offset->get_value(); + params["bpm"] = bpm_enabled->is_pressed() ? double(bpm_edit->get_value()) : double(0); + params["beat_count"] = (bpm_enabled->is_pressed() && beats_enabled->is_pressed()) ? int(beats_edit->get_value()) : int(0); + params["bar_beats"] = (bpm_enabled->is_pressed()) ? int(bar_beats_edit->get_value()) : int(4); + + EditorFileSystem::get_singleton()->reimport_file_with_custom_parameters(path, importer, params); +} + +AudioStreamImportSettings::AudioStreamImportSettings() { + get_ok_button()->set_text(TTR("Reimport")); + get_cancel_button()->set_text(TTR("Close")); + + VBoxContainer *main_vbox = memnew(VBoxContainer); + add_child(main_vbox); + + HBoxContainer *loop_hb = memnew(HBoxContainer); + loop_hb->add_theme_constant_override("separation", 4 * EDSCALE); + loop = memnew(CheckBox); + loop->set_text(TTR("Enable")); + loop->set_tooltip(TTR("Enable looping.")); + loop->connect("toggled", callable_mp(this, &AudioStreamImportSettings::_settings_changed).unbind(1)); + loop_hb->add_child(loop); + loop_hb->add_spacer(); + loop_hb->add_child(memnew(Label(TTR("Offset:")))); + loop_offset = memnew(SpinBox); + loop_offset->set_max(10000); + loop_offset->set_step(0.001); + loop_offset->set_suffix("sec"); + loop_offset->set_tooltip(TTR("Loop offset (from beginning). Note that if BPM is set, this setting will be ignored.")); + loop_offset->connect("value_changed", callable_mp(this, &AudioStreamImportSettings::_settings_changed).unbind(1)); + loop_hb->add_child(loop_offset); + main_vbox->add_margin_child(TTR("Loop:"), loop_hb); + + HBoxContainer *interactive_hb = memnew(HBoxContainer); + interactive_hb->add_theme_constant_override("separation", 4 * EDSCALE); + bpm_enabled = memnew(CheckBox); + bpm_enabled->set_text((TTR("BPM:"))); + bpm_enabled->connect("toggled", callable_mp(this, &AudioStreamImportSettings::_settings_changed).unbind(1)); + interactive_hb->add_child(bpm_enabled); + bpm_edit = memnew(SpinBox); + bpm_edit->set_max(400); + bpm_edit->set_step(0.01); + bpm_edit->set_tooltip(TTR("Configure the Beats Per Measure (tempo) used for the interactive streams.\nThis is required in order to configure beat information.")); + bpm_edit->connect("value_changed", callable_mp(this, &AudioStreamImportSettings::_settings_changed).unbind(1)); + interactive_hb->add_child(bpm_edit); + interactive_hb->add_spacer(); + bar_beats_label = memnew(Label(TTR("Beats/Bar:"))); + interactive_hb->add_child(bar_beats_label); + bar_beats_edit = memnew(SpinBox); + bar_beats_edit->set_tooltip(TTR("Configure the Beats Per Bar. This used for music-aware transitions between AudioStreams.")); + bar_beats_edit->set_min(2); + bar_beats_edit->set_max(32); + bar_beats_edit->connect("value_changed", callable_mp(this, &AudioStreamImportSettings::_settings_changed).unbind(1)); + interactive_hb->add_child(bar_beats_edit); + interactive_hb->add_spacer(); + beats_enabled = memnew(CheckBox); + beats_enabled->set_text(TTR("Length (in beats):")); + beats_enabled->connect("toggled", callable_mp(this, &AudioStreamImportSettings::_settings_changed).unbind(1)); + interactive_hb->add_child(beats_enabled); + beats_edit = memnew(SpinBox); + beats_edit->set_tooltip(TTR("Configure the amount of Beats used for music-aware looping. If zero, it will be autodetected from the length.\nIt is recommended to set this value (either manually or by clicking on a beat number in the preview) to ensure looping works properly.")); + beats_edit->set_max(99999); + beats_edit->connect("value_changed", callable_mp(this, &AudioStreamImportSettings::_settings_changed).unbind(1)); + interactive_hb->add_child(beats_edit); + main_vbox->add_margin_child(TTR("Music Playback:"), interactive_hb); + + color_rect = memnew(ColorRect); + main_vbox->add_margin_child(TTR("Preview:"), color_rect); + + color_rect->set_custom_minimum_size(Size2(600, 200) * EDSCALE); + color_rect->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + _player = memnew(AudioStreamPlayer); + _player->connect("finished", callable_mp(this, &AudioStreamImportSettings::_on_finished)); + color_rect->add_child(_player); + + VBoxContainer *vbox = memnew(VBoxContainer); + vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 0); + color_rect->add_child(vbox); + vbox->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + _preview = memnew(ColorRect); + _preview->set_v_size_flags(Control::SIZE_EXPAND_FILL); + _preview->connect("draw", callable_mp(this, &AudioStreamImportSettings::_draw_preview)); + _preview->set_v_size_flags(Control::SIZE_EXPAND_FILL); + vbox->add_child(_preview); + + HBoxContainer *zoom_hbox = memnew(HBoxContainer); + zoom_bar = memnew(HScrollBar); + zoom_in = memnew(Button); + zoom_in->set_flat(true); + zoom_reset = memnew(Button); + zoom_reset->set_flat(true); + zoom_out = memnew(Button); + zoom_out->set_flat(true); + zoom_hbox->add_child(zoom_bar); + zoom_bar->set_h_size_flags(Control::SIZE_EXPAND_FILL); + zoom_bar->set_v_size_flags(Control::SIZE_EXPAND_FILL); + zoom_hbox->add_child(zoom_out); + zoom_hbox->add_child(zoom_reset); + zoom_hbox->add_child(zoom_in); + zoom_in->connect("pressed", callable_mp(this, &AudioStreamImportSettings::_preview_zoom_in)); + zoom_reset->connect("pressed", callable_mp(this, &AudioStreamImportSettings::_preview_zoom_reset)); + zoom_out->connect("pressed", callable_mp(this, &AudioStreamImportSettings::_preview_zoom_out)); + zoom_bar->connect("value_changed", callable_mp(this, &AudioStreamImportSettings::_preview_zoom_offset_changed)); + vbox->add_child(zoom_hbox); + + _indicator = memnew(Control); + _indicator->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); + _indicator->connect("draw", callable_mp(this, &AudioStreamImportSettings::_draw_indicator)); + _indicator->connect("gui_input", callable_mp(this, &AudioStreamImportSettings::_on_input_indicator)); + _indicator->connect("mouse_exited", callable_mp(this, &AudioStreamImportSettings::_on_indicator_mouse_exited)); + _preview->add_child(_indicator); + + HBoxContainer *hbox = memnew(HBoxContainer); + hbox->add_theme_constant_override("separation", 0); + vbox->add_child(hbox); + + _play_button = memnew(Button); + _play_button->set_flat(true); + hbox->add_child(_play_button); + _play_button->set_focus_mode(Control::FOCUS_NONE); + _play_button->connect("pressed", callable_mp(this, &AudioStreamImportSettings::_play)); + + _stop_button = memnew(Button); + _stop_button->set_flat(true); + hbox->add_child(_stop_button); + _stop_button->set_focus_mode(Control::FOCUS_NONE); + _stop_button->connect("pressed", callable_mp(this, &AudioStreamImportSettings::_stop)); + + _current_label = memnew(Label); + _current_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); + _current_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + _current_label->set_modulate(Color(1, 1, 1, 0.5)); + hbox->add_child(_current_label); + + _duration_label = memnew(Label); + hbox->add_child(_duration_label); + + singleton = this; +} diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/import/audio_stream_import_settings.h index 0d927bddd5..5e399237ca 100644 --- a/editor/plugins/audio_stream_editor_plugin.h +++ b/editor/import/audio_stream_import_settings.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_stream_editor_plugin.h */ +/* audio_stream_import_settings.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,27 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIO_STREAM_EDITOR_PLUGIN_H -#define AUDIO_STREAM_EDITOR_PLUGIN_H +#ifndef AUDIO_STREAM_IMPORT_SETTINGS_H +#define AUDIO_STREAM_IMPORT_SETTINGS_H #include "editor/editor_plugin.h" #include "scene/audio/audio_stream_player.h" #include "scene/gui/color_rect.h" +#include "scene/gui/spin_box.h" #include "scene/resources/texture.h" -class AudioStreamEditor : public ColorRect { - GDCLASS(AudioStreamEditor, ColorRect); +class AudioStreamImportSettings : public ConfirmationDialog { + GDCLASS(AudioStreamImportSettings, ConfirmationDialog); + CheckBox *bpm_enabled = nullptr; + SpinBox *bpm_edit = nullptr; + CheckBox *beats_enabled = nullptr; + SpinBox *beats_edit = nullptr; + Label *bar_beats_label = nullptr; + SpinBox *bar_beats_edit = nullptr; + CheckBox *loop = nullptr; + SpinBox *loop_offset = nullptr; + ColorRect *color_rect = nullptr; Ref<AudioStream> stream; AudioStreamPlayer *_player = nullptr; ColorRect *_preview = nullptr; @@ -46,18 +56,42 @@ class AudioStreamEditor : public ColorRect { Label *_current_label = nullptr; Label *_duration_label = nullptr; + HScrollBar *zoom_bar = nullptr; + Button *zoom_in = nullptr; + Button *zoom_reset = nullptr; + Button *zoom_out = nullptr; + Button *_play_button = nullptr; Button *_stop_button = nullptr; + bool updating_settings = false; + float _current = 0; bool _dragging = false; + bool _beat_len_dragging = false; bool _pausing = false; + int _hovering_beat = -1; + + HashMap<StringName, Variant> params; + String importer; + String path; void _audio_changed(); + static AudioStreamImportSettings *singleton; + + void _settings_changed(); + + void _reimport(); + protected: void _notification(int p_what); void _preview_changed(ObjectID p_which); + void _preview_zoom_in(); + void _preview_zoom_out(); + void _preview_zoom_reset(); + void _preview_zoom_offset_changed(double); + void _play(); void _stop(); void _on_finished(); @@ -65,27 +99,16 @@ protected: void _draw_indicator(); void _on_input_indicator(Ref<InputEvent> p_event); void _seek_to(real_t p_x); - static void _bind_methods(); + void _set_beat_len_to(real_t p_x); + void _on_indicator_mouse_exited(); + int _get_beat_at_pos(real_t p_x); public: - void edit(Ref<AudioStream> p_stream); - AudioStreamEditor(); -}; + void edit(const String &p_path, const String &p_importer, const Ref<AudioStream> &p_stream); -class AudioStreamEditorPlugin : public EditorPlugin { - GDCLASS(AudioStreamEditorPlugin, EditorPlugin); + static AudioStreamImportSettings *get_singleton() { return singleton; } - AudioStreamEditor *audio_editor = nullptr; - -public: - virtual String get_name() const override { return "Audio"; } - bool has_main_screen() const override { return false; } - virtual void edit(Object *p_object) override; - virtual bool handles(Object *p_object) const override; - virtual void make_visible(bool p_visible) override; - - AudioStreamEditorPlugin(); - ~AudioStreamEditorPlugin(); + AudioStreamImportSettings(); }; -#endif // AUDIO_STREAM_EDITOR_PLUGIN_H +#endif // AUDIO_STREAM_IMPORT_SETTINGS_H diff --git a/editor/import/dynamic_font_import_settings.cpp b/editor/import/dynamic_font_import_settings.cpp index ee13a1a9c1..043681aa87 100644 --- a/editor/import/dynamic_font_import_settings.cpp +++ b/editor/import/dynamic_font_import_settings.cpp @@ -971,6 +971,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) { base_path = p_path; inspector_vars->edit(nullptr); + inspector_text->edit(nullptr); inspector_general->edit(nullptr); text_settings_data.instantiate(); diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h index e45db47440..a75b0a903f 100644 --- a/editor/import/editor_import_collada.h +++ b/editor/import/editor_import_collada.h @@ -44,4 +44,4 @@ public: EditorSceneFormatImporterCollada(); }; -#endif +#endif // EDITOR_IMPORT_COLLADA_H diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index 44fbd41962..4548513b6f 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -68,4 +68,4 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = nullptr) override; }; -#endif //EDITOR_IMPORT_PLUGIN_H +#endif // EDITOR_IMPORT_PLUGIN_H diff --git a/editor/import/post_import_plugin_skeleton_renamer.cpp b/editor/import/post_import_plugin_skeleton_renamer.cpp index bf84348ac3..69c0a047e4 100644 --- a/editor/import/post_import_plugin_skeleton_renamer.cpp +++ b/editor/import/post_import_plugin_skeleton_renamer.cpp @@ -154,16 +154,28 @@ void PostImportPluginSkeletonRenamer::internal_process(InternalImportCategory p_ Ref<Animation> anim = ap->get_animation(name); int track_len = anim->get_track_count(); for (int i = 0; i < track_len; i++) { - if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { - continue; - } String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *orig_node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); - if (node) { + while (node) { Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); if (track_skeleton && track_skeleton == skeleton) { - anim->track_set_path(i, String("%") + unique_name + String(":") + anim->track_get_path(i).get_concatenated_subnames()); + if (node == orig_node) { + if (anim->track_get_path(i).get_subname_count() > 0) { + anim->track_set_path(i, UNIQUE_NODE_PREFIX + unique_name + String(":") + anim->track_get_path(i).get_concatenated_subnames()); + } else { + anim->track_set_path(i, UNIQUE_NODE_PREFIX + unique_name); + } + } else { + if (anim->track_get_path(i).get_subname_count() > 0) { + anim->track_set_path(i, UNIQUE_NODE_PREFIX + unique_name + "/" + node->get_path_to(orig_node) + String(":") + anim->track_get_path(i).get_concatenated_subnames()); + } else { + anim->track_set_path(i, UNIQUE_NODE_PREFIX + unique_name + "/" + node->get_path_to(orig_node)); + } + } + break; } + node = node->get_parent(); } } } diff --git a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp index 8b0d8c8729..4f00bd120a 100644 --- a/editor/import/post_import_plugin_skeleton_rest_fixer.cpp +++ b/editor/import/post_import_plugin_skeleton_rest_fixer.cpp @@ -34,11 +34,11 @@ #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/3d/skeleton_3d.h" #include "scene/animation/animation_player.h" -#include "scene/resources/animation.h" #include "scene/resources/bone_map.h" void PostImportPluginSkeletonRestFixer::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) { if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/normalize_position_tracks"), true)); r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/overwrite_axis"), true)); r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/rest_fixer/fix_silhouette/enable"), false)); @@ -89,7 +89,54 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory } } - // Complement Rotation track for compatibility between defference rests. + // Set motion scale to Skeleton if normalize position tracks. + if (bool(p_options["retarget/rest_fixer/normalize_position_tracks"])) { + int src_bone_idx = src_skeleton->find_bone(profile->get_scale_base_bone()); + if (src_bone_idx >= 0) { + real_t motion_scale = abs(src_skeleton->get_bone_global_rest(src_bone_idx).origin.y); + if (motion_scale > 0) { + src_skeleton->set_motion_scale(motion_scale); + } + } + + TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + int track_len = anim->get_track_count(); + for (int i = 0; i < track_len; i++) { + if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_POSITION_3D) { + continue; + } + + if (anim->track_is_compressed(i)) { + continue; // Shouldn't occur in internal_process(). + } + + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); + if (node) { + Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); + if (track_skeleton) { + if (track_skeleton && track_skeleton == src_skeleton) { + real_t mlt = 1 / src_skeleton->get_motion_scale(); + int key_len = anim->track_get_key_count(i); + for (int j = 0; j < key_len; j++) { + Vector3 pos = static_cast<Vector3>(anim->track_get_key_value(i, j)); + anim->track_set_key_value(i, j, pos * mlt); + } + } + } + } + } + } + } + } + + // Complement Rotation track for compatibility between different rests. { TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); while (nodes.size()) { @@ -100,7 +147,7 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory Ref<Animation> anim = ap->get_animation(name); int track_len = anim->get_track_count(); - // Detect does the animetion have skeleton's TRS track. + // Detect does the animation have skeleton's TRS track. String track_path; bool found_skeleton = false; for (int i = 0; i < track_len; i++) { @@ -357,12 +404,12 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory Ref<Animation> anim = ap->get_animation(name); int track_len = anim->get_track_count(); for (int i = 0; i < track_len; i++) { - if (anim->track_get_path(i).get_subname_count() != 1 || anim->track_get_type(i) != Animation::TYPE_ROTATION_3D) { + if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { continue; } if (anim->track_is_compressed(i)) { - continue; // TODO: Adopt to compressed track. + continue; // Shouldn't occur in internal_process(). } String track_path = String(anim->track_get_path(i).get_concatenated_names()); @@ -374,20 +421,44 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory if (bn) { int bone_idx = src_skeleton->find_bone(bn); - Quaternion old_rest = old_skeleton_rest[bone_idx].basis.get_rotation_quaternion(); - Quaternion new_rest = src_skeleton->get_bone_rest(bone_idx).basis.get_rotation_quaternion(); - Quaternion old_pg; - Quaternion new_pg; + Transform3D old_rest = old_skeleton_rest[bone_idx]; + Transform3D new_rest = src_skeleton->get_bone_rest(bone_idx); + Transform3D old_pg; + Transform3D new_pg; int parent_idx = src_skeleton->get_bone_parent(bone_idx); if (parent_idx >= 0) { - old_pg = old_skeleton_global_rest[parent_idx].basis.get_rotation_quaternion(); - new_pg = src_skeleton->get_bone_global_rest(parent_idx).basis.get_rotation_quaternion(); + old_pg = old_skeleton_global_rest[parent_idx]; + new_pg = src_skeleton->get_bone_global_rest(parent_idx); } int key_len = anim->track_get_key_count(i); - for (int j = 0; j < key_len; j++) { - Quaternion qt = static_cast<Quaternion>(anim->track_get_key_value(i, j)); - anim->track_set_key_value(i, j, new_pg.inverse() * old_pg * qt * old_rest.inverse() * old_pg.inverse() * new_pg * new_rest); + if (anim->track_get_type(i) == Animation::TYPE_ROTATION_3D) { + Quaternion old_rest_q = old_rest.basis.get_rotation_quaternion(); + Quaternion new_rest_q = new_rest.basis.get_rotation_quaternion(); + Quaternion old_pg_q = old_pg.basis.get_rotation_quaternion(); + Quaternion new_pg_q = new_pg.basis.get_rotation_quaternion(); + for (int j = 0; j < key_len; j++) { + Quaternion qt = static_cast<Quaternion>(anim->track_get_key_value(i, j)); + anim->track_set_key_value(i, j, new_pg_q.inverse() * old_pg_q * qt * old_rest_q.inverse() * old_pg_q.inverse() * new_pg_q * new_rest_q); + } + } else if (anim->track_get_type(i) == Animation::TYPE_SCALE_3D) { + Basis old_rest_b = old_rest.basis; + Basis new_rest_b = new_rest.basis; + Basis old_pg_b = old_pg.basis; + Basis new_pg_b = new_pg.basis; + for (int j = 0; j < key_len; j++) { + Basis sc = Basis().scaled(static_cast<Vector3>(anim->track_get_key_value(i, j))); + anim->track_set_key_value(i, j, (new_pg_b.inverse() * old_pg_b * sc * old_rest_b.inverse() * old_pg_b.inverse() * new_pg_b * new_rest_b).get_scale()); + } + } else { + Vector3 old_rest_o = old_rest.origin; + Vector3 new_rest_o = new_rest.origin; + Quaternion old_pg_q = old_pg.basis.get_rotation_quaternion(); + Quaternion new_pg_q = new_pg.basis.get_rotation_quaternion(); + for (int j = 0; j < key_len; j++) { + Vector3 ps = static_cast<Vector3>(anim->track_get_key_value(i, j)); + anim->track_set_key_value(i, j, new_pg_q.xform_inv(old_pg_q.xform(ps - old_rest_o)) + new_rest_o); + } } } } diff --git a/editor/import/post_import_plugin_skeleton_track_organizer.cpp b/editor/import/post_import_plugin_skeleton_track_organizer.cpp new file mode 100644 index 0000000000..01186f47fe --- /dev/null +++ b/editor/import/post_import_plugin_skeleton_track_organizer.cpp @@ -0,0 +1,127 @@ +/*************************************************************************/ +/* post_import_plugin_skeleton_track_organizer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "post_import_plugin_skeleton_track_organizer.h" + +#include "editor/import/scene_import_settings.h" +#include "scene/3d/skeleton_3d.h" +#include "scene/animation/animation_player.h" +#include "scene/resources/bone_map.h" + +void PostImportPluginSkeletonTrackOrganizer::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) { + if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/except_bone_transform"), false)); + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/unimportant_positions"), true)); + r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::BOOL, "retarget/remove_tracks/unmapped_bones"), false)); + } +} + +void PostImportPluginSkeletonTrackOrganizer::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) { + if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { + // Prepare objects. + Object *map = p_options["retarget/bone_map"].get_validated_object(); + if (!map) { + return; + } + BoneMap *bone_map = Object::cast_to<BoneMap>(map); + Ref<SkeletonProfile> profile = bone_map->get_profile(); + if (!profile.is_valid()) { + return; + } + Skeleton3D *src_skeleton = Object::cast_to<Skeleton3D>(p_node); + if (!src_skeleton) { + return; + } + bool remove_except_bone = bool(p_options["retarget/remove_tracks/except_bone_transform"]); + bool remove_positions = bool(p_options["retarget/remove_tracks/unimportant_positions"]); + bool remove_unmapped_bones = bool(p_options["retarget/remove_tracks/unmapped_bones"]); + + if (!remove_positions && !remove_unmapped_bones) { + return; + } + + TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + int track_len = anim->get_track_count(); + Vector<int> remove_indices; + for (int i = 0; i < track_len; i++) { + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); + if (!node) { + if (remove_except_bone) { + remove_indices.push_back(i); + } + continue; + } + Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); + if (track_skeleton && track_skeleton == src_skeleton) { + if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { + if (remove_except_bone) { + remove_indices.push_back(i); + } + continue; + } + StringName bn = anim->track_get_path(i).get_subname(0); + if (bn) { + int prof_idx = profile->find_bone(bone_map->find_profile_bone_name(bn)); + if (remove_unmapped_bones && prof_idx < 0) { + remove_indices.push_back(i); + continue; + } + if (remove_positions && anim->track_get_type(i) == Animation::TYPE_POSITION_3D && prof_idx >= 0) { + StringName prof_bn = profile->get_bone_name(prof_idx); + if (prof_bn == profile->get_root_bone() || prof_bn == profile->get_scale_base_bone()) { + continue; + } + remove_indices.push_back(i); + } + } + } + if (remove_except_bone) { + remove_indices.push_back(i); + } + } + + remove_indices.reverse(); + for (int i = 0; i < remove_indices.size(); i++) { + anim->remove_track(remove_indices[i]); + } + } + } + } +} + +PostImportPluginSkeletonTrackOrganizer::PostImportPluginSkeletonTrackOrganizer() { +} diff --git a/editor/import/post_import_plugin_skeleton_track_organizer.h b/editor/import/post_import_plugin_skeleton_track_organizer.h new file mode 100644 index 0000000000..1830861430 --- /dev/null +++ b/editor/import/post_import_plugin_skeleton_track_organizer.h @@ -0,0 +1,46 @@ +/*************************************************************************/ +/* post_import_plugin_skeleton_track_organizer.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H +#define POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H + +#include "resource_importer_scene.h" + +class PostImportPluginSkeletonTrackOrganizer : public EditorScenePostImportPlugin { + GDCLASS(PostImportPluginSkeletonTrackOrganizer, EditorScenePostImportPlugin); + +public: + virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) override; + virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override; + + PostImportPluginSkeletonTrackOrganizer(); +}; + +#endif // POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h index 8682ab80a3..e791788d50 100644 --- a/editor/import/resource_importer_bitmask.h +++ b/editor/import/resource_importer_bitmask.h @@ -53,4 +53,5 @@ public: ResourceImporterBitMap(); ~ResourceImporterBitMap(); }; + #endif // RESOURCE_IMPORTER_BITMASK_H diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h index 306aafa843..2ed121c5e8 100644 --- a/editor/import/resource_importer_csv_translation.h +++ b/editor/import/resource_importer_csv_translation.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RESOURCEIMPORTERCSVTRANSLATION_H -#define RESOURCEIMPORTERCSVTRANSLATION_H +#ifndef RESOURCE_IMPORTER_CSV_TRANSLATION_H +#define RESOURCE_IMPORTER_CSV_TRANSLATION_H #include "core/io/resource_importer.h" @@ -54,4 +54,4 @@ public: ResourceImporterCSVTranslation(); }; -#endif // RESOURCEIMPORTERCSVTRANSLATION_H +#endif // RESOURCE_IMPORTER_CSV_TRANSLATION_H diff --git a/editor/import/resource_importer_imagefont.h b/editor/import/resource_importer_imagefont.h index f46bc8c19b..e163f873da 100644 --- a/editor/import/resource_importer_imagefont.h +++ b/editor/import/resource_importer_imagefont.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RESOURCE_IMPORTER_IMAGE_FONT_H -#define RESOURCE_IMPORTER_IMAGE_FONT_H +#ifndef RESOURCE_IMPORTER_IMAGEFONT_H +#define RESOURCE_IMPORTER_IMAGEFONT_H #include "core/io/resource_importer.h" #include "scene/resources/font.h" @@ -55,4 +55,4 @@ public: ResourceImporterImageFont(); }; -#endif // RESOURCE_IMPORTER_IMAGE_FONT_H +#endif // RESOURCE_IMPORTER_IMAGEFONT_H diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h index 3da9f02adb..4dfac90fa1 100644 --- a/editor/import/resource_importer_obj.h +++ b/editor/import/resource_importer_obj.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RESOURCEIMPORTEROBJ_H -#define RESOURCEIMPORTEROBJ_H +#ifndef RESOURCE_IMPORTER_OBJ_H +#define RESOURCE_IMPORTER_OBJ_H #include "resource_importer_scene.h" @@ -69,4 +69,4 @@ public: ResourceImporterOBJ(); }; -#endif // RESOURCEIMPORTEROBJ_H +#endif // RESOURCE_IMPORTER_OBJ_H diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 860269bfcb..fab3e000cf 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -743,6 +743,163 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, HashMap<R return p_node; } +Node *ResourceImporterScene::_pre_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps) { + // children first + for (int i = 0; i < p_node->get_child_count(); i++) { + Node *r = _pre_fix_animations(p_node->get_child(i), p_root, p_node_data, p_animation_data, p_animation_fps); + if (!r) { + i--; //was erased + } + } + + String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node)); + + Dictionary node_settings; + if (p_node_data.has(import_id)) { + node_settings = p_node_data[import_id]; + } + + { + //make sure this is unique + node_settings = node_settings.duplicate(true); + //fill node settings for this node with default values + List<ImportOption> iopts; + get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts); + for (const ImportOption &E : iopts) { + if (!node_settings.has(E.option.name)) { + node_settings[E.option.name] = E.default_value; + } + } + } + + if (Object::cast_to<AnimationPlayer>(p_node)) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); + + Array animation_clips; + { + int clip_count = node_settings["clips/amount"]; + + for (int i = 0; i < clip_count; i++) { + String name = node_settings["clip_" + itos(i + 1) + "/name"]; + int from_frame = node_settings["clip_" + itos(i + 1) + "/start_frame"]; + int end_frame = node_settings["clip_" + itos(i + 1) + "/end_frame"]; + Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)node_settings["clip_" + itos(i + 1) + "/loop_mode"]); + bool save_to_file = node_settings["clip_" + itos(i + 1) + "/save_to_file/enabled"]; + bool save_to_path = node_settings["clip_" + itos(i + 1) + "/save_to_file/path"]; + bool save_to_file_keep_custom = node_settings["clip_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"]; + + animation_clips.push_back(name); + animation_clips.push_back(from_frame / p_animation_fps); + animation_clips.push_back(end_frame / p_animation_fps); + animation_clips.push_back(loop_mode); + animation_clips.push_back(save_to_file); + animation_clips.push_back(save_to_path); + animation_clips.push_back(save_to_file_keep_custom); + } + } + + if (animation_clips.size()) { + _create_clips(ap, animation_clips, true); + } else { + List<StringName> anims; + ap->get_animation_list(&anims); + AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = { + AnimationImportTracks(int(node_settings["import_tracks/position"])), + AnimationImportTracks(int(node_settings["import_tracks/rotation"])), + AnimationImportTracks(int(node_settings["import_tracks/scale"])) + }; + if (anims.size() > 1 && (import_tracks_mode[0] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[1] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[2] != ANIMATION_IMPORT_TRACKS_IF_PRESENT)) { + _optimize_track_usage(ap, import_tracks_mode); + } + } + } + + return p_node; +} + +Node *ResourceImporterScene::_post_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps) { + // children first + for (int i = 0; i < p_node->get_child_count(); i++) { + Node *r = _post_fix_animations(p_node->get_child(i), p_root, p_node_data, p_animation_data, p_animation_fps); + if (!r) { + i--; //was erased + } + } + + String import_id = p_node->get_meta("import_id", "PATH:" + p_root->get_path_to(p_node)); + + Dictionary node_settings; + if (p_node_data.has(import_id)) { + node_settings = p_node_data[import_id]; + } + + { + //make sure this is unique + node_settings = node_settings.duplicate(true); + //fill node settings for this node with default values + List<ImportOption> iopts; + get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts); + for (const ImportOption &E : iopts) { + if (!node_settings.has(E.option.name)) { + node_settings[E.option.name] = E.default_value; + } + } + } + + if (Object::cast_to<AnimationPlayer>(p_node)) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); + + bool use_optimizer = node_settings["optimizer/enabled"]; + float anim_optimizer_linerr = node_settings["optimizer/max_linear_error"]; + float anim_optimizer_angerr = node_settings["optimizer/max_angular_error"]; + float anim_optimizer_maxang = node_settings["optimizer/max_angle"]; + + if (use_optimizer) { + _optimize_animations(ap, anim_optimizer_linerr, anim_optimizer_angerr, anim_optimizer_maxang); + } + + bool use_compression = node_settings["compression/enabled"]; + int anim_compression_page_size = node_settings["compression/page_size"]; + + if (use_compression) { + _compress_animations(ap, anim_compression_page_size); + } + + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + if (p_animation_data.has(name)) { + Dictionary anim_settings = p_animation_data[name]; + { + //fill with default values + List<ImportOption> iopts; + get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts); + for (const ImportOption &F : iopts) { + if (!anim_settings.has(F.option.name)) { + anim_settings[F.option.name] = F.default_value; + } + } + } + + anim->set_loop_mode(static_cast<Animation::LoopMode>((int)anim_settings["settings/loop_mode"])); + bool save = anim_settings["save_to_file/enabled"]; + String path = anim_settings["save_to_file/path"]; + bool keep_custom = anim_settings["save_to_file/keep_custom_tracks"]; + + Ref<Animation> saved_anim = _save_animation_to_file(anim, save, path, keep_custom); + + if (saved_anim != anim) { + Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim)); + al->add_animation(name, saved_anim); //replace + } + } + } + } + + return p_node; +} + Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) { // children first for (int i = 0; i < p_node->get_child_count(); i++) { @@ -1012,83 +1169,6 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap< post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, p_root, p_node, Ref<Resource>(), node_settings); } - bool use_optimizer = node_settings["optimizer/enabled"]; - float anim_optimizer_linerr = node_settings["optimizer/max_linear_error"]; - float anim_optimizer_angerr = node_settings["optimizer/max_angular_error"]; - float anim_optimizer_maxang = node_settings["optimizer/max_angle"]; - - if (use_optimizer) { - _optimize_animations(ap, anim_optimizer_linerr, anim_optimizer_angerr, anim_optimizer_maxang); - } - - Array animation_clips; - { - int clip_count = node_settings["clips/amount"]; - - for (int i = 0; i < clip_count; i++) { - String name = node_settings["clip_" + itos(i + 1) + "/name"]; - int from_frame = node_settings["clip_" + itos(i + 1) + "/start_frame"]; - int end_frame = node_settings["clip_" + itos(i + 1) + "/end_frame"]; - Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)node_settings["clip_" + itos(i + 1) + "/loop_mode"]); - bool save_to_file = node_settings["clip_" + itos(i + 1) + "/save_to_file/enabled"]; - bool save_to_path = node_settings["clip_" + itos(i + 1) + "/save_to_file/path"]; - bool save_to_file_keep_custom = node_settings["clip_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"]; - - animation_clips.push_back(name); - animation_clips.push_back(from_frame / p_animation_fps); - animation_clips.push_back(end_frame / p_animation_fps); - animation_clips.push_back(loop_mode); - animation_clips.push_back(save_to_file); - animation_clips.push_back(save_to_path); - animation_clips.push_back(save_to_file_keep_custom); - } - } - - if (animation_clips.size()) { - _create_clips(ap, animation_clips, true); - } else { - List<StringName> anims; - ap->get_animation_list(&anims); - for (const StringName &name : anims) { - Ref<Animation> anim = ap->get_animation(name); - if (p_animation_data.has(name)) { - Dictionary anim_settings = p_animation_data[name]; - { - //fill with default values - List<ImportOption> iopts; - get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts); - for (const ImportOption &F : iopts) { - if (!anim_settings.has(F.option.name)) { - anim_settings[F.option.name] = F.default_value; - } - } - } - - anim->set_loop_mode(static_cast<Animation::LoopMode>((int)anim_settings["settings/loop_mode"])); - bool save = anim_settings["save_to_file/enabled"]; - String path = anim_settings["save_to_file/path"]; - bool keep_custom = anim_settings["save_to_file/keep_custom_tracks"]; - - Ref<Animation> saved_anim = _save_animation_to_file(anim, save, path, keep_custom); - - if (saved_anim != anim) { - Ref<AnimationLibrary> al = ap->get_animation_library(ap->find_animation_library(anim)); - al->add_animation(name, saved_anim); //replace - } - } - } - - AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = { - AnimationImportTracks(int(node_settings["import_tracks/position"])), - AnimationImportTracks(int(node_settings["import_tracks/rotation"])), - AnimationImportTracks(int(node_settings["import_tracks/scale"])) - }; - - if (anims.size() > 1 && (import_tracks_mode[0] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[1] != ANIMATION_IMPORT_TRACKS_IF_PRESENT || import_tracks_mode[2] != ANIMATION_IMPORT_TRACKS_IF_PRESENT)) { - _optimize_track_usage(ap, import_tracks_mode); - } - } - if (post_importer_plugins.size()) { List<StringName> anims; ap->get_animation_list(&anims); @@ -1113,13 +1193,6 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap< } } } - - bool use_compression = node_settings["compression/enabled"]; - int anim_compression_page_size = node_settings["compression/page_size"]; - - if (use_compression) { - _compress_animations(ap, anim_compression_page_size); - } } return p_node; @@ -2099,7 +2172,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p post_importer_plugins.write[i]->pre_process(scene, p_options); } + _pre_fix_animations(scene, scene, node_data, animation_data, fps); _post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps); + _post_fix_animations(scene, scene, node_data, animation_data, fps); String root_type = p_options["nodes/root_type"]; root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class. diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index b77c1dccb4..b336931476 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RESOURCEIMPORTERSCENE_H -#define RESOURCEIMPORTERSCENE_H +#ifndef RESOURCE_IMPORTER_SCENE_H +#define RESOURCE_IMPORTER_SCENE_H #include "core/error/error_macros.h" #include "core/io/resource_importer.h" @@ -274,7 +274,9 @@ public: virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; } Node *_pre_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames); + Node *_pre_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps); Node *_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps); + Node *_post_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps); Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks); void _create_clips(AnimationPlayer *anim, const Array &p_clips, bool p_bake_all); @@ -479,4 +481,4 @@ Transform3D ResourceImporterScene::get_collision_shapes_transform(const M &p_opt return transform; } -#endif // RESOURCEIMPORTERSCENE_H +#endif // RESOURCE_IMPORTER_SCENE_H diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 7def2d4f77..496ad3bf70 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RESOURCEIMPORTTEXTURE_H -#define RESOURCEIMPORTTEXTURE_H +#ifndef RESOURCE_IMPORTER_TEXTURE_H +#define RESOURCE_IMPORTER_TEXTURE_H #include "core/io/file_access.h" #include "core/io/image.h" @@ -109,4 +109,4 @@ public: ~ResourceImporterTexture(); }; -#endif // RESOURCEIMPORTTEXTURE_H +#endif // RESOURCE_IMPORTER_TEXTURE_H diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index f0ba1eb7a1..3a47bfb29f 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -33,7 +33,7 @@ #include "core/io/file_access.h" #include "core/io/marshalls.h" #include "core/io/resource_saver.h" -#include "scene/resources/audio_stream_sample.h" +#include "scene/resources/audio_stream_wav.h" const float TRIM_DB_LIMIT = -50; const int TRIM_FADE_OUT_FRAMES = 500; @@ -55,7 +55,7 @@ String ResourceImporterWAV::get_save_extension() const { } String ResourceImporterWAV::get_resource_type() const { - return "AudioStreamSample"; + return "AudioStreamWAV"; } bool ResourceImporterWAV::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const { @@ -86,7 +86,7 @@ void ResourceImporterWAV::get_import_options(const String &p_path, List<ImportOp r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "force/max_rate_hz", PROPERTY_HINT_RANGE, "11025,192000,1,exp"), 44100)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/trim"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/normalize"), false)); - // Keep the `edit/loop_mode` enum in sync with AudioStreamSample::LoopMode (note: +1 offset due to "Detect From WAV"). + // Keep the `edit/loop_mode` enum in sync with AudioStreamWAV::LoopMode (note: +1 offset due to "Detect From WAV"). r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "edit/loop_mode", PROPERTY_HINT_ENUM, "Detect From WAV,Disabled,Forward,Ping-Pong,Backward", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "edit/loop_begin"), 0)); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "edit/loop_end"), -1)); @@ -130,7 +130,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s int format_bits = 0; int format_channels = 0; - AudioStreamSample::LoopMode loop_mode = AudioStreamSample::LOOP_DISABLED; + AudioStreamWAV::LoopMode loop_mode = AudioStreamWAV::LOOP_DISABLED; uint16_t compression_code = 1; bool format_found = false; bool data_found = false; @@ -282,11 +282,11 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s int loop_type = file->get_32(); if (loop_type == 0x00 || loop_type == 0x01 || loop_type == 0x02) { if (loop_type == 0x00) { - loop_mode = AudioStreamSample::LOOP_FORWARD; + loop_mode = AudioStreamWAV::LOOP_FORWARD; } else if (loop_type == 0x01) { - loop_mode = AudioStreamSample::LOOP_PINGPONG; + loop_mode = AudioStreamWAV::LOOP_PINGPONG; } else if (loop_type == 0x02) { - loop_mode = AudioStreamSample::LOOP_BACKWARD; + loop_mode = AudioStreamWAV::LOOP_BACKWARD; } loop_begin = file->get_32(); loop_end = file->get_32(); @@ -386,7 +386,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s bool trim = p_options["edit/trim"]; - if (trim && (loop_mode != AudioStreamSample::LOOP_DISABLED) && format_channels > 0) { + if (trim && (loop_mode != AudioStreamWAV::LOOP_DISABLED) && format_channels > 0) { int first = 0; int last = (frames / format_channels) - 1; bool found = false; @@ -431,7 +431,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } if (import_loop_mode >= 2) { - loop_mode = (AudioStreamSample::LoopMode)(import_loop_mode - 1); + loop_mode = (AudioStreamWAV::LoopMode)(import_loop_mode - 1); loop_begin = p_options["edit/loop_begin"]; loop_end = p_options["edit/loop_end"]; // Wrap around to max frames, so `-1` can be used to select the end, etc. @@ -463,10 +463,10 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } Vector<uint8_t> dst_data; - AudioStreamSample::Format dst_format; + AudioStreamWAV::Format dst_format; if (compression == 1) { - dst_format = AudioStreamSample::FORMAT_IMA_ADPCM; + dst_format = AudioStreamWAV::FORMAT_IMA_ADPCM; if (format_channels == 1) { _compress_ima_adpcm(data, dst_data); } else { @@ -503,7 +503,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } } else { - dst_format = is16 ? AudioStreamSample::FORMAT_16_BITS : AudioStreamSample::FORMAT_8_BITS; + dst_format = is16 ? AudioStreamWAV::FORMAT_16_BITS : AudioStreamWAV::FORMAT_8_BITS; dst_data.resize(data.size() * (is16 ? 2 : 1)); { uint8_t *w = dst_data.ptrw(); @@ -521,7 +521,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } } - Ref<AudioStreamSample> sample; + Ref<AudioStreamWAV> sample; sample.instantiate(); sample->set_data(dst_data); sample->set_format(dst_format); diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 0e2967dc42..1c39c425b1 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -502,7 +502,7 @@ void SceneImportSettings::_update_camera() { Transform3D xf; xf.basis = Basis(Vector3(1, 0, 0), rot_x) * Basis(Vector3(0, 1, 0), rot_y); xf.origin = center; - xf.translate(0, 0, camera_size); + xf.translate_local(0, 0, camera_size); camera->set_transform(xf); } diff --git a/editor/import_dock.h b/editor/import_dock.h index 7f4aa1ddb3..3098c6e815 100644 --- a/editor/import_dock.h +++ b/editor/import_dock.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef IMPORTDOCK_H -#define IMPORTDOCK_H +#ifndef IMPORT_DOCK_H +#define IMPORT_DOCK_H #include "core/io/config_file.h" #include "core/io/resource_importer.h" @@ -105,4 +105,4 @@ public: ~ImportDock(); }; -#endif // IMPORTDOCK_H +#endif // IMPORT_DOCK_H diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 1f2d8afb7d..536852c0f2 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -153,4 +153,4 @@ public: ~InspectorDock(); }; -#endif +#endif // INSPECTOR_DOCK_H diff --git a/editor/plugins/animation_library_editor.h b/editor/plugins/animation_library_editor.h index bf89508321..6e214860b8 100644 --- a/editor/plugins/animation_library_editor.h +++ b/editor/plugins/animation_library_editor.h @@ -116,4 +116,4 @@ public: AnimationLibraryEditor(); }; -#endif // ANIMATIONPLAYERLIBRARYEDITOR_H +#endif // ANIMATION_LIBRARY_EDITOR_H diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp index 1258b9a03c..93dc0ff3c9 100644 --- a/editor/plugins/animation_state_machine_editor.cpp +++ b/editor/plugins/animation_state_machine_editor.cpp @@ -1018,7 +1018,7 @@ void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) { anim->set_animation(animations_to_add[p_index]); - String base_name = animations_to_add[p_index]; + String base_name = animations_to_add[p_index].validate_node_name(); int base = 1; String name = base_name; while (state_machine->has_node(name)) { diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h index e02662b8db..070d25e29f 100644 --- a/editor/plugins/asset_library_editor_plugin.h +++ b/editor/plugins/asset_library_editor_plugin.h @@ -338,4 +338,4 @@ public: ~AssetLibraryEditorPlugin(); }; -#endif // EDITORASSETLIBRARY_H +#endif // ASSET_LIBRARY_EDITOR_PLUGIN_H diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp deleted file mode 100644 index 9b874ada45..0000000000 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/*************************************************************************/ -/* audio_stream_editor_plugin.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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_stream_editor_plugin.h" - -#include "core/config/project_settings.h" -#include "core/io/resource_loader.h" -#include "core/os/keyboard.h" -#include "editor/audio_stream_preview.h" -#include "editor/editor_node.h" -#include "editor/editor_scale.h" -#include "editor/editor_settings.h" - -void AudioStreamEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_READY: { - AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", callable_mp(this, &AudioStreamEditor::_preview_changed)); - } break; - - case NOTIFICATION_THEME_CHANGED: - case NOTIFICATION_ENTER_TREE: { - _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - _stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); - _preview->set_color(get_theme_color(SNAME("dark_color_2"), SNAME("Editor"))); - set_color(get_theme_color(SNAME("dark_color_1"), SNAME("Editor"))); - - _indicator->update(); - _preview->update(); - } break; - - case NOTIFICATION_PROCESS: { - _current = _player->get_playback_position(); - _indicator->update(); - } break; - - case NOTIFICATION_VISIBILITY_CHANGED: { - if (!is_visible_in_tree()) { - _stop(); - } - } break; - } -} - -void AudioStreamEditor::_draw_preview() { - Rect2 rect = _preview->get_rect(); - Size2 size = get_size(); - - Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream); - float preview_len = preview->get_length(); - - Vector<Vector2> lines; - lines.resize(size.width * 2); - - for (int i = 0; i < size.width; i++) { - float ofs = i * preview_len / size.width; - float ofs_n = (i + 1) * preview_len / size.width; - float max = preview->get_max(ofs, ofs_n) * 0.5 + 0.5; - float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5; - - int idx = i; - lines.write[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y); - lines.write[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y); - } - - Vector<Color> color; - color.push_back(get_theme_color(SNAME("contrast_color_2"), SNAME("Editor"))); - - RS::get_singleton()->canvas_item_add_multiline(_preview->get_canvas_item(), lines, color); -} - -void AudioStreamEditor::_preview_changed(ObjectID p_which) { - if (stream.is_valid() && stream->get_instance_id() == p_which) { - _preview->update(); - } -} - -void AudioStreamEditor::_audio_changed() { - if (!is_visible()) { - return; - } - update(); -} - -void AudioStreamEditor::_play() { - if (_player->is_playing()) { - // '_pausing' variable indicates that we want to pause the audio player, not stop it. See '_on_finished()'. - _pausing = true; - _player->stop(); - _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - set_process(false); - } else { - _player->play(_current); - _play_button->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons"))); - set_process(true); - } -} - -void AudioStreamEditor::_stop() { - _player->stop(); - _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - _current = 0; - _indicator->update(); - set_process(false); -} - -void AudioStreamEditor::_on_finished() { - _play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - if (!_pausing) { - _current = 0; - _indicator->update(); - } else { - _pausing = false; - } - set_process(false); -} - -void AudioStreamEditor::_draw_indicator() { - if (!stream.is_valid()) { - return; - } - - Rect2 rect = _preview->get_rect(); - float len = stream->get_length(); - float ofs_x = _current / len * rect.size.width; - const Color color = get_theme_color(SNAME("accent_color"), SNAME("Editor")); - _indicator->draw_line(Point2(ofs_x, 0), Point2(ofs_x, rect.size.height), color, Math::round(2 * EDSCALE)); - _indicator->draw_texture( - get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons")), - Point2(ofs_x - get_theme_icon(SNAME("TimelineIndicator"), SNAME("EditorIcons"))->get_width() * 0.5, 0), - color); - - _current_label->set_text(String::num(_current, 2).pad_decimals(2) + " /"); -} - -void AudioStreamEditor::_on_input_indicator(Ref<InputEvent> p_event) { - const Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) { - if (mb->is_pressed()) { - _seek_to(mb->get_position().x); - } - _dragging = mb->is_pressed(); - } - - const Ref<InputEventMouseMotion> mm = p_event; - if (mm.is_valid()) { - if (_dragging) { - _seek_to(mm->get_position().x); - } - } -} - -void AudioStreamEditor::_seek_to(real_t p_x) { - _current = p_x / _preview->get_rect().size.x * stream->get_length(); - _current = CLAMP(_current, 0, stream->get_length()); - _player->seek(_current); - _indicator->update(); -} - -void AudioStreamEditor::edit(Ref<AudioStream> p_stream) { - if (!stream.is_null()) { - stream->disconnect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed)); - } - - stream = p_stream; - _player->set_stream(stream); - _current = 0; - String text = String::num(stream->get_length(), 2).pad_decimals(2) + "s"; - _duration_label->set_text(text); - - if (!stream.is_null()) { - stream->connect("changed", callable_mp(this, &AudioStreamEditor::_audio_changed)); - update(); - } else { - hide(); - } -} - -void AudioStreamEditor::_bind_methods() { -} - -AudioStreamEditor::AudioStreamEditor() { - set_custom_minimum_size(Size2(1, 100) * EDSCALE); - - _player = memnew(AudioStreamPlayer); - _player->connect("finished", callable_mp(this, &AudioStreamEditor::_on_finished)); - add_child(_player); - - VBoxContainer *vbox = memnew(VBoxContainer); - vbox->set_anchors_and_offsets_preset(PRESET_FULL_RECT, PRESET_MODE_MINSIZE, 0); - add_child(vbox); - - _preview = memnew(ColorRect); - _preview->set_v_size_flags(SIZE_EXPAND_FILL); - _preview->connect("draw", callable_mp(this, &AudioStreamEditor::_draw_preview)); - vbox->add_child(_preview); - - _indicator = memnew(Control); - _indicator->set_anchors_and_offsets_preset(PRESET_FULL_RECT); - _indicator->connect("draw", callable_mp(this, &AudioStreamEditor::_draw_indicator)); - _indicator->connect("gui_input", callable_mp(this, &AudioStreamEditor::_on_input_indicator)); - _preview->add_child(_indicator); - - HBoxContainer *hbox = memnew(HBoxContainer); - hbox->add_theme_constant_override("separation", 0); - vbox->add_child(hbox); - - _play_button = memnew(Button); - _play_button->set_flat(true); - hbox->add_child(_play_button); - _play_button->set_focus_mode(Control::FOCUS_NONE); - _play_button->connect("pressed", callable_mp(this, &AudioStreamEditor::_play)); - _play_button->set_shortcut(ED_SHORTCUT("inspector/audio_preview_play_pause", TTR("Audio Preview Play/Pause"), Key::SPACE)); - - _stop_button = memnew(Button); - _stop_button->set_flat(true); - hbox->add_child(_stop_button); - _stop_button->set_focus_mode(Control::FOCUS_NONE); - _stop_button->connect("pressed", callable_mp(this, &AudioStreamEditor::_stop)); - - _current_label = memnew(Label); - _current_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); - _current_label->set_h_size_flags(SIZE_EXPAND_FILL); - _current_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - _current_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); - _current_label->set_modulate(Color(1, 1, 1, 0.5)); - hbox->add_child(_current_label); - - _duration_label = memnew(Label); - _duration_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts"))); - _duration_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts"))); - hbox->add_child(_duration_label); -} - -void AudioStreamEditorPlugin::edit(Object *p_object) { - AudioStream *s = Object::cast_to<AudioStream>(p_object); - if (!s) { - return; - } - - audio_editor->edit(Ref<AudioStream>(s)); -} - -bool AudioStreamEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("AudioStream"); -} - -void AudioStreamEditorPlugin::make_visible(bool p_visible) { - audio_editor->set_visible(p_visible); -} - -AudioStreamEditorPlugin::AudioStreamEditorPlugin() { - audio_editor = memnew(AudioStreamEditor); - add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, audio_editor); - audio_editor->hide(); -} - -AudioStreamEditorPlugin::~AudioStreamEditorPlugin() { -} diff --git a/editor/plugins/bit_map_editor_plugin.h b/editor/plugins/bit_map_editor_plugin.h index c883e5542f..b045f8c751 100644 --- a/editor/plugins/bit_map_editor_plugin.h +++ b/editor/plugins/bit_map_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BIT_MAP_PREVIEW_EDITOR_PLUGIN_H -#define BIT_MAP_PREVIEW_EDITOR_PLUGIN_H +#ifndef BIT_MAP_EDITOR_PLUGIN_H +#define BIT_MAP_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/resources/bit_map.h" @@ -61,4 +61,4 @@ public: BitMapEditorPlugin(); }; -#endif // BIT_MAP_PREVIEW_EDITOR_PLUGIN_H +#endif // BIT_MAP_EDITOR_PLUGIN_H diff --git a/editor/plugins/bone_map_editor_plugin.cpp b/editor/plugins/bone_map_editor_plugin.cpp index 967a95be9d..3669971b1e 100644 --- a/editor/plugins/bone_map_editor_plugin.cpp +++ b/editor/plugins/bone_map_editor_plugin.cpp @@ -33,6 +33,7 @@ #include "editor/editor_scale.h" #include "editor/import/post_import_plugin_skeleton_renamer.h" #include "editor/import/post_import_plugin_skeleton_rest_fixer.h" +#include "editor/import/post_import_plugin_skeleton_track_organizer.h" #include "editor/import/scene_import_settings.h" void BoneMapperButton::fetch_textures() { @@ -64,6 +65,9 @@ void BoneMapperButton::set_state(BoneMapState p_state) { case BONE_MAP_STATE_SET: { circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/set")); } break; + case BONE_MAP_STATE_MISSING: { + circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/missing")); + } break; case BONE_MAP_STATE_ERROR: { circle->set_modulate(EditorSettings::get_singleton()->get("editors/bone_mapper/handle_colors/error")); } break; @@ -310,16 +314,48 @@ void BoneMapper::recreate_items() { void BoneMapper::_update_state() { int len = bone_mapper_buttons.size(); for (int i = 0; i < len; i++) { - StringName sbn = bone_map->get_skeleton_bone_name(bone_mapper_buttons[i]->get_profile_bone_name()); - if (skeleton->find_bone(sbn) >= 0) { + StringName pbn = bone_mapper_buttons[i]->get_profile_bone_name(); + StringName sbn = bone_map->get_skeleton_bone_name(pbn); + int bone_idx = skeleton->find_bone(sbn); + if (bone_idx >= 0) { if (bone_map->get_skeleton_bone_name_count(sbn) == 1) { - bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_SET); + Ref<SkeletonProfile> prof = bone_map->get_profile(); + + StringName parent_name = prof->get_bone_parent(prof->find_bone(pbn)); + Vector<int> prof_parent_bones; + while (parent_name != StringName()) { + prof_parent_bones.push_back(skeleton->find_bone(bone_map->get_skeleton_bone_name(parent_name))); + if (prof->find_bone(parent_name) == -1) { + break; + } + parent_name = prof->get_bone_parent(prof->find_bone(parent_name)); + } + + int parent_id = skeleton->get_bone_parent(bone_idx); + Vector<int> skel_parent_bones; + while (parent_id >= 0) { + skel_parent_bones.push_back(parent_id); + parent_id = skeleton->get_bone_parent(parent_id); + } + + bool is_broken = false; + for (int j = 0; j < prof_parent_bones.size(); j++) { + if (prof_parent_bones[j] != -1 && !skel_parent_bones.has(prof_parent_bones[j])) { + is_broken = true; + } + } + + if (is_broken) { + bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_ERROR); + } else { + bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_SET); + } } else { bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_ERROR); } } else { if (bone_mapper_buttons[i]->is_require()) { - bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_ERROR); + bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_MISSING); } else { bone_mapper_buttons[i]->set_state(BoneMapperButton::BONE_MAP_STATE_UNSET); } @@ -379,11 +415,15 @@ void BoneMapEditor::create_editors() { } void BoneMapEditor::fetch_objects() { + skeleton = nullptr; // Hackey... but it may be the easist way to get a selected object from "ImporterScene". SceneImportSettings *si = SceneImportSettings::get_singleton(); if (!si) { return; } + if (!si->is_visible()) { + return; + } Node *selected = si->get_selected_node(); if (selected) { Skeleton3D *sk = Object::cast_to<Skeleton3D>(selected); @@ -404,11 +444,11 @@ void BoneMapEditor::_notification(int p_what) { create_editors(); } break; case NOTIFICATION_EXIT_TREE: { - if (!bone_mapper) { - return; + if (bone_mapper) { + remove_child(bone_mapper); + bone_mapper->queue_delete(); } - remove_child(bone_mapper); - bone_mapper->queue_delete(); + skeleton = nullptr; } break; } } @@ -436,14 +476,19 @@ void EditorInspectorPluginBoneMap::parse_begin(Object *p_object) { BoneMapEditorPlugin::BoneMapEditorPlugin() { // Register properties in editor settings. + EDITOR_DEF("editors/bone_mapper/handle_colors/unset", Color(0.3, 0.3, 0.3)); EDITOR_DEF("editors/bone_mapper/handle_colors/set", Color(0.1, 0.6, 0.25)); + EDITOR_DEF("editors/bone_mapper/handle_colors/missing", Color(0.8, 0.2, 0.8)); EDITOR_DEF("editors/bone_mapper/handle_colors/error", Color(0.8, 0.2, 0.2)); - EDITOR_DEF("editors/bone_mapper/handle_colors/unset", Color(0.3, 0.3, 0.3)); Ref<EditorInspectorPluginBoneMap> inspector_plugin; inspector_plugin.instantiate(); add_inspector_plugin(inspector_plugin); + Ref<PostImportPluginSkeletonTrackOrganizer> post_import_plugin_track_organizer; + post_import_plugin_track_organizer.instantiate(); + add_scene_post_import_plugin(post_import_plugin_track_organizer); + Ref<PostImportPluginSkeletonRenamer> post_import_plugin_renamer; post_import_plugin_renamer.instantiate(); add_scene_post_import_plugin(post_import_plugin_renamer); diff --git a/editor/plugins/bone_map_editor_plugin.h b/editor/plugins/bone_map_editor_plugin.h index e1ea6b4060..339547ea10 100644 --- a/editor/plugins/bone_map_editor_plugin.h +++ b/editor/plugins/bone_map_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BONE_MAP_EDITOR_H -#define BONE_MAP_EDITOR_H +#ifndef BONE_MAP_EDITOR_PLUGIN_H +#define BONE_MAP_EDITOR_PLUGIN_H #include "editor/editor_node.h" #include "editor/editor_plugin.h" @@ -47,6 +47,7 @@ public: enum BoneMapState { BONE_MAP_STATE_UNSET, BONE_MAP_STATE_SET, + BONE_MAP_STATE_MISSING, BONE_MAP_STATE_ERROR }; @@ -176,4 +177,4 @@ public: BoneMapEditorPlugin(); }; -#endif // BONE_MAP_EDITOR_H +#endif // BONE_MAP_EDITOR_PLUGIN_H diff --git a/editor/plugins/camera_3d_editor_plugin.h b/editor/plugins/camera_3d_editor_plugin.h index a8164f9b85..a969b31976 100644 --- a/editor/plugins/camera_3d_editor_plugin.h +++ b/editor/plugins/camera_3d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERA_EDITOR_PLUGIN_H -#define CAMERA_EDITOR_PLUGIN_H +#ifndef CAMERA_3D_EDITOR_PLUGIN_H +#define CAMERA_3D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/3d/camera_3d.h" @@ -68,4 +68,4 @@ public: ~Camera3DEditorPlugin(); }; -#endif // CAMERA_EDITOR_PLUGIN_H +#endif // CAMERA_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 10f4b4fe24..19239b8650 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -50,6 +50,7 @@ #include "scene/2d/skeleton_2d.h" #include "scene/2d/sprite_2d.h" #include "scene/2d/touch_screen_button.h" +#include "scene/gui/flow_container.h" #include "scene/gui/grid_container.h" #include "scene/gui/nine_patch_rect.h" #include "scene/gui/subviewport_container.h" @@ -2281,7 +2282,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { } selection_menu_additive_selection = b->is_shift_pressed(); - selection_menu->set_position(get_screen_position() + b->get_position()); + selection_menu->set_position(viewport->get_screen_transform().xform(b->get_position())); selection_menu->reset_size(); selection_menu->popup(); return true; @@ -2792,10 +2793,10 @@ void CanvasItemEditor::_draw_rulers() { if (grid_snap_active || _is_grid_visible()) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (snap_relative && selection.size() > 0) { - ruler_transform.translate(_get_encompassing_rect_from_list(selection).position); + ruler_transform.translate_local(_get_encompassing_rect_from_list(selection).position); ruler_transform.scale_basis(grid_step * Math::pow(2.0, grid_step_multiplier)); } else { - ruler_transform.translate(grid_offset); + ruler_transform.translate_local(grid_offset); ruler_transform.scale_basis(grid_step * Math::pow(2.0, grid_step_multiplier)); } while ((transform * ruler_transform).get_scale().x < 50 || (transform * ruler_transform).get_scale().y < 50) { @@ -3861,7 +3862,7 @@ void CanvasItemEditor::_update_editor_settings() { key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55)); animation_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); - context_menu_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles"))); + context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles"))); panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); pan_speed = int(EditorSettings::get_singleton()->get("editors/panning/2d_editor_pan_speed")); @@ -4926,11 +4927,11 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) { ERR_FAIL_COND(!p_control); - hbc_context_menu->add_child(p_control); + context_menu_hbox->add_child(p_control); } void CanvasItemEditor::remove_control_from_menu_panel(Control *p_control) { - hbc_context_menu->remove_child(p_control); + context_menu_hbox->remove_child(p_control); } void CanvasItemEditor::add_control_to_left_panel(Control *p_control) { @@ -4979,9 +4980,14 @@ CanvasItemEditor::CanvasItemEditor() { EditorNode::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", Callable(this, "_update_override_camera_button"), make_binds(true)); EditorNode::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", Callable(this, "_update_override_camera_button"), make_binds(false)); - hb = memnew(HBoxContainer); - add_child(hb); - hb->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); + // A fluid container for all toolbars. + HFlowContainer *main_flow = memnew(HFlowContainer); + add_child(main_flow); + + // Main toolbars. + HBoxContainer *main_menu_hbox = memnew(HBoxContainer); + main_menu_hbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); + main_flow->add_child(main_menu_hbox); bottom_split = memnew(VSplitContainer); add_child(bottom_split); @@ -5059,12 +5065,12 @@ CanvasItemEditor::CanvasItemEditor() { // This prevents the first button's hover/pressed effect from "touching" the panel's border, // which looks ugly. Control *margin_left = memnew(Control); - hb->add_child(margin_left); + main_menu_hbox->add_child(margin_left); margin_left->set_custom_minimum_size(Size2(2, 0) * EDSCALE); select_button = memnew(Button); select_button->set_flat(true); - hb->add_child(select_button); + main_menu_hbox->add_child(select_button); select_button->set_toggle_mode(true); select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_SELECT)); select_button->set_pressed(true); @@ -5072,11 +5078,11 @@ CanvasItemEditor::CanvasItemEditor() { select_button->set_shortcut_context(this); select_button->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Alt+Drag: Scale selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("RMB: Add node at position clicked.")); - hb->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); move_button = memnew(Button); move_button->set_flat(true); - hb->add_child(move_button); + main_menu_hbox->add_child(move_button); move_button->set_toggle_mode(true); move_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_MOVE)); move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode", TTR("Move Mode"), Key::W)); @@ -5085,7 +5091,7 @@ CanvasItemEditor::CanvasItemEditor() { rotate_button = memnew(Button); rotate_button->set_flat(true); - hb->add_child(rotate_button); + main_menu_hbox->add_child(rotate_button); rotate_button->set_toggle_mode(true); rotate_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_ROTATE)); rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), Key::E)); @@ -5094,32 +5100,32 @@ CanvasItemEditor::CanvasItemEditor() { scale_button = memnew(Button); scale_button->set_flat(true); - hb->add_child(scale_button); + main_menu_hbox->add_child(scale_button); scale_button->set_toggle_mode(true); scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_SCALE)); scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), Key::S)); scale_button->set_shortcut_context(this); scale_button->set_tooltip(TTR("Shift: Scale proportionally.")); - hb->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); list_select_button = memnew(Button); list_select_button->set_flat(true); - hb->add_child(list_select_button); + main_menu_hbox->add_child(list_select_button); list_select_button->set_toggle_mode(true); list_select_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_LIST_SELECT)); list_select_button->set_tooltip(TTR("Show list of selectable nodes at position clicked.")); pivot_button = memnew(Button); pivot_button->set_flat(true); - hb->add_child(pivot_button); + main_menu_hbox->add_child(pivot_button); pivot_button->set_toggle_mode(true); pivot_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_EDIT_PIVOT)); pivot_button->set_tooltip(TTR("Click to change object's rotation pivot.")); pan_button = memnew(Button); pan_button->set_flat(true); - hb->add_child(pan_button); + main_menu_hbox->add_child(pan_button); pan_button->set_toggle_mode(true); pan_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_PAN)); pan_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/pan_mode", TTR("Pan Mode"), Key::G)); @@ -5128,18 +5134,18 @@ CanvasItemEditor::CanvasItemEditor() { ruler_button = memnew(Button); ruler_button->set_flat(true); - hb->add_child(ruler_button); + main_menu_hbox->add_child(ruler_button); ruler_button->set_toggle_mode(true); ruler_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_RULER)); ruler_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/ruler_mode", TTR("Ruler Mode"), Key::R)); ruler_button->set_shortcut_context(this); ruler_button->set_tooltip(TTR("Ruler Mode")); - hb->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); smart_snap_button = memnew(Button); smart_snap_button->set_flat(true); - hb->add_child(smart_snap_button); + main_menu_hbox->add_child(smart_snap_button); smart_snap_button->set_toggle_mode(true); smart_snap_button->connect("toggled", callable_mp(this, &CanvasItemEditor::_button_toggle_smart_snap)); smart_snap_button->set_tooltip(TTR("Toggle smart snapping.")); @@ -5148,7 +5154,7 @@ CanvasItemEditor::CanvasItemEditor() { grid_snap_button = memnew(Button); grid_snap_button->set_flat(true); - hb->add_child(grid_snap_button); + main_menu_hbox->add_child(grid_snap_button); grid_snap_button->set_toggle_mode(true); grid_snap_button->connect("toggled", callable_mp(this, &CanvasItemEditor::_button_toggle_grid_snap)); grid_snap_button->set_tooltip(TTR("Toggle grid snapping.")); @@ -5157,7 +5163,7 @@ CanvasItemEditor::CanvasItemEditor() { snap_config_menu = memnew(MenuButton); snap_config_menu->set_shortcut_context(this); - hb->add_child(snap_config_menu); + main_menu_hbox->add_child(snap_config_menu); snap_config_menu->set_h_size_flags(SIZE_SHRINK_END); snap_config_menu->set_tooltip(TTR("Snapping Options")); snap_config_menu->set_switch_on_hover(true); @@ -5186,11 +5192,11 @@ CanvasItemEditor::CanvasItemEditor() { smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_other_nodes", TTR("Snap to Other Nodes")), SNAP_USE_OTHER_NODES); smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_guides", TTR("Snap to Guides")), SNAP_USE_GUIDES); - hb->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); lock_button = memnew(Button); lock_button->set_flat(true); - hb->add_child(lock_button); + main_menu_hbox->add_child(lock_button); lock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(LOCK_SELECTED)); lock_button->set_tooltip(TTR("Lock selected node, preventing selection and movement.")); @@ -5199,7 +5205,7 @@ CanvasItemEditor::CanvasItemEditor() { unlock_button = memnew(Button); unlock_button->set_flat(true); - hb->add_child(unlock_button); + main_menu_hbox->add_child(unlock_button); unlock_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(UNLOCK_SELECTED)); unlock_button->set_tooltip(TTR("Unlock selected node, allowing selection and movement.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. @@ -5207,7 +5213,7 @@ CanvasItemEditor::CanvasItemEditor() { group_button = memnew(Button); group_button->set_flat(true); - hb->add_child(group_button); + main_menu_hbox->add_child(group_button); group_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(GROUP_SELECTED)); group_button->set_tooltip(TTR("Makes sure the object's children are not selectable.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. @@ -5215,17 +5221,17 @@ CanvasItemEditor::CanvasItemEditor() { ungroup_button = memnew(Button); ungroup_button->set_flat(true); - hb->add_child(ungroup_button); + main_menu_hbox->add_child(ungroup_button); ungroup_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(UNGROUP_SELECTED)); ungroup_button->set_tooltip(TTR("Restores the object's children's ability to be selected.")); // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. ungroup_button->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G)); - hb->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); skeleton_menu = memnew(MenuButton); skeleton_menu->set_shortcut_context(this); - hb->add_child(skeleton_menu); + main_menu_hbox->add_child(skeleton_menu); skeleton_menu->set_tooltip(TTR("Skeleton Options")); skeleton_menu->set_switch_on_hover(true); @@ -5236,24 +5242,24 @@ CanvasItemEditor::CanvasItemEditor() { p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bone2D Node(s) from Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::B), SKELETON_MAKE_BONES); p->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_popup_callback)); - hb->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); override_camera_button = memnew(Button); override_camera_button->set_flat(true); - hb->add_child(override_camera_button); + main_menu_hbox->add_child(override_camera_button); override_camera_button->connect("toggled", callable_mp(this, &CanvasItemEditor::_button_override_camera)); override_camera_button->set_toggle_mode(true); override_camera_button->set_disabled(true); _update_override_camera_button(false); - hb->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); view_menu = memnew(MenuButton); // TRANSLATORS: Noun, name of the 2D/3D View menus. view_menu->set_text(TTR("View")); view_menu->set_switch_on_hover(true); view_menu->set_shortcut_context(this); - hb->add_child(view_menu); + main_menu_hbox->add_child(view_menu); view_menu->get_popup()->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_popup_callback)); p = view_menu->get_popup(); @@ -5286,16 +5292,17 @@ CanvasItemEditor::CanvasItemEditor() { p->add_separator(); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KeyModifierMask::SHIFT | KeyModifierMask::CMD | Key::P), PREVIEW_CANVAS_SCALE); - hb->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); - context_menu_container = memnew(PanelContainer); - hbc_context_menu = memnew(HBoxContainer); - context_menu_container->add_child(hbc_context_menu); - hb->add_child(context_menu_container); + // Contextual toolbars. + context_menu_panel = memnew(PanelContainer); + context_menu_hbox = memnew(HBoxContainer); + context_menu_panel->add_child(context_menu_hbox); + main_flow->add_child(context_menu_panel); // Animation controls. animation_hb = memnew(HBoxContainer); - hbc_context_menu->add_child(animation_hb); + context_menu_hbox->add_child(animation_hb); animation_hb->add_child(memnew(VSeparator)); animation_hb->hide(); @@ -5369,7 +5376,7 @@ CanvasItemEditor::CanvasItemEditor() { add_child(selection_menu); selection_menu->set_min_size(Vector2(100, 0)); selection_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_selection_result_pressed)); - selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide)); + selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide), varray(), CONNECT_DEFERRED); add_node_menu = memnew(PopupMenu); add_child(add_node_menu); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 83685baf7a..5b368de3cc 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -188,11 +188,10 @@ private: HScrollBar *h_scroll = nullptr; VScrollBar *v_scroll = nullptr; - HBoxContainer *hb = nullptr; // Used for secondary menu items which are displayed depending on the currently selected node // (such as MeshInstance's "Mesh" menu). - PanelContainer *context_menu_container = nullptr; - HBoxContainer *hbc_context_menu = nullptr; + PanelContainer *context_menu_panel = nullptr; + HBoxContainer *context_menu_hbox = nullptr; Transform2D transform; GridVisibility grid_visibility = GRID_VISIBILITY_SHOW_WHEN_SNAPPING; @@ -503,8 +502,6 @@ protected: static void _bind_methods(); - HBoxContainer *get_panel_hb() { return hb; } - static CanvasItemEditor *singleton; public: @@ -633,4 +630,4 @@ public: ~CanvasItemEditorViewport(); }; -#endif //CANVAS_ITEM_EDITOR_PLUGIN_H +#endif // CANVAS_ITEM_EDITOR_PLUGIN_H diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index da9e9f339f..f7de05ddd1 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -112,4 +112,4 @@ public: ~CollisionShape2DEditorPlugin(); }; -#endif //COLLISION_SHAPE_2D_EDITOR_PLUGIN_H +#endif // COLLISION_SHAPE_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp index 4d77f71be9..ec038174fc 100644 --- a/editor/plugins/control_editor_plugin.cpp +++ b/editor/plugins/control_editor_plugin.cpp @@ -173,7 +173,7 @@ void EditorPropertyAnchorsPreset::setup(const Vector<String> &p_options) { Vector<String> split_after; split_after.append("Custom"); - split_after.append("PresetWide"); + split_after.append("PresetFullRect"); split_after.append("PresetBottomLeft"); split_after.append("PresetCenter"); @@ -181,24 +181,18 @@ void EditorPropertyAnchorsPreset::setup(const Vector<String> &p_options) { Vector<String> text_split = p_options[i].split(":"); int64_t current_val = text_split[1].to_int(); - String humanized_name = text_split[0]; - if (humanized_name.begins_with("Preset")) { - if (humanized_name == "PresetWide") { - humanized_name = "Full Rect"; - } else { - humanized_name = humanized_name.trim_prefix("Preset"); - humanized_name = humanized_name.capitalize(); - } - - String icon_name = text_split[0].trim_prefix("Preset"); - icon_name = "ControlAlign" + icon_name; + String option_name = text_split[0]; + if (option_name.begins_with("Preset")) { + String preset_name = option_name.trim_prefix("Preset"); + String humanized_name = preset_name.capitalize(); + String icon_name = "ControlAlign" + preset_name; options->add_icon_item(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(icon_name, "EditorIcons"), humanized_name); } else { - options->add_item(humanized_name); + options->add_item(option_name); } options->set_item_metadata(j, current_val); - if (split_after.has(text_split[0])) { + if (split_after.has(option_name)) { options->add_separator(); j++; } diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h index d3f1d3acbb..11389bc095 100644 --- a/editor/plugins/control_editor_plugin.h +++ b/editor/plugins/control_editor_plugin.h @@ -247,4 +247,4 @@ public: ControlEditorPlugin(); }; -#endif //CONTROL_EDITOR_PLUGIN_H +#endif // CONTROL_EDITOR_PLUGIN_H diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.h b/editor/plugins/cpu_particles_3d_editor_plugin.h index 70f2da4b2d..f38349985c 100644 --- a/editor/plugins/cpu_particles_3d_editor_plugin.h +++ b/editor/plugins/cpu_particles_3d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CPU_PARTICLES_EDITOR_PLUGIN_H -#define CPU_PARTICLES_EDITOR_PLUGIN_H +#ifndef CPU_PARTICLES_3D_EDITOR_PLUGIN_H +#define CPU_PARTICLES_3D_EDITOR_PLUGIN_H #include "editor/plugins/gpu_particles_3d_editor_plugin.h" #include "scene/3d/cpu_particles_3d.h" @@ -78,4 +78,4 @@ public: ~CPUParticles3DEditorPlugin(); }; -#endif // CPU_PARTICLES_EDITOR_PLUGIN_H +#endif // CPU_PARTICLES_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 66e58339ed..2954071054 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -542,11 +542,11 @@ void CurveEditor::update_view_transform() { const Vector2 scale = view_size / world_rect.size; Transform2D world_trans; - world_trans.translate(-world_rect.position - Vector2(0, world_rect.size.y)); + world_trans.translate_local(-world_rect.position - Vector2(0, world_rect.size.y)); world_trans.scale(Vector2(scale.x, -scale.y)); Transform2D view_trans; - view_trans.translate(view_margin); + view_trans.translate_local(view_margin); _world_to_view = view_trans * world_trans; } diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 478f4264e5..6b632101d3 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -599,7 +599,7 @@ Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const Ref<Resource> &p_f uint8_t *imgdata = img.ptrw(); uint8_t *imgw = imgdata; - Ref<AudioStreamPlayback> playback = stream->instance_playback(); + Ref<AudioStreamPlayback> playback = stream->instantiate_playback(); ERR_FAIL_COND_V(playback.is_null(), Ref<Texture2D>()); real_t len_s = stream->get_length(); diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index f548683b70..163cfe79f9 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITORPREVIEWPLUGINS_H -#define EDITORPREVIEWPLUGINS_H +#ifndef EDITOR_PREVIEW_PLUGINS_H +#define EDITOR_PREVIEW_PLUGINS_H #include "core/templates/safe_refcount.h" #include "editor/editor_resource_preview.h" @@ -193,4 +193,5 @@ public: EditorGradientPreviewPlugin(); }; -#endif // EDITORPREVIEWPLUGINS_H + +#endif // EDITOR_PREVIEW_PLUGINS_H diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp index 848fb5887d..a7b0f8b148 100644 --- a/editor/plugins/font_config_plugin.cpp +++ b/editor/plugins/font_config_plugin.cpp @@ -895,17 +895,45 @@ void FontPreview::_notification(int p_what) { Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); Color text_color = get_theme_color(SNAME("font_color"), SNAME("Label")); - font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + 2 * EDSCALE), name, HORIZONTAL_ALIGNMENT_CENTER, get_size().x, font_size, text_color); // Draw font preview. - Vector2 pos = Vector2(0, font->get_height(font_size)) + (get_size() - Vector2(0, font->get_height(font_size)) - line->get_size()) / 2; - line->draw(get_canvas_item(), pos, text_color); - - // Draw font baseline. - Color line_color = text_color; - line_color.a *= 0.6; - draw_line(Vector2(0, pos.y + line->get_line_ascent()), Vector2(pos.x - 5, pos.y + line->get_line_ascent()), line_color); - draw_line(Vector2(pos.x + line->get_size().x + 5, pos.y + line->get_line_ascent()), Vector2(get_size().x, pos.y + line->get_line_ascent()), line_color); + bool prev_ok = true; + if (prev_font.is_valid()) { + if (prev_font->get_font_name().is_empty()) { + prev_ok = false; + } else { + String name; + if (prev_font->get_font_style_name().is_empty()) { + name = prev_font->get_font_name(); + } else { + name = vformat("%s (%s)", prev_font->get_font_name(), prev_font->get_font_style_name()); + } + if (prev_font->is_class("FontVariation")) { + name += " " + TTR(" - Variation"); + } + font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + 2 * EDSCALE), name, HORIZONTAL_ALIGNMENT_CENTER, get_size().x, font_size, text_color); + + String sample; + static const String sample_base = U"12æ¼¢å—ԱբΑαÐбΑα×בابÜÜ’Þ€Þआআਆઆଆஆఆಆആආà¸à¸´àºàº´à¼€á€€á‚ áƒí•œê¸€áˆ€áŽ£áášáš ᜀᜠá€á កá á¤á¥Ab😀"; + for (int i = 0; i < sample_base.length(); i++) { + if (prev_font->has_char(sample_base[i])) { + sample += sample_base[i]; + } + } + if (sample.is_empty()) { + sample = prev_font->get_supported_chars().substr(0, 6); + } + if (sample.is_empty()) { + prev_ok = false; + } else { + prev_font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + prev_font->get_height(50)), sample, HORIZONTAL_ALIGNMENT_CENTER, get_size().x, 50, text_color); + } + } + } + if (!prev_ok) { + text_color.a *= 0.5; + font->draw_string(get_canvas_item(), Point2(0, font->get_height(font_size) + 2 * EDSCALE), TTR("Unable to preview font"), HORIZONTAL_ALIGNMENT_CENTER, get_size().x, font_size, text_color); + } } break; } } @@ -917,30 +945,11 @@ Size2 FontPreview::get_minimum_size() const { } void FontPreview::set_data(const Ref<Font> &p_f) { - line->clear(); - if (p_f.is_valid()) { - name = vformat("%s (%s)", p_f->get_font_name(), p_f->get_font_style_name()); - if (p_f->is_class("FontVariation")) { - name += " " + TTR(" - Variation"); - } - String sample; - static const String sample_base = U"12æ¼¢å—ԱբΑαÐбΑα×בابÜÜ’Þ€Þआআਆઆଆஆఆಆആආà¸à¸´àºàº´à¼€á€€á‚ áƒí•œê¸€áˆ€áŽ£áášáš ᜀᜠá€á កá á¤á¥Ab😀"; - for (int i = 0; i < sample_base.length(); i++) { - if (p_f->has_char(sample_base[i])) { - sample += sample_base[i]; - } - } - if (sample.is_empty()) { - sample = p_f->get_supported_chars().substr(0, 6); - } - line->add_string(sample, p_f, 50); - } - + prev_font = p_f; update(); } FontPreview::FontPreview() { - line.instantiate(); } /*************************************************************************/ @@ -965,6 +974,71 @@ bool EditorInspectorPluginFontPreview::parse_property(Object *p_object, const Va } /*************************************************************************/ +/* EditorPropertyFontNamesArray */ +/*************************************************************************/ + +void EditorPropertyFontNamesArray::_add_element() { + Size2 size = get_size(); + menu->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y)); + menu->reset_size(); + menu->popup(); +} + +void EditorPropertyFontNamesArray::_add_font(int p_option) { + if (updating) { + return; + } + + Variant array = object->get_array(); + int previous_size = array.call("size"); + + array.call("resize", previous_size + 1); + array.set(previous_size, menu->get_item_text(p_option)); + + emit_changed(get_edited_property(), array, "", false); + object->set_array(array); + update_property(); +} + +EditorPropertyFontNamesArray::EditorPropertyFontNamesArray() { + menu = memnew(PopupMenu); + menu->add_item("Sans-Serif", 0); + menu->add_item("Serif", 1); + menu->add_item("Monospace", 2); + menu->add_item("Fantasy", 3); + menu->add_item("Cursive", 4); + + menu->add_separator(); + + if (OS::get_singleton()) { + Vector<String> fonts = OS::get_singleton()->get_system_fonts(); + for (int i = 0; i < fonts.size(); i++) { + menu->add_item(fonts[i], i + 6); + } + } + add_child(menu); + menu->connect("id_pressed", callable_mp(this, &EditorPropertyFontNamesArray::_add_font)); +} + +/*************************************************************************/ +/* EditorInspectorPluginSystemFont */ +/*************************************************************************/ + +bool EditorInspectorPluginSystemFont::can_handle(Object *p_object) { + return Object::cast_to<SystemFont>(p_object) != nullptr; +} + +bool EditorInspectorPluginSystemFont::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) { + if (p_path == "font_names") { + EditorPropertyFontNamesArray *editor = memnew(EditorPropertyFontNamesArray); + editor->setup(p_type, p_hint_text); + add_property_editor(p_path, editor); + return true; + } + return false; +} + +/*************************************************************************/ /* FontEditorPlugin */ /*************************************************************************/ @@ -973,6 +1047,10 @@ FontEditorPlugin::FontEditorPlugin() { fc_plugin.instantiate(); EditorInspector::add_inspector_plugin(fc_plugin); + Ref<EditorInspectorPluginSystemFont> fs_plugin; + fs_plugin.instantiate(); + EditorInspector::add_inspector_plugin(fs_plugin); + Ref<EditorInspectorPluginFontPreview> fp_plugin; fp_plugin.instantiate(); EditorInspector::add_inspector_plugin(fp_plugin); diff --git a/editor/plugins/font_config_plugin.h b/editor/plugins/font_config_plugin.h index 9b7ee55870..3eaa2fdc17 100644 --- a/editor/plugins/font_config_plugin.h +++ b/editor/plugins/font_config_plugin.h @@ -28,12 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OT_FEATURES_PLUGIN_H -#define OT_FEATURES_PLUGIN_H +#ifndef FONT_CONFIG_PLUGIN_H +#define FONT_CONFIG_PLUGIN_H #include "core/io/marshalls.h" #include "editor/editor_plugin.h" #include "editor/editor_properties.h" +#include "editor/editor_properties_array_dict.h" /*************************************************************************/ @@ -225,8 +226,7 @@ protected: void _notification(int p_what); static void _bind_methods(); - String name; - Ref<TextLine> line; + Ref<Font> prev_font; public: virtual Size2 get_minimum_size() const override; @@ -249,6 +249,33 @@ public: /*************************************************************************/ +class EditorPropertyFontNamesArray : public EditorPropertyArray { + GDCLASS(EditorPropertyFontNamesArray, EditorPropertyArray); + + PopupMenu *menu = nullptr; + +protected: + virtual void _add_element() override; + + void _add_font(int p_option); + static void _bind_methods(){}; + +public: + EditorPropertyFontNamesArray(); +}; + +/*************************************************************************/ + +class EditorInspectorPluginSystemFont : public EditorInspectorPlugin { + GDCLASS(EditorInspectorPluginSystemFont, EditorInspectorPlugin); + +public: + virtual bool can_handle(Object *p_object) override; + virtual bool parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide = false) override; +}; + +/*************************************************************************/ + class FontEditorPlugin : public EditorPlugin { GDCLASS(FontEditorPlugin, EditorPlugin); @@ -258,4 +285,4 @@ public: virtual String get_name() const override { return "Font"; } }; -#endif // OT_FEATURES_PLUGIN_H +#endif // FONT_CONFIG_PLUGIN_H diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h index b91a17d9e5..b5eca46ad3 100644 --- a/editor/plugins/gdextension_export_plugin.h +++ b/editor/plugins/gdextension_export_plugin.h @@ -31,7 +31,7 @@ #ifndef GDEXTENSION_EXPORT_PLUGIN_H #define GDEXTENSION_EXPORT_PLUGIN_H -#include "editor/editor_export.h" +#include "editor/export/editor_export.h" class GDExtensionExportPlugin : public EditorExportPlugin { protected: diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.h b/editor/plugins/gpu_particles_2d_editor_plugin.h index 75f68617d1..bf49a82166 100644 --- a/editor/plugins/gpu_particles_2d_editor_plugin.h +++ b/editor/plugins/gpu_particles_2d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PARTICLES_2D_EDITOR_PLUGIN_H -#define PARTICLES_2D_EDITOR_PLUGIN_H +#ifndef GPU_PARTICLES_2D_EDITOR_PLUGIN_H +#define GPU_PARTICLES_2D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/2d/collision_polygon_2d.h" @@ -97,4 +97,4 @@ public: ~GPUParticles2DEditorPlugin(); }; -#endif // PARTICLES_2D_EDITOR_PLUGIN_H +#endif // GPU_PARTICLES_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.h b/editor/plugins/gpu_particles_3d_editor_plugin.h index 6ba6d102ef..17bdfa6e3f 100644 --- a/editor/plugins/gpu_particles_3d_editor_plugin.h +++ b/editor/plugins/gpu_particles_3d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PARTICLES_EDITOR_PLUGIN_H -#define PARTICLES_EDITOR_PLUGIN_H +#ifndef GPU_PARTICLES_3D_EDITOR_PLUGIN_H +#define GPU_PARTICLES_3D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/3d/gpu_particles_3d.h" @@ -114,4 +114,4 @@ public: ~GPUParticles3DEditorPlugin(); }; -#endif // PARTICLES_EDITOR_PLUGIN_H +#endif // GPU_PARTICLES_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp index 1386f03662..5c7047a81f 100644 --- a/editor/plugins/gradient_editor_plugin.cpp +++ b/editor/plugins/gradient_editor_plugin.cpp @@ -85,6 +85,7 @@ void GradientEditor::reverse_gradient() { } GradientEditor::GradientEditor() { + GradientEdit::get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(GradientEdit::get_picker())); editing = false; } diff --git a/editor/plugins/gradient_texture_2d_editor_plugin.h b/editor/plugins/gradient_texture_2d_editor_plugin.h index 4ce64ce1dc..93c49b1e6f 100644 --- a/editor/plugins/gradient_texture_2d_editor_plugin.h +++ b/editor/plugins/gradient_texture_2d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GRADIENT_TEXTURE_2D_EDITOR -#define GRADIENT_TEXTURE_2D_EDITOR +#ifndef GRADIENT_TEXTURE_2D_EDITOR_PLUGIN_H +#define GRADIENT_TEXTURE_2D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "editor/editor_spin_slider.h" @@ -109,4 +109,4 @@ public: GradientTexture2DEditorPlugin(); }; -#endif +#endif // GRADIENT_TEXTURE_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/lightmap_gi_editor_plugin.h b/editor/plugins/lightmap_gi_editor_plugin.h index 1202efe8fc..a06f97fc94 100644 --- a/editor/plugins/lightmap_gi_editor_plugin.h +++ b/editor/plugins/lightmap_gi_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BAKED_LIGHTMAP_EDITOR_PLUGIN_H -#define BAKED_LIGHTMAP_EDITOR_PLUGIN_H +#ifndef LIGHTMAP_GI_EDITOR_PLUGIN_H +#define LIGHTMAP_GI_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/3d/lightmap_gi.h" @@ -67,4 +67,4 @@ public: ~LightmapGIEditorPlugin(); }; -#endif +#endif // LIGHTMAP_GI_EDITOR_PLUGIN_H diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 34db75f118..e21cb7e76a 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -155,7 +155,9 @@ MaterialEditor::MaterialEditor() { camera = memnew(Camera3D); camera->set_transform(Transform3D(Basis(), Vector3(0, 0, 3))); - camera->set_perspective(45, 0.1, 10); + // Use low field of view so the sphere/box is fully encompassed within the preview, + // without much distortion. + camera->set_perspective(20, 0.1, 10); camera->make_current(); viewport->add_child(camera); @@ -177,8 +179,8 @@ MaterialEditor::MaterialEditor() { Transform3D box_xform; box_xform.basis.rotate(Vector3(1, 0, 0), Math::deg2rad(25.0)); box_xform.basis = box_xform.basis * Basis().rotated(Vector3(0, 1, 0), Math::deg2rad(-25.0)); - box_xform.basis.scale(Vector3(0.8, 0.8, 0.8)); - box_xform.origin.y = 0.2; + box_xform.basis.scale(Vector3(0.7, 0.7, 0.7)); + box_xform.origin.y = 0.05; box_instance->set_transform(box_xform); sphere_mesh.instantiate(); diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h index 3554b3c1e9..fb61f03485 100644 --- a/editor/plugins/mesh_editor_plugin.h +++ b/editor/plugins/mesh_editor_plugin.h @@ -87,4 +87,4 @@ public: MeshEditorPlugin(); }; -#endif +#endif // MESH_EDITOR_PLUGIN_H diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h index 36d8eacd98..7968176744 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.h +++ b/editor/plugins/mesh_instance_3d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef MESH_INSTANCE_EDITOR_PLUGIN_H -#define MESH_INSTANCE_EDITOR_PLUGIN_H +#ifndef MESH_INSTANCE_3D_EDITOR_PLUGIN_H +#define MESH_INSTANCE_3D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/3d/mesh_instance_3d.h" @@ -97,4 +97,4 @@ public: ~MeshInstance3DEditorPlugin(); }; -#endif // MESH_EDITOR_PLUGIN_H +#endif // MESH_INSTANCE_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h index 7550b75fa3..239da88ba2 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.h +++ b/editor/plugins/navigation_polygon_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NAVIGATIONPOLYGONEDITORPLUGIN_H -#define NAVIGATIONPOLYGONEDITORPLUGIN_H +#ifndef NAVIGATION_POLYGON_EDITOR_PLUGIN_H +#define NAVIGATION_POLYGON_EDITOR_PLUGIN_H #include "editor/plugins/abstract_polygon_2d_editor.h" #include "scene/2d/navigation_region_2d.h" @@ -67,4 +67,4 @@ public: NavigationPolygonEditorPlugin(); }; -#endif // NAVIGATIONPOLYGONEDITORPLUGIN_H +#endif // NAVIGATION_POLYGON_EDITOR_PLUGIN_H diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 6eef85d8b2..f7a2915ea2 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -5080,8 +5080,8 @@ Basis JointGizmosDrawer::look_body_toward_z(const Transform3D &p_joint_transform void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const Transform3D &p_offset, const Basis &p_base, real_t p_limit_lower, real_t p_limit_upper, Vector<Vector3> &r_points, bool p_inverse) { if (p_limit_lower == p_limit_upper) { - r_points.push_back(p_offset.translated(Vector3()).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3(0.5, 0, 0))).origin); + r_points.push_back(p_offset.translated_local(Vector3()).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(0.5, 0, 0))).origin); } else { if (p_limit_lower > p_limit_upper) { @@ -5123,20 +5123,20 @@ void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const } if (i == points - 1) { - r_points.push_back(p_offset.translated(to).origin); - r_points.push_back(p_offset.translated(Vector3()).origin); + r_points.push_back(p_offset.translated_local(to).origin); + r_points.push_back(p_offset.translated_local(Vector3()).origin); } if (i == 0) { - r_points.push_back(p_offset.translated(from).origin); - r_points.push_back(p_offset.translated(Vector3()).origin); + r_points.push_back(p_offset.translated_local(from).origin); + r_points.push_back(p_offset.translated_local(Vector3()).origin); } - r_points.push_back(p_offset.translated(from).origin); - r_points.push_back(p_offset.translated(to).origin); + r_points.push_back(p_offset.translated_local(from).origin); + r_points.push_back(p_offset.translated_local(to).origin); } - r_points.push_back(p_offset.translated(Vector3(0, p_radius * 1.5, 0)).origin); - r_points.push_back(p_offset.translated(Vector3()).origin); + r_points.push_back(p_offset.translated_local(Vector3(0, p_radius * 1.5, 0)).origin); + r_points.push_back(p_offset.translated_local(Vector3()).origin); } } @@ -5152,17 +5152,17 @@ void JointGizmosDrawer::draw_cone(const Transform3D &p_offset, const Basis &p_ba Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w; - r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, a.x, a.y))).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, b.x, b.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, a.x, a.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, b.x, b.y))).origin); if (i % 90 == 0) { - r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, a.x, a.y))).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3())).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, a.x, a.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3())).origin); } } - r_points.push_back(p_offset.translated(p_base.xform(Vector3())).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3(1, 0, 0))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3())).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(1, 0, 0))).origin); /// Twist float ts = Math::rad2deg(p_twist); @@ -5176,8 +5176,8 @@ void JointGizmosDrawer::draw_cone(const Transform3D &p_offset, const Basis &p_ba Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w * c; Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w * cn; - r_points.push_back(p_offset.translated(p_base.xform(Vector3(c, a.x, a.y))).origin); - r_points.push_back(p_offset.translated(p_base.xform(Vector3(cn, b.x, b.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(c, a.x, a.y))).origin); + r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(cn, b.x, b.y))).origin); } } @@ -5361,17 +5361,17 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { void Joint3DGizmoPlugin::CreatePinJointGizmo(const Transform3D &p_offset, Vector<Vector3> &r_cursor_points) { float cs = 0.25; - r_cursor_points.push_back(p_offset.translated(Vector3(+cs, 0, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(-cs, 0, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, +cs, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, -cs, 0)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, +cs)).origin); - r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, -cs)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(+cs, 0, 0)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(-cs, 0, 0)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(0, +cs, 0)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(0, -cs, 0)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(0, 0, +cs)).origin); + r_cursor_points.push_back(p_offset.translated_local(Vector3(0, 0, -cs)).origin); } void Joint3DGizmoPlugin::CreateHingeJointGizmo(const Transform3D &p_offset, const Transform3D &p_trs_joint, const Transform3D &p_trs_body_a, const Transform3D &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) { - r_common_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin); - r_common_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin); + r_common_points.push_back(p_offset.translated_local(Vector3(0, 0, 0.5)).origin); + r_common_points.push_back(p_offset.translated_local(Vector3(0, 0, -0.5)).origin); if (!p_use_limit) { p_limit_upper = -1; @@ -5404,34 +5404,34 @@ void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform3D &p_offset, con p_linear_limit_upper = -p_linear_limit_upper; float cs = 0.25; - r_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin); - r_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin); + r_points.push_back(p_offset.translated_local(Vector3(0, 0, 0.5)).origin); + r_points.push_back(p_offset.translated_local(Vector3(0, 0, -0.5)).origin); if (p_linear_limit_lower >= p_linear_limit_upper) { - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, 0, 0)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, 0, 0)).origin); - - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, -cs)).origin); - - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, -cs)).origin); - r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, 0, 0)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, 0, 0)).origin); + + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, -cs)).origin); + + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, -cs)).origin); + r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, -cs)).origin); } else { - r_points.push_back(p_offset.translated(Vector3(+cs * 2, 0, 0)).origin); - r_points.push_back(p_offset.translated(Vector3(-cs * 2, 0, 0)).origin); + r_points.push_back(p_offset.translated_local(Vector3(+cs * 2, 0, 0)).origin); + r_points.push_back(p_offset.translated_local(Vector3(-cs * 2, 0, 0)).origin); } if (r_body_a_points) { @@ -5554,13 +5554,13 @@ void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo( break; } -#define ADD_VTX(x, y, z) \ - { \ - Vector3 v; \ - v[a1] = (x); \ - v[a2] = (y); \ - v[a3] = (z); \ - r_points.push_back(p_offset.translated(v).origin); \ +#define ADD_VTX(x, y, z) \ + { \ + Vector3 v; \ + v[a1] = (x); \ + v[a2] = (y); \ + v[a3] = (z); \ + r_points.push_back(p_offset.translated_local(v).origin); \ } if (enable_lin && lll >= lul) { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index a77521e5d4..48f1a7c44e 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -33,8 +33,8 @@ #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/input/input_map.h" -#include "core/math/camera_matrix.h" #include "core/math/math_funcs.h" +#include "core/math/projection.h" #include "core/os/keyboard.h" #include "core/templates/sort_array.h" #include "editor/debugger/editor_debugger_node.h" @@ -52,6 +52,7 @@ #include "scene/3d/visual_instance_3d.h" #include "scene/3d/world_environment.h" #include "scene/gui/center_container.h" +#include "scene/gui/flow_container.h" #include "scene/gui/subviewport_container.h" #include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" @@ -355,14 +356,14 @@ void Node3DEditorViewport::_update_camera(real_t p_interp_delta) { Transform3D Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) const { Transform3D camera_transform; - camera_transform.translate(p_cursor.pos); + camera_transform.translate_local(p_cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -p_cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot); if (orthogonal) { - camera_transform.translate(0, 0, (get_zfar() - get_znear()) / 2.0); + camera_transform.translate_local(0, 0, (get_zfar() - get_znear()) / 2.0); } else { - camera_transform.translate(0, 0, p_cursor.distance); + camera_transform.translate_local(0, 0, p_cursor.distance); } return camera_transform; @@ -514,7 +515,7 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) { } } -ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) { +ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const { Vector3 ray = _get_ray(p_pos); Vector3 pos = _get_ray_pos(p_pos); Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink(); @@ -641,7 +642,7 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayRe } Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { - CameraMatrix cm; + Projection cm; if (orthogonal) { cm.set_orthogonal(camera->get_size(), get_size().aspect(), get_znear() + p_vector3.z, get_zfar()); } else { @@ -650,10 +651,10 @@ Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { Vector2 screen_he = cm.get_viewport_half_extents(); Transform3D camera_transform; - camera_transform.translate(cursor.pos); + camera_transform.translate_local(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); - camera_transform.translate(0, 0, cursor.distance); + camera_transform.translate_local(0, 0, cursor.distance); return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_he.y, -(get_znear() + p_vector3.z))); } @@ -1259,7 +1260,9 @@ void Node3DEditorViewport::_surface_mouse_enter() { } void Node3DEditorViewport::_surface_mouse_exit() { - _remove_preview(); + _remove_preview_node(); + _reset_preview_material(); + _remove_preview_material(); } void Node3DEditorViewport::_surface_focus_enter() { @@ -2099,7 +2102,7 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const Transform3D camera_transform; - camera_transform.translate(cursor.pos); + camera_transform.translate_local(cursor.pos); camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot); camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot); const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis"); @@ -2109,7 +2112,7 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const (invert_y_axis ? -1 : 1) * p_relative.y * pan_speed, 0); translation *= cursor.distance / DISTANCE_DEFAULT; - camera_transform.translate(translation); + camera_transform.translate_local(translation); cursor.pos = camera_transform.origin; } @@ -2422,8 +2425,8 @@ void Node3DEditorViewport::_project_settings_changed() { const float fsr_sharpness = GLOBAL_GET("rendering/scaling_3d/fsr_sharpness"); viewport->set_fsr_sharpness(fsr_sharpness); - const float fsr_mipmap_bias = GLOBAL_GET("rendering/scaling_3d/fsr_mipmap_bias"); - viewport->set_fsr_mipmap_bias(fsr_mipmap_bias); + const float texture_mipmap_bias = GLOBAL_GET("rendering/textures/default_filters/texture_mipmap_bias"); + viewport->set_texture_mipmap_bias(texture_mipmap_bias); } void Node3DEditorViewport::_notification(int p_what) { @@ -2519,14 +2522,14 @@ void Node3DEditorViewport::_notification(int p_what) { const Vector3 offset(0.005, 0.005, 0.005); Basis aabb_s; aabb_s.scale(se->aabb.size + offset); - t.translate(se->aabb.position - offset / 2); + t.translate_local(se->aabb.position - offset / 2); t.basis = t.basis * aabb_s; } { const Vector3 offset(0.01, 0.01, 0.01); Basis aabb_s; aabb_s.scale(se->aabb.size + offset); - t_offset.translate(se->aabb.position - offset / 2); + t_offset.translate_local(se->aabb.position - offset / 2); t_offset.basis = t_offset.basis * aabb_s; } @@ -2702,6 +2705,13 @@ void Node3DEditorViewport::_notification(int p_what) { cinema_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); locked_label->add_theme_style_override("normal", gui_base->get_theme_stylebox(SNAME("Information3dViewport"), SNAME("EditorStyles"))); } break; + + case NOTIFICATION_DRAG_END: { + // Clear preview material when dropped outside applicable object. + if (spatial_editor->get_preview_material().is_valid() && !is_drag_successful()) { + _remove_preview_material(); + } + } break; } } @@ -3793,7 +3803,7 @@ Node *Node3DEditorViewport::_sanitize_preview_node(Node *p_node) const { return p_node; } -void Node3DEditorViewport::_create_preview(const Vector<String> &files) const { +void Node3DEditorViewport::_create_preview_node(const Vector<String> &files) const { for (int i = 0; i < files.size(); i++) { String path = files[i]; Ref<Resource> res = ResourceLoader::load(path); @@ -3820,7 +3830,7 @@ void Node3DEditorViewport::_create_preview(const Vector<String> &files) const { *preview_bounds = _calculate_spatial_bounds(preview_node); } -void Node3DEditorViewport::_remove_preview() { +void Node3DEditorViewport::_remove_preview_node() { if (preview_node->get_parent()) { for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { Node *node = preview_node->get_child(i); @@ -3831,6 +3841,106 @@ void Node3DEditorViewport::_remove_preview() { } } +bool Node3DEditorViewport::_apply_preview_material(ObjectID p_target, const Point2 &p_point) const { + _reset_preview_material(); + + if (p_target.is_null()) { + return false; + } + + spatial_editor->set_preview_material_target(p_target); + + Object *target_inst = ObjectDB::get_instance(p_target); + + bool is_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL); + + MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(target_inst); + if (is_ctrl && mesh_instance) { + Ref<Mesh> mesh = mesh_instance->get_mesh(); + int surface_count = mesh->get_surface_count(); + + Vector3 world_ray = _get_ray(p_point); + Vector3 world_pos = _get_ray_pos(p_point); + + int closest_surface = -1; + float closest_dist = 1e20; + + Transform3D gt = mesh_instance->get_global_transform(); + + Transform3D ai = gt.affine_inverse(); + Vector3 xform_ray = ai.basis.xform(world_ray).normalized(); + Vector3 xform_pos = ai.xform(world_pos); + + for (int surface = 0; surface < surface_count; surface++) { + Ref<TriangleMesh> surface_mesh = mesh->generate_surface_triangle_mesh(surface); + + Vector3 rpos, rnorm; + if (surface_mesh->intersect_ray(xform_pos, xform_ray, rpos, rnorm)) { + Vector3 hitpos = gt.xform(rpos); + + const real_t dist = world_pos.distance_to(hitpos); + + if (dist < 0) { + continue; + } + + if (dist < closest_dist) { + closest_surface = surface; + closest_dist = dist; + } + } + } + + if (closest_surface == -1) { + return false; + } + + if (spatial_editor->get_preview_material() != mesh_instance->get_surface_override_material(closest_surface)) { + spatial_editor->set_preview_material_surface(closest_surface); + spatial_editor->set_preview_reset_material(mesh_instance->get_surface_override_material(closest_surface)); + mesh_instance->set_surface_override_material(closest_surface, spatial_editor->get_preview_material()); + } + + return true; + } + + GeometryInstance3D *geometry_instance = Object::cast_to<GeometryInstance3D>(target_inst); + if (geometry_instance && spatial_editor->get_preview_material() != geometry_instance->get_material_override()) { + spatial_editor->set_preview_reset_material(geometry_instance->get_material_override()); + geometry_instance->set_material_override(spatial_editor->get_preview_material()); + return true; + } + + return false; +} + +void Node3DEditorViewport::_reset_preview_material() const { + ObjectID last_target = spatial_editor->get_preview_material_target(); + if (last_target.is_null()) { + return; + } + Object *last_target_inst = ObjectDB::get_instance(last_target); + + MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(last_target_inst); + GeometryInstance3D *geometry_instance = Object::cast_to<GeometryInstance3D>(last_target_inst); + if (mesh_instance && spatial_editor->get_preview_material_surface() != -1) { + mesh_instance->set_surface_override_material(spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_reset_material()); + spatial_editor->set_preview_material_surface(-1); + } else if (geometry_instance) { + geometry_instance->set_material_override(spatial_editor->get_preview_reset_material()); + } +} + +void Node3DEditorViewport::_remove_preview_material() { + preview_material_label->hide(); + preview_material_label_desc->hide(); + + spatial_editor->set_preview_material(Ref<Material>()); + spatial_editor->set_preview_reset_material(Ref<Material>()); + spatial_editor->set_preview_material_target(ObjectID()); + spatial_editor->set_preview_material_surface(-1); +} + bool Node3DEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) { if (p_desired_node->get_scene_file_path() == p_target_scene_path) { return true; @@ -3929,7 +4039,26 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po } void Node3DEditorViewport::_perform_drop_data() { - _remove_preview(); + if (spatial_editor->get_preview_material_target().is_valid()) { + GeometryInstance3D *geometry_instance = Object::cast_to<GeometryInstance3D>(ObjectDB::get_instance(spatial_editor->get_preview_material_target())); + MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(ObjectDB::get_instance(spatial_editor->get_preview_material_target())); + if (mesh_instance && spatial_editor->get_preview_material_surface() != -1) { + editor_data->get_undo_redo().create_action(vformat(TTR("Set Surface %d Override Material"), spatial_editor->get_preview_material_surface())); + editor_data->get_undo_redo().add_do_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_material()); + editor_data->get_undo_redo().add_undo_method(geometry_instance, "set_surface_override_material", spatial_editor->get_preview_material_surface(), spatial_editor->get_preview_reset_material()); + editor_data->get_undo_redo().commit_action(); + } else if (geometry_instance) { + editor_data->get_undo_redo().create_action(TTR("Set Material Override")); + editor_data->get_undo_redo().add_do_method(geometry_instance, "set_material_override", spatial_editor->get_preview_material()); + editor_data->get_undo_redo().add_undo_method(geometry_instance, "set_material_override", spatial_editor->get_preview_reset_material()); + editor_data->get_undo_redo().commit_action(); + } + + _remove_preview_material(); + return; + } + + _remove_preview_node(); Vector<String> error_files; @@ -3967,7 +4096,7 @@ void Node3DEditorViewport::_perform_drop_data() { bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { bool can_instantiate = false; - if (!preview_node->is_inside_tree()) { + if (!preview_node->is_inside_tree() && spatial_editor->get_preview_material().is_null()) { Dictionary d = p_data; if (d.has("type") && (String(d["type"]) == "files")) { Vector<String> files = d["files"]; @@ -3976,40 +4105,78 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); List<String> mesh_extensions; ResourceLoader::get_recognized_extensions_for_type("Mesh", &mesh_extensions); + List<String> material_extensions; + ResourceLoader::get_recognized_extensions_for_type("Material", &material_extensions); + List<String> texture_extensions; + ResourceLoader::get_recognized_extensions_for_type("Texture", &texture_extensions); for (int i = 0; i < files.size(); i++) { // Check if dragged files with mesh or scene extension can be created at least once. - if (mesh_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) { + if (mesh_extensions.find(files[i].get_extension()) || + scene_extensions.find(files[i].get_extension()) || + material_extensions.find(files[i].get_extension()) || + texture_extensions.find(files[i].get_extension())) { Ref<Resource> res = ResourceLoader::load(files[i]); if (res.is_null()) { continue; } Ref<PackedScene> scn = res; + Ref<Material> mat = res; + Ref<Texture2D> tex = res; if (scn.is_valid()) { Node *instantiated_scene = scn->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); if (!instantiated_scene) { continue; } memdelete(instantiated_scene); + } else if (mat.is_valid()) { + Ref<BaseMaterial3D> base_mat = res; + Ref<ShaderMaterial> shader_mat = res; + + if (base_mat.is_null() && !shader_mat.is_null()) { + break; + } + + spatial_editor->set_preview_material(mat); + break; + } else if (tex.is_valid()) { + Ref<StandardMaterial3D> new_mat = memnew(StandardMaterial3D); + new_mat->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, tex); + + spatial_editor->set_preview_material(new_mat); + break; + } else { + continue; } can_instantiate = true; break; } } if (can_instantiate) { - _create_preview(files); + _create_preview_node(files); } } } else { - can_instantiate = true; + if (preview_node->is_inside_tree()) { + can_instantiate = true; + } } if (can_instantiate) { Transform3D global_transform = Transform3D(Basis(), _get_instance_position(p_point)); preview_node->set_global_transform(global_transform); + return true; + } + + if (spatial_editor->get_preview_material().is_valid()) { + preview_material_label->show(); + preview_material_label_desc->show(); + + ObjectID new_preview_material_target = _select_ray(p_point); + return _apply_preview_material(new_preview_material_target, p_point); } - return can_instantiate; + return false; } void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { @@ -4047,7 +4214,7 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_ } else { accept->set_text(TTR("Cannot drag and drop into multiple selected nodes.")); accept->popup_centered(); - _remove_preview(); + _remove_preview_node(); return; } @@ -4698,6 +4865,23 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p zoom_limit_label->hide(); surface->add_child(zoom_limit_label); + preview_material_label = memnew(Label); + preview_material_label->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_LEFT); + preview_material_label->set_offset(Side::SIDE_TOP, -70 * EDSCALE); + preview_material_label->set_text(TTR("Overriding material...")); + preview_material_label->add_theme_color_override("font_color", Color(1, 1, 1, 1)); + preview_material_label->hide(); + surface->add_child(preview_material_label); + + preview_material_label_desc = memnew(Label); + preview_material_label_desc->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_LEFT); + preview_material_label_desc->set_offset(Side::SIDE_TOP, -50 * EDSCALE); + preview_material_label_desc->set_text(TTR("Drag and drop to override the material of any geometry node.\nHold Ctrl when dropping to override a specific surface.")); + preview_material_label_desc->add_theme_color_override("font_color", Color(0.8, 0.8, 0.8, 1)); + preview_material_label_desc->add_theme_constant_override("line_spacing", 0); + preview_material_label_desc->hide(); + surface->add_child(preview_material_label_desc); + frame_time_gradient = memnew(Gradient); // The color is set when the theme changes. frame_time_gradient->add_point(0.5, Color()); @@ -6638,7 +6822,7 @@ void Node3DEditor::_finish_grid() { } void Node3DEditor::update_grid() { - const Camera3D::Projection current_projection = viewports[0]->camera->get_projection(); + const Camera3D::ProjectionType current_projection = viewports[0]->camera->get_projection(); if (current_projection != grid_camera_last_update_perspective) { grid_init_draw = false; // redraw @@ -6983,7 +7167,7 @@ void Node3DEditor::_update_theme() { environ_sky_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor")))); environ_ground_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor")))); - context_menu_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles"))); + context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles"))); } void Node3DEditor::_notification(int p_what) { @@ -7072,11 +7256,11 @@ Vector<int> Node3DEditor::get_subgizmo_selection() { } void Node3DEditor::add_control_to_menu_panel(Control *p_control) { - hbc_context_menu->add_child(p_control); + context_menu_hbox->add_child(p_control); } void Node3DEditor::remove_control_from_menu_panel(Control *p_control) { - hbc_context_menu->remove_child(p_control); + context_menu_hbox->remove_child(p_control); } void Node3DEditor::set_can_preview(Camera3D *p_preview) { @@ -7530,8 +7714,13 @@ Node3DEditor::Node3DEditor() { camera_override_viewport_id = 0; - hbc_menu = memnew(HBoxContainer); - vbc->add_child(hbc_menu); + // A fluid container for all toolbars. + HFlowContainer *main_flow = memnew(HFlowContainer); + vbc->add_child(main_flow); + + // Main toolbars. + HBoxContainer *main_menu_hbox = memnew(HBoxContainer); + main_flow->add_child(main_menu_hbox); Vector<Variant> button_binds; button_binds.resize(1); @@ -7541,11 +7730,11 @@ Node3DEditor::Node3DEditor() { // This prevents the first button's hover/pressed effect from "touching" the panel's border, // which looks ugly. Control *margin_left = memnew(Control); - hbc_menu->add_child(margin_left); + main_menu_hbox->add_child(margin_left); margin_left->set_custom_minimum_size(Size2(2, 0) * EDSCALE); tool_button[TOOL_MODE_SELECT] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_MODE_SELECT]); + main_menu_hbox->add_child(tool_button[TOOL_MODE_SELECT]); tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true); tool_button[TOOL_MODE_SELECT]->set_flat(true); tool_button[TOOL_MODE_SELECT]->set_pressed(true); @@ -7554,10 +7743,10 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), Key::Q)); tool_button[TOOL_MODE_SELECT]->set_shortcut_context(this); tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.")); - hbc_menu->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); tool_button[TOOL_MODE_MOVE] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]); + main_menu_hbox->add_child(tool_button[TOOL_MODE_MOVE]); tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true); tool_button[TOOL_MODE_MOVE]->set_flat(true); button_binds.write[0] = MENU_TOOL_MOVE; @@ -7566,7 +7755,7 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_MODE_MOVE]->set_shortcut_context(this); tool_button[TOOL_MODE_ROTATE] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]); + main_menu_hbox->add_child(tool_button[TOOL_MODE_ROTATE]); tool_button[TOOL_MODE_ROTATE]->set_toggle_mode(true); tool_button[TOOL_MODE_ROTATE]->set_flat(true); button_binds.write[0] = MENU_TOOL_ROTATE; @@ -7575,7 +7764,7 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_MODE_ROTATE]->set_shortcut_context(this); tool_button[TOOL_MODE_SCALE] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]); + main_menu_hbox->add_child(tool_button[TOOL_MODE_SCALE]); tool_button[TOOL_MODE_SCALE]->set_toggle_mode(true); tool_button[TOOL_MODE_SCALE]->set_flat(true); button_binds.write[0] = MENU_TOOL_SCALE; @@ -7583,10 +7772,10 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_MODE_SCALE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_scale", TTR("Scale Mode"), Key::R)); tool_button[TOOL_MODE_SCALE]->set_shortcut_context(this); - hbc_menu->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); tool_button[TOOL_MODE_LIST_SELECT] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]); + main_menu_hbox->add_child(tool_button[TOOL_MODE_LIST_SELECT]); tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true); tool_button[TOOL_MODE_LIST_SELECT]->set_flat(true); button_binds.write[0] = MENU_TOOL_LIST_SELECT; @@ -7594,7 +7783,7 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show list of selectable nodes at position clicked.")); tool_button[TOOL_LOCK_SELECTED] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]); + main_menu_hbox->add_child(tool_button[TOOL_LOCK_SELECTED]); tool_button[TOOL_LOCK_SELECTED]->set_flat(true); button_binds.write[0] = MENU_LOCK_SELECTED; tool_button[TOOL_LOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); @@ -7603,7 +7792,7 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_LOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/lock_selected_nodes", TTR("Lock Selected Node(s)"), KeyModifierMask::CMD | Key::L)); tool_button[TOOL_UNLOCK_SELECTED] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]); + main_menu_hbox->add_child(tool_button[TOOL_UNLOCK_SELECTED]); tool_button[TOOL_UNLOCK_SELECTED]->set_flat(true); button_binds.write[0] = MENU_UNLOCK_SELECTED; tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); @@ -7612,7 +7801,7 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_UNLOCK_SELECTED]->set_shortcut(ED_SHORTCUT("editor/unlock_selected_nodes", TTR("Unlock Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::L)); tool_button[TOOL_GROUP_SELECTED] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_GROUP_SELECTED]); + main_menu_hbox->add_child(tool_button[TOOL_GROUP_SELECTED]); tool_button[TOOL_GROUP_SELECTED]->set_flat(true); button_binds.write[0] = MENU_GROUP_SELECTED; tool_button[TOOL_GROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); @@ -7621,7 +7810,7 @@ Node3DEditor::Node3DEditor() { tool_button[TOOL_GROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/group_selected_nodes", TTR("Group Selected Node(s)"), KeyModifierMask::CMD | Key::G)); tool_button[TOOL_UNGROUP_SELECTED] = memnew(Button); - hbc_menu->add_child(tool_button[TOOL_UNGROUP_SELECTED]); + main_menu_hbox->add_child(tool_button[TOOL_UNGROUP_SELECTED]); tool_button[TOOL_UNGROUP_SELECTED]->set_flat(true); button_binds.write[0] = MENU_UNGROUP_SELECTED; tool_button[TOOL_UNGROUP_SELECTED]->connect("pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed), button_binds); @@ -7629,10 +7818,10 @@ Node3DEditor::Node3DEditor() { // Define the shortcut globally (without a context) so that it works if the Scene tree dock is currently focused. tool_button[TOOL_UNGROUP_SELECTED]->set_shortcut(ED_SHORTCUT("editor/ungroup_selected_nodes", TTR("Ungroup Selected Node(s)"), KeyModifierMask::CMD | KeyModifierMask::SHIFT | Key::G)); - hbc_menu->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); tool_option_button[TOOL_OPT_LOCAL_COORDS] = memnew(Button); - hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]); + main_menu_hbox->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]); tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_toggle_mode(true); tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true); button_binds.write[0] = MENU_TOOL_LOCAL_COORDS; @@ -7641,7 +7830,7 @@ Node3DEditor::Node3DEditor() { tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_shortcut_context(this); tool_option_button[TOOL_OPT_USE_SNAP] = memnew(Button); - hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]); + main_menu_hbox->add_child(tool_option_button[TOOL_OPT_USE_SNAP]); tool_option_button[TOOL_OPT_USE_SNAP]->set_toggle_mode(true); tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true); button_binds.write[0] = MENU_TOOL_USE_SNAP; @@ -7649,10 +7838,10 @@ Node3DEditor::Node3DEditor() { tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut(ED_SHORTCUT("spatial_editor/snap", TTR("Use Snap"), Key::Y)); tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut_context(this); - hbc_menu->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); tool_option_button[TOOL_OPT_OVERRIDE_CAMERA] = memnew(Button); - hbc_menu->add_child(tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]); + main_menu_hbox->add_child(tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]); tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_toggle_mode(true); tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_flat(true); tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_disabled(true); @@ -7660,7 +7849,7 @@ Node3DEditor::Node3DEditor() { tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->connect("toggled", callable_mp(this, &Node3DEditor::_menu_item_toggled), button_binds); _update_camera_override_button(false); - hbc_menu->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); sun_button = memnew(Button); sun_button->set_tooltip(TTR("Toggle preview sunlight.\nIf a DirectionalLight3D node is added to the scene, preview sunlight is disabled.")); sun_button->set_toggle_mode(true); @@ -7668,7 +7857,7 @@ Node3DEditor::Node3DEditor() { sun_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED); sun_button->set_disabled(true); - hbc_menu->add_child(sun_button); + main_menu_hbox->add_child(sun_button); environ_button = memnew(Button); environ_button->set_tooltip(TTR("Toggle preview environment.\nIf a WorldEnvironment node is added to the scene, preview environment is disabled.")); @@ -7677,16 +7866,16 @@ Node3DEditor::Node3DEditor() { environ_button->connect("pressed", callable_mp(this, &Node3DEditor::_update_preview_environment), varray(), CONNECT_DEFERRED); environ_button->set_disabled(true); - hbc_menu->add_child(environ_button); + main_menu_hbox->add_child(environ_button); sun_environ_settings = memnew(Button); sun_environ_settings->set_tooltip(TTR("Edit Sun and Environment settings.")); sun_environ_settings->set_flat(true); sun_environ_settings->connect("pressed", callable_mp(this, &Node3DEditor::_sun_environ_settings_pressed)); - hbc_menu->add_child(sun_environ_settings); + main_menu_hbox->add_child(sun_environ_settings); - hbc_menu->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); // Drag and drop support; preview_node = memnew(Node3D); @@ -7720,7 +7909,7 @@ Node3DEditor::Node3DEditor() { transform_menu->set_text(TTR("Transform")); transform_menu->set_switch_on_hover(true); transform_menu->set_shortcut_context(this); - hbc_menu->add_child(transform_menu); + main_menu_hbox->add_child(transform_menu); p = transform_menu->get_popup(); p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap Object to Floor"), Key::PAGEDOWN), MENU_SNAP_TO_FLOOR); @@ -7736,14 +7925,14 @@ Node3DEditor::Node3DEditor() { view_menu->set_text(TTR("View")); view_menu->set_switch_on_hover(true); view_menu->set_shortcut_context(this); - hbc_menu->add_child(view_menu); + main_menu_hbox->add_child(view_menu); - hbc_menu->add_child(memnew(VSeparator)); + main_menu_hbox->add_child(memnew(VSeparator)); - context_menu_container = memnew(PanelContainer); - hbc_context_menu = memnew(HBoxContainer); - context_menu_container->add_child(hbc_context_menu); - hbc_menu->add_child(context_menu_container); + context_menu_panel = memnew(PanelContainer); + context_menu_hbox = memnew(HBoxContainer); + context_menu_panel->add_child(context_menu_hbox); + main_flow->add_child(context_menu_panel); // Get the view menu popup and have it stay open when a checkable item is selected p = view_menu->get_popup(); @@ -8023,6 +8212,7 @@ void fragment() { sun_color->set_edit_alpha(false); sun_vb->add_margin_child(TTR("Sun Color"), sun_color); sun_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + sun_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(sun_color->get_picker())); sun_energy = memnew(EditorSpinSlider); sun_vb->add_margin_child(TTR("Sun Energy"), sun_energy); @@ -8068,10 +8258,12 @@ void fragment() { environ_sky_color = memnew(ColorPickerButton); environ_sky_color->set_edit_alpha(false); environ_sky_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + environ_sky_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(environ_sky_color->get_picker())); environ_vb->add_margin_child(TTR("Sky Color"), environ_sky_color); environ_ground_color = memnew(ColorPickerButton); environ_ground_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); environ_ground_color->set_edit_alpha(false); + environ_ground_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(environ_ground_color->get_picker())); environ_vb->add_margin_child(TTR("Ground Color"), environ_ground_color); environ_energy = memnew(EditorSpinSlider); environ_energy->connect("value_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); @@ -8132,7 +8324,6 @@ void fragment() { _preview_settings_changed(); } } - Node3DEditor::~Node3DEditor() { memdelete(preview_node); } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 8a602be08b..4469271a38 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -227,6 +227,9 @@ private: Label *locked_label = nullptr; Label *zoom_limit_label = nullptr; + Label *preview_material_label = nullptr; + Label *preview_material_label_desc = nullptr; + VBoxContainer *top_right_vbox = nullptr; ViewportRotationControl *rotation_control = nullptr; Gradient *frame_time_gradient = nullptr; @@ -244,7 +247,7 @@ private: void _compute_edit(const Point2 &p_point); void _clear_selected(); void _select_clicked(bool p_allow_locked); - ObjectID _select_ray(const Point2 &p_pos); + ObjectID _select_ray(const Point2 &p_pos) const; void _find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked); Vector3 _get_ray_pos(const Vector2 &p_pos) const; Vector3 _get_ray(const Vector2 &p_pos) const; @@ -272,6 +275,7 @@ private: float get_fov() const; ObjectID clicked; + ObjectID material_target; Vector<_RayResult> selection_results; bool clicked_wants_append = false; bool selection_in_progress = false; @@ -399,8 +403,11 @@ private: Node *_sanitize_preview_node(Node *p_node) const; - void _create_preview(const Vector<String> &files) const; - void _remove_preview(); + void _create_preview_node(const Vector<String> &files) const; + void _remove_preview_node(); + bool _apply_preview_material(ObjectID p_target, const Point2 &p_point) const; + void _reset_preview_material() const; + void _remove_preview_material(); bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); bool _create_instance(Node *parent, String &path, const Point2 &p_point); void _perform_drop_data(); @@ -560,7 +567,7 @@ private: bool grid_enable[3]; //should be always visible if true bool grid_enabled = false; bool grid_init_draw = false; - Camera3D::Projection grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; + Camera3D::ProjectionType grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; Vector3 grid_camera_last_update_position = Vector3(); Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3]; @@ -593,6 +600,11 @@ private: Node3D *preview_node = nullptr; AABB preview_bounds; + Ref<Material> preview_material; + Ref<Material> preview_reset_material; + ObjectID preview_material_target; + int preview_material_surface = -1; + struct Gizmo { bool visible = false; real_t scale = 0; @@ -664,11 +676,10 @@ private: void _menu_gizmo_toggled(int p_option); void _update_camera_override_button(bool p_game_running); void _update_camera_override_viewport(Object *p_viewport); - HBoxContainer *hbc_menu = nullptr; // Used for secondary menu items which are displayed depending on the currently selected node // (such as MeshInstance's "Mesh" menu). - PanelContainer *context_menu_container = nullptr; - HBoxContainer *hbc_context_menu = nullptr; + PanelContainer *context_menu_panel = nullptr; + HBoxContainer *context_menu_hbox = nullptr; void _generate_selection_boxes(); UndoRedo *undo_redo = nullptr; @@ -851,6 +862,15 @@ public: void set_can_preview(Camera3D *p_preview); + void set_preview_material(Ref<Material> p_material) { preview_material = p_material; } + Ref<Material> get_preview_material() { return preview_material; } + void set_preview_reset_material(Ref<Material> p_material) { preview_reset_material = p_material; } + Ref<Material> get_preview_reset_material() const { return preview_reset_material; } + void set_preview_material_target(ObjectID p_object_id) { preview_material_target = p_object_id; } + ObjectID get_preview_material_target() const { return preview_material_target; } + void set_preview_material_surface(int p_surface) { preview_material_surface = p_surface; } + int get_preview_material_surface() const { return preview_material_surface; } + Node3DEditorViewport *get_editor_viewport(int p_idx) { ERR_FAIL_INDEX_V(p_idx, static_cast<int>(VIEWPORTS_COUNT), nullptr); return viewports[p_idx]; diff --git a/editor/plugins/occluder_instance_3d_editor_plugin.h b/editor/plugins/occluder_instance_3d_editor_plugin.h index 360b7297cf..e8d98927f4 100644 --- a/editor/plugins/occluder_instance_3d_editor_plugin.h +++ b/editor/plugins/occluder_instance_3d_editor_plugin.h @@ -63,4 +63,4 @@ public: ~OccluderInstance3DEditorPlugin(); }; -#endif +#endif // OCCLUDER_INSTANCE_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h index ee31fcf43d..53e4e2efa8 100644 --- a/editor/plugins/path_3d_editor_plugin.h +++ b/editor/plugins/path_3d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PATH_EDITOR_PLUGIN_H -#define PATH_EDITOR_PLUGIN_H +#ifndef PATH_3D_EDITOR_PLUGIN_H +#define PATH_3D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "editor/plugins/node_3d_editor_gizmos.h" @@ -118,4 +118,4 @@ public: ~Path3DEditorPlugin(); }; -#endif // PATH_EDITOR_PLUGIN_H +#endif // PATH_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/physical_bone_3d_editor_plugin.h b/editor/plugins/physical_bone_3d_editor_plugin.h index 93e722a432..f15eab7991 100644 --- a/editor/plugins/physical_bone_3d_editor_plugin.h +++ b/editor/plugins/physical_bone_3d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PHYSICAL_BONE_PLUGIN_H -#define PHYSICAL_BONE_PLUGIN_H +#ifndef PHYSICAL_BONE_3D_EDITOR_PLUGIN_H +#define PHYSICAL_BONE_3D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/3d/physics_body_3d.h" @@ -76,4 +76,4 @@ public: PhysicalBone3DEditorPlugin(); }; -#endif +#endif // PHYSICAL_BONE_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index fc545b44e8..14e3eb5402 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1862,16 +1862,10 @@ void ScriptTextEditor::_enable_code_editor() { color_picker = memnew(ColorPicker); color_picker->set_deferred_mode(true); color_picker->connect("color_changed", callable_mp(this, &ScriptTextEditor::_color_changed)); + color_panel->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(color_picker)); color_panel->add_child(color_picker); - // get default color picker mode from editor settings - int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode"); - color_picker->set_color_mode((ColorPicker::ColorModeType)default_color_mode); - - int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape"); - color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape); - quick_open = memnew(ScriptEditorQuickOpen); quick_open->connect("goto_line", callable_mp(this, &ScriptTextEditor::_goto_line)); add_child(quick_open); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 5f6c805173..54c72e4d27 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -45,6 +45,7 @@ #include "editor/shader_create_dialog.h" #include "scene/gui/split_container.h" #include "servers/display_server.h" +#include "servers/rendering/shader_preprocessor.h" #include "servers/rendering/shader_types.h" /*** SHADER SCRIPT EDITOR ****/ @@ -72,15 +73,65 @@ Ref<Shader> ShaderTextEditor::get_edited_shader() const { return shader; } +Ref<ShaderInclude> ShaderTextEditor::get_edited_shader_include() const { + return shader_inc; +} + void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader) { + set_edited_shader(p_shader, p_shader->get_code()); +} + +void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader, const String &p_code) { if (shader == p_shader) { return; } + if (shader.is_valid()) { + shader->disconnect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); + } shader = p_shader; + shader_inc = Ref<ShaderInclude>(); + + set_edited_code(p_code); + + if (shader.is_valid()) { + shader->connect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); + } +} + +void ShaderTextEditor::set_edited_shader_include(const Ref<ShaderInclude> &p_shader_inc) { + set_edited_shader_include(p_shader_inc, p_shader_inc->get_code()); +} + +void ShaderTextEditor::_shader_changed() { + // This function is used for dependencies (include changing changes main shader and forces it to revalidate) + if (block_shader_changed) { + return; + } + dependencies_version++; + _validate_script(); +} + +void ShaderTextEditor::set_edited_shader_include(const Ref<ShaderInclude> &p_shader_inc, const String &p_code) { + if (shader_inc == p_shader_inc) { + return; + } + if (shader_inc.is_valid()) { + shader_inc->disconnect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); + } + shader_inc = p_shader_inc; + shader = Ref<Shader>(); + + set_edited_code(p_code); + + if (shader_inc.is_valid()) { + shader_inc->connect(SNAME("changed"), callable_mp(this, &ShaderTextEditor::_shader_changed)); + } +} +void ShaderTextEditor::set_edited_code(const String &p_code) { _load_theme_settings(); - get_text_editor()->set_text(p_shader->get_code()); + get_text_editor()->set_text(p_code); get_text_editor()->clear_undo_history(); get_text_editor()->call_deferred(SNAME("set_h_scroll"), 0); get_text_editor()->call_deferred(SNAME("set_v_scroll"), 0); @@ -132,11 +183,12 @@ void ShaderTextEditor::_load_theme_settings() { syntax_highlighter->clear_keyword_colors(); - List<String> keywords; - ShaderLanguage::get_keyword_list(&keywords); const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); const Color control_flow_keyword_color = EDITOR_GET("text_editor/theme/highlighting/control_flow_keyword_color"); + List<String> keywords; + ShaderLanguage::get_keyword_list(&keywords); + for (const String &E : keywords) { if (ShaderLanguage::is_control_flow_keyword(E)) { syntax_highlighter->add_keyword_color(E, control_flow_keyword_color); @@ -145,11 +197,41 @@ void ShaderTextEditor::_load_theme_settings() { } } + List<String> pp_keywords; + ShaderPreprocessor::get_keyword_list(&pp_keywords, false); + + for (const String &E : pp_keywords) { + syntax_highlighter->add_keyword_color(E, keyword_color); + } + // Colorize built-ins like `COLOR` differently to make them easier // to distinguish from keywords at a quick glance. List<String> built_ins; - if (shader.is_valid()) { + + if (shader_inc.is_valid()) { + for (int i = 0; i < RenderingServer::SHADER_MAX; i++) { + for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) { + for (const KeyValue<StringName, ShaderLanguage::BuiltInInfo> &F : E.value.built_ins) { + built_ins.push_back(F.key); + } + } + + const Vector<ShaderLanguage::ModeInfo> &modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i)); + + for (int j = 0; j < modes.size(); j++) { + const ShaderLanguage::ModeInfo &info = modes[j]; + + if (!info.options.is_empty()) { + for (int k = 0; k < info.options.size(); k++) { + built_ins.push_back(String(info.name) + "_" + String(info.options[k])); + } + } else { + built_ins.push_back(String(info.name)); + } + } + } + } else if (shader.is_valid()) { for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode()))) { for (const KeyValue<StringName, ShaderLanguage::BuiltInInfo> &F : E.value.built_ins) { built_ins.push_back(F.key); @@ -191,8 +273,12 @@ void ShaderTextEditor::_load_theme_settings() { text_editor->add_auto_brace_completion_pair("/*", "*/"); } + // Colorize preprocessor include strings. + const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color"); + syntax_highlighter->add_color_region("\"", "\"", string_color, false); + if (warnings_panel) { - // Warnings panel + // Warnings panel. warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts"))); warnings_panel->add_theme_font_size_override("normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"))); } @@ -216,82 +302,204 @@ void ShaderTextEditor::_check_shader_mode() { } if (shader->get_mode() != mode) { + set_block_shader_changed(true); shader->set_code(get_text_editor()->get_text()); + set_block_shader_changed(false); _load_theme_settings(); } } -static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); - return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); +static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) { + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_variable); + return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); +} + +static String complete_from_path; + +static void _complete_include_paths_search(EditorFileSystemDirectory *p_efsd, List<ScriptLanguage::CodeCompletionOption> *r_options) { + if (!p_efsd) { + return; + } + for (int i = 0; i < p_efsd->get_file_count(); i++) { + if (p_efsd->get_file_type(i) == SNAME("ShaderInclude")) { + String path = p_efsd->get_file_path(i); + if (path.begins_with(complete_from_path)) { + path = path.replace_first(complete_from_path, ""); + } + r_options->push_back(ScriptLanguage::CodeCompletionOption(path, ScriptLanguage::CODE_COMPLETION_KIND_FILE_PATH)); + } + } + for (int j = 0; j < p_efsd->get_subdir_count(); j++) { + _complete_include_paths_search(p_efsd->get_subdir(j), r_options); + } +} + +static void _complete_include_paths(List<ScriptLanguage::CodeCompletionOption> *r_options) { + _complete_include_paths_search(EditorFileSystem::get_singleton()->get_filesystem(), r_options); } void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptLanguage::CodeCompletionOption> *r_options) { - _check_shader_mode(); + List<ScriptLanguage::CodeCompletionOption> pp_options; + ShaderPreprocessor preprocessor; + String code; + complete_from_path = (shader.is_valid() ? shader->get_path() : shader_inc->get_path()).get_base_dir(); + if (!complete_from_path.ends_with("/")) { + complete_from_path += "/"; + } + preprocessor.preprocess(p_code, code, nullptr, nullptr, nullptr, &pp_options, _complete_include_paths); + complete_from_path = String(); + if (pp_options.size()) { + for (const ScriptLanguage::CodeCompletionOption &E : pp_options) { + r_options->push_back(E); + } + return; + } ShaderLanguage sl; String calltip; - ShaderLanguage::ShaderCompileInfo info; + info.global_shader_uniform_type_func = _get_global_shader_uniform_type; + + if (shader.is_null()) { + info.is_include = true; + + sl.complete(code, info, r_options, calltip); + get_text_editor()->set_code_hint(calltip); + return; + } + _check_shader_mode(); info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())); info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())); info.shader_types = ShaderTypes::get_singleton()->get_types(); - info.global_variable_type_func = _get_global_variable_type; - - sl.complete(p_code, info, r_options, calltip); + sl.complete(code, info, r_options, calltip); get_text_editor()->set_code_hint(calltip); } void ShaderTextEditor::_validate_script() { - _check_shader_mode(); + emit_signal(SNAME("script_changed")); // Ensure to notify that it changed, so it is applied - String code = get_text_editor()->get_text(); - //List<StringName> params; - //shader->get_param_list(¶ms); + String code; - ShaderLanguage::ShaderCompileInfo info; - info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())); - info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())); - info.shader_types = ShaderTypes::get_singleton()->get_types(); - info.global_variable_type_func = _get_global_variable_type; - - ShaderLanguage sl; + if (shader.is_valid()) { + _check_shader_mode(); + code = shader->get_code(); + } else { + code = shader_inc->get_code(); + } - sl.enable_warning_checking(saved_warnings_enabled); - sl.set_warning_flags(saved_warning_flags); + ShaderPreprocessor preprocessor; + String code_pp; + String error_pp; + List<ShaderPreprocessor::FilePosition> err_positions; + last_compile_result = preprocessor.preprocess(code, code_pp, &error_pp, &err_positions); - last_compile_result = sl.compile(code, info); + for (int i = 0; i < get_text_editor()->get_line_count(); i++) { + get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); + } + set_error(""); + set_error_count(0); if (last_compile_result != OK) { - String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text(); + //preprocessor error + ERR_FAIL_COND(err_positions.size() == 0); + + String error_text = error_pp; + int error_line = err_positions.front()->get().line; + if (err_positions.size() == 1) { + // Error in main file + error_text = "error(" + itos(error_line) + "): " + error_text; + } else { + error_text = "error(" + itos(error_line) + ") in include " + err_positions.back()->get().file.get_file() + ":" + itos(err_positions.back()->get().line) + ": " + error_text; + set_error_count(err_positions.size() - 1); + } + set_error(error_text); - set_error_pos(sl.get_error_line() - 1, 0); + set_error_pos(error_line - 1, 0); for (int i = 0; i < get_text_editor()->get_line_count(); i++) { get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); } - get_text_editor()->set_line_background_color(sl.get_error_line() - 1, marked_line_color); + get_text_editor()->set_line_background_color(error_line - 1, marked_line_color); + + set_warning_count(0); + } else { - for (int i = 0; i < get_text_editor()->get_line_count(); i++) { - get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0)); + ShaderLanguage sl; + + sl.enable_warning_checking(saved_warnings_enabled); + uint32_t flags = saved_warning_flags; + if (shader.is_null()) { + if (flags & ShaderWarning::UNUSED_CONSTANT) { + flags &= ~(ShaderWarning::UNUSED_CONSTANT); + } + if (flags & ShaderWarning::UNUSED_FUNCTION) { + flags &= ~(ShaderWarning::UNUSED_FUNCTION); + } + if (flags & ShaderWarning::UNUSED_STRUCT) { + flags &= ~(ShaderWarning::UNUSED_STRUCT); + } + if (flags & ShaderWarning::UNUSED_UNIFORM) { + flags &= ~(ShaderWarning::UNUSED_UNIFORM); + } + if (flags & ShaderWarning::UNUSED_VARYING) { + flags &= ~(ShaderWarning::UNUSED_VARYING); + } } - set_error(""); - } + sl.set_warning_flags(flags); - if (warnings.size() > 0 || last_compile_result != OK) { - warnings_panel->clear(); - } - warnings.clear(); - for (List<ShaderWarning>::Element *E = sl.get_warnings_ptr(); E; E = E->next()) { - warnings.push_back(E->get()); - } - if (warnings.size() > 0 && last_compile_result == OK) { - warnings.sort_custom<WarningsComparator>(); - _update_warning_panel(); - } else { - set_warning_count(0); + ShaderLanguage::ShaderCompileInfo info; + info.global_shader_uniform_type_func = _get_global_shader_uniform_type; + + if (shader.is_null()) { + info.is_include = true; + } else { + Shader::Mode mode = shader->get_mode(); + info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(mode)); + info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(mode)); + info.shader_types = ShaderTypes::get_singleton()->get_types(); + } + + code = code_pp; + //compiler error + last_compile_result = sl.compile(code, info); + + if (last_compile_result != OK) { + String error_text; + int error_line; + Vector<ShaderLanguage::FilePosition> include_positions = sl.get_include_positions(); + if (include_positions.size() > 1) { + //error is in an include + error_line = include_positions[0].line; + error_text = "error(" + itos(error_line) + ") in include " + include_positions[include_positions.size() - 1].file + ":" + itos(include_positions[include_positions.size() - 1].line) + ": " + sl.get_error_text(); + set_error_count(include_positions.size() - 1); + } else { + error_line = sl.get_error_line(); + error_text = "error(" + itos(error_line) + "): " + sl.get_error_text(); + set_error_count(0); + } + set_error(error_text); + set_error_pos(error_line - 1, 0); + get_text_editor()->set_line_background_color(error_line - 1, marked_line_color); + } else { + set_error(""); + } + + if (warnings.size() > 0 || last_compile_result != OK) { + warnings_panel->clear(); + } + warnings.clear(); + for (List<ShaderWarning>::Element *E = sl.get_warnings_ptr(); E; E = E->next()) { + warnings.push_back(E->get()); + } + if (warnings.size() > 0 && last_compile_result == OK) { + warnings.sort_custom<WarningsComparator>(); + _update_warning_panel(); + } else { + set_warning_count(0); + } } - emit_signal(SNAME("script_changed")); + + emit_signal(SNAME("script_validated"), last_compile_result == OK); // Notify that validation finished, to update the list of scripts } void ShaderTextEditor::_update_warning_panel() { @@ -338,6 +546,7 @@ void ShaderTextEditor::_update_warning_panel() { } void ShaderTextEditor::_bind_methods() { + ADD_SIGNAL(MethodInfo("script_validated", PropertyInfo(Variant::BOOL, "valid"))); } ShaderTextEditor::ShaderTextEditor() { @@ -473,6 +682,8 @@ void ShaderEditor::_warning_clicked(Variant p_line) { void ShaderEditor::_bind_methods() { ClassDB::bind_method("_show_warnings_panel", &ShaderEditor::_show_warnings_panel); ClassDB::bind_method("_warning_clicked", &ShaderEditor::_warning_clicked); + + ADD_SIGNAL(MethodInfo("validation_changed")); } void ShaderEditor::ensure_select_current() { @@ -524,15 +735,23 @@ void ShaderEditor::_update_warnings(bool p_validate) { } void ShaderEditor::_check_for_external_edit() { - if (shader.is_null() || !shader.is_valid()) { + bool use_autoreload = bool(EDITOR_GET("text_editor/behavior/files/auto_reload_scripts_on_external_change")); + + if (shader_inc.is_valid()) { + if (shader_inc->get_last_modified_time() != FileAccess::get_modified_time(shader_inc->get_path())) { + if (use_autoreload) { + _reload_shader_include_from_disk(); + } else { + disk_changed->call_deferred(SNAME("popup_centered")); + } + } return; } - if (shader->is_built_in()) { + if (shader.is_null() || shader->is_built_in()) { return; } - bool use_autoreload = bool(EDITOR_GET("text_editor/behavior/files/auto_reload_scripts_on_external_change")); if (shader->get_last_modified_time() != FileAccess::get_modified_time(shader->get_path())) { if (use_autoreload) { _reload_shader_from_disk(); @@ -546,11 +765,32 @@ void ShaderEditor::_reload_shader_from_disk() { Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_FAIL_COND(!rel_shader.is_valid()); + shader_editor->set_block_shader_changed(true); shader->set_code(rel_shader->get_code()); + shader_editor->set_block_shader_changed(false); shader->set_last_modified_time(rel_shader->get_last_modified_time()); shader_editor->reload_text(); } +void ShaderEditor::_reload_shader_include_from_disk() { + Ref<ShaderInclude> rel_shader_include = ResourceLoader::load(shader_inc->get_path(), shader_inc->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_FAIL_COND(!rel_shader_include.is_valid()); + + shader_editor->set_block_shader_changed(true); + shader_inc->set_code(rel_shader_include->get_code()); + shader_editor->set_block_shader_changed(false); + shader_inc->set_last_modified_time(rel_shader_include->get_last_modified_time()); + shader_editor->reload_text(); +} + +void ShaderEditor::_reload() { + if (shader.is_valid()) { + _reload_shader_from_disk(); + } else if (shader_inc.is_valid()) { + _reload_shader_include_from_disk(); + } +} + void ShaderEditor::edit(const Ref<Shader> &p_shader) { if (p_shader.is_null() || !p_shader->is_text_shader()) { return; @@ -561,37 +801,79 @@ void ShaderEditor::edit(const Ref<Shader> &p_shader) { } shader = p_shader; + shader_inc = Ref<ShaderInclude>(); + + shader_editor->set_edited_shader(shader); +} - shader_editor->set_edited_shader(p_shader); +void ShaderEditor::edit(const Ref<ShaderInclude> &p_shader_inc) { + if (p_shader_inc.is_null()) { + return; + } + + if (shader_inc == p_shader_inc) { + return; + } + + shader_inc = p_shader_inc; + shader = Ref<Shader>(); - //vertex_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_VERTEX); - // see if already has it + shader_editor->set_edited_shader_include(p_shader_inc); } void ShaderEditor::save_external_data(const String &p_str) { - if (shader.is_null()) { + if (shader.is_null() && shader_inc.is_null()) { disk_changed->hide(); return; } apply_shaders(); - if (!shader->is_built_in()) { - //external shader, save it + + Ref<Shader> edited_shader = shader_editor->get_edited_shader(); + if (edited_shader.is_valid()) { + ResourceSaver::save(edited_shader->get_path(), edited_shader); + } + if (shader.is_valid() && shader != edited_shader) { ResourceSaver::save(shader->get_path(), shader); } + Ref<ShaderInclude> edited_shader_inc = shader_editor->get_edited_shader_include(); + if (edited_shader_inc.is_valid()) { + ResourceSaver::save(edited_shader_inc->get_path(), edited_shader_inc); + } + if (shader_inc.is_valid() && shader_inc != edited_shader_inc) { + ResourceSaver::save(shader_inc->get_path(), shader_inc); + } + disk_changed->hide(); } +void ShaderEditor::validate_script() { + shader_editor->_validate_script(); +} + void ShaderEditor::apply_shaders() { + String editor_code = shader_editor->get_text_editor()->get_text(); if (shader.is_valid()) { String shader_code = shader->get_code(); - String editor_code = shader_editor->get_text_editor()->get_text(); - if (shader_code != editor_code) { + if (shader_code != editor_code || dependencies_version != shader_editor->get_dependencies_version()) { + shader_editor->set_block_shader_changed(true); shader->set_code(editor_code); + shader_editor->set_block_shader_changed(false); shader->set_edited(true); } } + if (shader_inc.is_valid()) { + String shader_inc_code = shader_inc->get_code(); + if (shader_inc_code != editor_code || dependencies_version != shader_editor->get_dependencies_version()) { + shader_editor->set_block_shader_changed(true); + shader_inc->set_code(editor_code); + shader_editor->set_block_shader_changed(false); + shader_inc->set_edited(true); + } + } + + dependencies_version = shader_editor->get_dependencies_version(); } void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { @@ -704,6 +986,9 @@ ShaderEditor::ShaderEditor() { _update_warnings(false); shader_editor = memnew(ShaderTextEditor); + + shader_editor->connect("script_validated", callable_mp(this, &ShaderEditor::_script_validated)); + shader_editor->set_v_size_flags(SIZE_EXPAND_FILL); shader_editor->add_theme_constant_override("separation", 0); shader_editor->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); @@ -829,7 +1114,7 @@ ShaderEditor::ShaderEditor() { dl->set_text(TTR("This shader has been modified on disk.\nWhat action should be taken?")); vbc->add_child(dl); - disk_changed->connect("confirmed", callable_mp(this, &ShaderEditor::_reload_shader_from_disk)); + disk_changed->connect("confirmed", callable_mp(this, &ShaderEditor::_reload)); disk_changed->set_ok_button_text(TTR("Reload")); disk_changed->add_button(TTR("Resave"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); @@ -844,19 +1129,37 @@ void ShaderEditorPlugin::_update_shader_list() { shader_list->clear(); for (uint32_t i = 0; i < edited_shaders.size(); i++) { String text; - String path = edited_shaders[i].shader->get_path(); - String _class = edited_shaders[i].shader->get_class(); + String path; + String _class; + String shader_name; + if (edited_shaders[i].shader.is_valid()) { + Ref<Shader> shader = edited_shaders[i].shader; + + path = shader->get_path(); + _class = shader->get_class(); + shader_name = shader->get_name(); + } else { + Ref<ShaderInclude> shader_inc = edited_shaders[i].shader_inc; + + path = shader_inc->get_path(); + _class = shader_inc->get_class(); + shader_name = shader_inc->get_name(); + } if (path.is_resource_file()) { text = path.get_file(); - } else if (edited_shaders[i].shader->get_name() != "") { - text = edited_shaders[i].shader->get_name(); + } else if (shader_name != "") { + text = shader_name; } else { - text = _class + ":" + itos(edited_shaders[i].shader->get_instance_id()); + if (edited_shaders[i].shader.is_valid()) { + text = _class + ":" + itos(edited_shaders[i].shader->get_instance_id()); + } else { + text = _class + ":" + itos(edited_shaders[i].shader_inc->get_instance_id()); + } } if (!shader_list->has_theme_icon(_class, SNAME("EditorIcons"))) { - _class = "Resource"; + _class = "TextFile"; } Ref<Texture2D> icon = shader_list->get_theme_icon(_class, SNAME("EditorIcons")); @@ -871,38 +1174,70 @@ void ShaderEditorPlugin::_update_shader_list() { for (int i = 1; i < FILE_MAX; i++) { file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), edited_shaders.size() == 0); } + + _update_shader_list_status(); } -void ShaderEditorPlugin::edit(Object *p_object) { - Shader *s = Object::cast_to<Shader>(p_object); - for (uint32_t i = 0; i < edited_shaders.size(); i++) { - if (edited_shaders[i].shader.ptr() == s) { - // Exists, select. - shader_tabs->set_current_tab(i); - shader_list->select(i); - return; +void ShaderEditorPlugin::_update_shader_list_status() { + for (int i = 0; i < shader_list->get_item_count(); i++) { + ShaderEditor *se = Object::cast_to<ShaderEditor>(shader_tabs->get_tab_control(i)); + if (se) { + if (se->was_compilation_successful()) { + shader_list->set_item_tag_icon(i, Ref<Texture2D>()); + } else { + shader_list->set_item_tag_icon(i, shader_list->get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); + } } } - // Add. +} + +void ShaderEditorPlugin::edit(Object *p_object) { EditedShader es; - es.shader = Ref<Shader>(s); - Ref<VisualShader> vs = es.shader; - if (vs.is_valid()) { - es.visual_shader_editor = memnew(VisualShaderEditor); - es.visual_shader_editor->edit(vs.ptr()); - shader_tabs->add_child(es.visual_shader_editor); - } else { + + ShaderInclude *si = Object::cast_to<ShaderInclude>(p_object); + if (si != nullptr) { + for (uint32_t i = 0; i < edited_shaders.size(); i++) { + if (edited_shaders[i].shader_inc.ptr() == si) { + shader_tabs->set_current_tab(i); + shader_list->select(i); + return; + } + } + es.shader_inc = Ref<ShaderInclude>(si); es.shader_editor = memnew(ShaderEditor); - es.shader_editor->edit(s); + es.shader_editor->edit(si); shader_tabs->add_child(es.shader_editor); + es.shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list_status)); + } else { + Shader *s = Object::cast_to<Shader>(p_object); + for (uint32_t i = 0; i < edited_shaders.size(); i++) { + if (edited_shaders[i].shader.ptr() == s) { + shader_tabs->set_current_tab(i); + shader_list->select(i); + return; + } + } + es.shader = Ref<Shader>(s); + Ref<VisualShader> vs = es.shader; + if (vs.is_valid()) { + es.visual_shader_editor = memnew(VisualShaderEditor); + shader_tabs->add_child(es.visual_shader_editor); + es.visual_shader_editor->edit(vs.ptr()); + } else { + es.shader_editor = memnew(ShaderEditor); + shader_tabs->add_child(es.shader_editor); + es.shader_editor->edit(s); + es.shader_editor->connect("validation_changed", callable_mp(this, &ShaderEditorPlugin::_update_shader_list_status)); + } } + shader_tabs->set_current_tab(shader_tabs->get_tab_count() - 1); edited_shaders.push_back(es); _update_shader_list(); } bool ShaderEditorPlugin::handles(Object *p_object) const { - return Object::cast_to<Shader>(p_object) != nullptr; + return Object::cast_to<Shader>(p_object) != nullptr || Object::cast_to<ShaderInclude>(p_object) != nullptr; } void ShaderEditorPlugin::make_visible(bool p_visible) { @@ -949,6 +1284,9 @@ void ShaderEditorPlugin::apply_changes() { } void ShaderEditorPlugin::_shader_selected(int p_index) { + if (edited_shaders[p_index].shader_editor) { + edited_shaders[p_index].shader_editor->validate_script(); + } shader_tabs->set_current_tab(p_index); } @@ -975,31 +1313,56 @@ void ShaderEditorPlugin::_resource_saved(Object *obj) { void ShaderEditorPlugin::_menu_item_pressed(int p_index) { switch (p_index) { case FILE_NEW: { - String base_path = FileSystemDock::get_singleton()->get_current_path(); + String base_path = FileSystemDock::get_singleton()->get_current_path().get_base_dir(); shader_create_dialog->config(base_path.plus_file("new_shader"), false, false, 0); shader_create_dialog->popup_centered(); } break; + case FILE_NEW_INCLUDE: { + String base_path = FileSystemDock::get_singleton()->get_current_path().get_base_dir(); + shader_create_dialog->config(base_path.plus_file("new_shader"), false, false, 2); + shader_create_dialog->popup_centered(); + } break; case FILE_OPEN: { InspectorDock::get_singleton()->open_resource("Shader"); } break; + case FILE_OPEN_INCLUDE: { + InspectorDock::get_singleton()->open_resource("ShaderInclude"); + } break; case FILE_SAVE: { int index = shader_tabs->get_current_tab(); ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); - EditorNode::get_singleton()->save_resource(edited_shaders[index].shader); + if (edited_shaders[index].shader.is_valid()) { + EditorNode::get_singleton()->save_resource(edited_shaders[index].shader); + } else { + EditorNode::get_singleton()->save_resource(edited_shaders[index].shader_inc); + } } break; case FILE_SAVE_AS: { int index = shader_tabs->get_current_tab(); ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); - String path = edited_shaders[index].shader->get_path(); - if (!path.is_resource_file()) { - path = ""; + String path; + if (edited_shaders[index].shader.is_valid()) { + path = edited_shaders[index].shader->get_path(); + if (!path.is_resource_file()) { + path = ""; + } + EditorNode::get_singleton()->save_resource_as(edited_shaders[index].shader, path); + } else { + path = edited_shaders[index].shader_inc->get_path(); + if (!path.is_resource_file()) { + path = ""; + } + EditorNode::get_singleton()->save_resource_as(edited_shaders[index].shader_inc, path); } - EditorNode::get_singleton()->save_resource_as(edited_shaders[index].shader, path); } break; case FILE_INSPECT: { int index = shader_tabs->get_current_tab(); ERR_FAIL_INDEX(index, shader_tabs->get_tab_count()); - EditorNode::get_singleton()->push_item(edited_shaders[index].shader.ptr()); + if (edited_shaders[index].shader.is_valid()) { + EditorNode::get_singleton()->push_item(edited_shaders[index].shader.ptr()); + } else { + EditorNode::get_singleton()->push_item(edited_shaders[index].shader_inc.ptr()); + } } break; case FILE_CLOSE: { _close_shader(shader_tabs->get_current_tab()); @@ -1011,6 +1374,10 @@ void ShaderEditorPlugin::_shader_created(Ref<Shader> p_shader) { EditorNode::get_singleton()->push_item(p_shader.ptr()); } +void ShaderEditorPlugin::_shader_include_created(Ref<ShaderInclude> p_shader_inc) { + EditorNode::get_singleton()->push_item(p_shader_inc.ptr()); +} + ShaderEditorPlugin::ShaderEditorPlugin() { main_split = memnew(HSplitContainer); @@ -1021,18 +1388,20 @@ ShaderEditorPlugin::ShaderEditorPlugin() { file_menu = memnew(MenuButton); file_menu->set_text(TTR("File")); file_menu->get_popup()->add_item(TTR("New Shader"), FILE_NEW); + file_menu->get_popup()->add_item(TTR("New Shader Include"), FILE_NEW_INCLUDE); file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_item(TTR("Load Shader"), FILE_OPEN); - file_menu->get_popup()->add_item(TTR("Save Shader"), FILE_SAVE); - file_menu->get_popup()->add_item(TTR("Save Shader As"), FILE_SAVE_AS); + file_menu->get_popup()->add_item(TTR("Load Shader File"), FILE_OPEN); + file_menu->get_popup()->add_item(TTR("Load Shader Include File"), FILE_OPEN_INCLUDE); + file_menu->get_popup()->add_item(TTR("Save File"), FILE_SAVE); + file_menu->get_popup()->add_item(TTR("Save File As"), FILE_SAVE_AS); file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_item(TTR("Open Shader in Inspector"), FILE_INSPECT); + file_menu->get_popup()->add_item(TTR("Open File in Inspector"), FILE_INSPECT); file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_item(TTR("Close Shader"), FILE_CLOSE); + file_menu->get_popup()->add_item(TTR("Close File"), FILE_CLOSE); file_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed)); file_hb->add_child(file_menu); - for (int i = 1; i < FILE_MAX; i++) { + for (int i = 2; i < FILE_MAX; i++) { file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), true); } @@ -1060,6 +1429,7 @@ ShaderEditorPlugin::ShaderEditorPlugin() { shader_create_dialog = memnew(ShaderCreateDialog); vb->add_child(shader_create_dialog); shader_create_dialog->connect("shader_created", callable_mp(this, &ShaderEditorPlugin::_shader_created)); + shader_create_dialog->connect("shader_include_created", callable_mp(this, &ShaderEditorPlugin::_shader_include_created)); } ShaderEditorPlugin::~ShaderEditorPlugin() { diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index 2e0dbe0d60..907de6ea87 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -40,6 +40,7 @@ #include "scene/gui/text_edit.h" #include "scene/main/timer.h" #include "scene/resources/shader.h" +#include "scene/resources/shader_include.h" #include "servers/rendering/shader_warnings.h" class ItemList; @@ -59,12 +60,18 @@ class ShaderTextEditor : public CodeTextEditor { Ref<CodeHighlighter> syntax_highlighter; RichTextLabel *warnings_panel = nullptr; Ref<Shader> shader; + Ref<ShaderInclude> shader_inc; List<ShaderWarning> warnings; Error last_compile_result = Error::OK; void _check_shader_mode(); void _update_warning_panel(); + bool block_shader_changed = false; + void _shader_changed(); + + uint32_t dependencies_version = 0; // Incremented if deps changed + protected: void _notification(int p_what); static void _bind_methods(); @@ -73,13 +80,23 @@ protected: virtual void _code_complete_script(const String &p_code, List<ScriptLanguage::CodeCompletionOption> *r_options) override; public: + void set_block_shader_changed(bool p_block) { block_shader_changed = p_block; } + uint32_t get_dependencies_version() const { return dependencies_version; } + virtual void _validate_script() override; void reload_text(); void set_warnings_panel(RichTextLabel *p_warnings_panel); Ref<Shader> get_edited_shader() const; + Ref<ShaderInclude> get_edited_shader_include() const; + void set_edited_shader(const Ref<Shader> &p_shader); + void set_edited_shader(const Ref<Shader> &p_shader, const String &p_code); + void set_edited_shader_include(const Ref<ShaderInclude> &p_include); + void set_edited_shader_include(const Ref<ShaderInclude> &p_include, const String &p_code); + void set_edited_code(const String &p_code); + ShaderTextEditor(); }; @@ -126,38 +143,50 @@ class ShaderEditor : public PanelContainer { ConfirmationDialog *disk_changed = nullptr; ShaderTextEditor *shader_editor = nullptr; + bool compilation_success = true; void _menu_option(int p_option); mutable Ref<Shader> shader; + mutable Ref<ShaderInclude> shader_inc; void _editor_settings_changed(); void _project_settings_changed(); void _check_for_external_edit(); void _reload_shader_from_disk(); + void _reload_shader_include_from_disk(); + void _reload(); void _show_warnings_panel(bool p_show); void _warning_clicked(Variant p_line); void _update_warnings(bool p_validate); + void _script_validated(bool p_valid) { + compilation_success = p_valid; + emit_signal(SNAME("validation_changed")); + } + + uint32_t dependencies_version = 0xFFFFFFFF; + protected: void _notification(int p_what); static void _bind_methods(); void _make_context_menu(bool p_selection, Vector2 p_position); - void _text_edit_gui_input(const Ref<InputEvent> &ev); + void _text_edit_gui_input(const Ref<InputEvent> &p_ev); void _update_bookmark_list(); void _bookmark_item_pressed(int p_idx); public: + bool was_compilation_successful() const { return compilation_success; } void apply_shaders(); - void ensure_select_current(); void edit(const Ref<Shader> &p_shader); - + void edit(const Ref<ShaderInclude> &p_shader_inc); void goto_line_selection(int p_line, int p_begin, int p_end); + void save_external_data(const String &p_str = ""); + void validate_script(); virtual Size2 get_minimum_size() const override { return Size2(0, 200); } - void save_external_data(const String &p_str = ""); ShaderEditor(); }; @@ -167,6 +196,7 @@ class ShaderEditorPlugin : public EditorPlugin { struct EditedShader { Ref<Shader> shader; + Ref<ShaderInclude> shader_inc; ShaderEditor *shader_editor = nullptr; VisualShaderEditor *visual_shader_editor = nullptr; }; @@ -175,7 +205,9 @@ class ShaderEditorPlugin : public EditorPlugin { enum { FILE_NEW, + FILE_NEW_INCLUDE, FILE_OPEN, + FILE_OPEN_INCLUDE, FILE_SAVE, FILE_SAVE_AS, FILE_INSPECT, @@ -199,6 +231,8 @@ class ShaderEditorPlugin : public EditorPlugin { void _close_shader(int p_index); void _shader_created(Ref<Shader> p_shader); + void _shader_include_created(Ref<ShaderInclude> p_shader_inc); + void _update_shader_list_status(); public: virtual String get_name() const override { return "Shader"; } @@ -218,4 +252,4 @@ public: ~ShaderEditorPlugin(); }; -#endif +#endif // SHADER_EDITOR_PLUGIN_H diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 93e44c8ca0..5d6c56d5f0 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -157,7 +157,7 @@ void BoneTransformEditor::_property_keyed(const String &p_path, bool p_advance) if (split.size() == 3 && split[0] == "bones") { int bone_idx = split[1].to_int(); if (split[2] == "position") { - te->insert_transform_key(skeleton, skeleton->get_bone_name(bone_idx), Animation::TYPE_POSITION_3D, skeleton->get(p_path)); + te->insert_transform_key(skeleton, skeleton->get_bone_name(bone_idx), Animation::TYPE_POSITION_3D, (Vector3)skeleton->get(p_path) / skeleton->get_motion_scale()); } if (split[2] == "rotation") { te->insert_transform_key(skeleton, skeleton->get_bone_name(bone_idx), Animation::TYPE_ROTATION_3D, skeleton->get(p_path)); @@ -319,7 +319,7 @@ void Skeleton3DEditor::insert_keys(const bool p_all_bones) { } if (pos_enabled && (p_all_bones || te->has_track(skeleton, name, Animation::TYPE_POSITION_3D))) { - te->insert_transform_key(skeleton, name, Animation::TYPE_POSITION_3D, skeleton->get_bone_pose_position(i)); + te->insert_transform_key(skeleton, name, Animation::TYPE_POSITION_3D, skeleton->get_bone_pose_position(i) / skeleton->get_motion_scale()); } if (rot_enabled && (p_all_bones || te->has_track(skeleton, name, Animation::TYPE_ROTATION_3D))) { te->insert_transform_key(skeleton, name, Animation::TYPE_ROTATION_3D, skeleton->get_bone_pose_rotation(i)); diff --git a/editor/plugins/sprite_2d_editor_plugin.h b/editor/plugins/sprite_2d_editor_plugin.h index 8e3dc19c7e..b87f108bd2 100644 --- a/editor/plugins/sprite_2d_editor_plugin.h +++ b/editor/plugins/sprite_2d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPRITE_EDITOR_PLUGIN_H -#define SPRITE_EDITOR_PLUGIN_H +#ifndef SPRITE_2D_EDITOR_PLUGIN_H +#define SPRITE_2D_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/2d/sprite_2d.h" @@ -111,4 +111,4 @@ public: ~Sprite2DEditorPlugin(); }; -#endif // SPRITE_EDITOR_PLUGIN_H +#endif // SPRITE_2D_EDITOR_PLUGIN_H diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h index 2f7f6f83bb..357bdb0845 100644 --- a/editor/plugins/texture_3d_editor_plugin.h +++ b/editor/plugins/texture_3d_editor_plugin.h @@ -91,4 +91,4 @@ public: Texture3DEditorPlugin(); }; -#endif // TEXTURE_EDITOR_PLUGIN_H +#endif // TEXTURE_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h index 830916e954..f49aa83eb2 100644 --- a/editor/plugins/texture_layered_editor_plugin.h +++ b/editor/plugins/texture_layered_editor_plugin.h @@ -93,4 +93,4 @@ public: TextureLayeredEditorPlugin(); }; -#endif // TEXTURE_EDITOR_PLUGIN_H +#endif // TEXTURE_LAYERED_EDITOR_PLUGIN_H diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index c725966745..744ed1f1a2 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -70,9 +70,17 @@ void ThemeItemImportTree::_update_items_tree() { for (const StringName &E : types) { String type_name = (String)E; + Ref<Texture2D> type_icon; + if (E == "") { + type_icon = get_theme_icon(SNAME("NodeDisabled"), SNAME("EditorIcons")); + } else { + type_icon = EditorNode::get_singleton()->get_class_icon(E, "NodeDisabled"); + } + TreeItem *type_node = import_items_tree->create_item(root); type_node->set_meta("_can_be_imported", false); type_node->set_collapsed(true); + type_node->set_icon(0, type_icon); type_node->set_text(0, type_name); type_node->set_cell_mode(IMPORT_ITEM, TreeItem::CELL_MODE_CHECK); type_node->set_checked(IMPORT_ITEM, false); @@ -214,7 +222,7 @@ void ThemeItemImportTree::_update_items_tree() { if (color_amount > 0) { Array arr; arr.push_back(color_amount); - select_colors_label->set_text(TTRN("One color", "{num} colors", color_amount).format(arr, "{num}")); + select_colors_label->set_text(TTRN("1 color", "{num} colors", color_amount).format(arr, "{num}")); select_all_colors_button->set_visible(true); select_full_colors_button->set_visible(true); deselect_all_colors_button->set_visible(true); @@ -228,7 +236,7 @@ void ThemeItemImportTree::_update_items_tree() { if (constant_amount > 0) { Array arr; arr.push_back(constant_amount); - select_constants_label->set_text(TTRN("One constant", "{num} constants", constant_amount).format(arr, "{num}")); + select_constants_label->set_text(TTRN("1 constant", "{num} constants", constant_amount).format(arr, "{num}")); select_all_constants_button->set_visible(true); select_full_constants_button->set_visible(true); deselect_all_constants_button->set_visible(true); @@ -242,7 +250,7 @@ void ThemeItemImportTree::_update_items_tree() { if (font_amount > 0) { Array arr; arr.push_back(font_amount); - select_fonts_label->set_text(TTRN("One font", "{num} fonts", font_amount).format(arr, "{num}")); + select_fonts_label->set_text(TTRN("1 font", "{num} fonts", font_amount).format(arr, "{num}")); select_all_fonts_button->set_visible(true); select_full_fonts_button->set_visible(true); deselect_all_fonts_button->set_visible(true); @@ -256,7 +264,7 @@ void ThemeItemImportTree::_update_items_tree() { if (font_size_amount > 0) { Array arr; arr.push_back(font_size_amount); - select_font_sizes_label->set_text(TTRN("One font size", "{num} font sizes", font_size_amount).format(arr, "{num}")); + select_font_sizes_label->set_text(TTRN("1 font size", "{num} font sizes", font_size_amount).format(arr, "{num}")); select_all_font_sizes_button->set_visible(true); select_full_font_sizes_button->set_visible(true); deselect_all_font_sizes_button->set_visible(true); @@ -270,7 +278,7 @@ void ThemeItemImportTree::_update_items_tree() { if (icon_amount > 0) { Array arr; arr.push_back(icon_amount); - select_icons_label->set_text(TTRN("One icon", "{num} icons", icon_amount).format(arr, "{num}")); + select_icons_label->set_text(TTRN("1 icon", "{num} icons", icon_amount).format(arr, "{num}")); select_all_icons_button->set_visible(true); select_full_icons_button->set_visible(true); deselect_all_icons_button->set_visible(true); @@ -286,7 +294,7 @@ void ThemeItemImportTree::_update_items_tree() { if (stylebox_amount > 0) { Array arr; arr.push_back(stylebox_amount); - select_styleboxes_label->set_text(TTRN("One stylebox", "{num} styleboxes", stylebox_amount).format(arr, "{num}")); + select_styleboxes_label->set_text(TTRN("1 stylebox", "{num} styleboxes", stylebox_amount).format(arr, "{num}")); select_all_styleboxes_button->set_visible(true); select_full_styleboxes_button->set_visible(true); deselect_all_styleboxes_button->set_visible(true); @@ -1170,6 +1178,8 @@ ThemeItemImportTree::ThemeItemImportTree() { import_add_selected_button->connect("pressed", callable_mp(this, &ThemeItemImportTree::_import_selected)); } +/////////////////////// + void ThemeItemEditorDialog::ok_pressed() { if (import_default_theme_items->has_selected_items() || import_editor_theme_items->has_selected_items() || import_other_theme_items->has_selected_items()) { confirm_closing_dialog->set_text(TTR("Import Items tab has some items selected. Selection will be lost upon closing this window.\nClose anyway?")); @@ -1867,6 +1877,8 @@ void ThemeItemEditorDialog::_notification(int p_what) { edit_items_remove_custom->set_icon(get_theme_icon(SNAME("ThemeRemoveCustomItems"), SNAME("EditorIcons"))); edit_items_remove_all->set_icon(get_theme_icon(SNAME("ThemeRemoveAllItems"), SNAME("EditorIcons"))); + edit_add_type_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons"))); + import_another_theme_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"))); } break; } @@ -1924,8 +1936,7 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito edit_add_type_value->set_h_size_flags(Control::SIZE_EXPAND_FILL); edit_add_type_value->connect("text_submitted", callable_mp(this, &ThemeItemEditorDialog::_add_theme_type)); edit_add_type_hb->add_child(edit_add_type_value); - Button *edit_add_type_button = memnew(Button); - edit_add_type_button->set_text(TTR("Add")); + edit_add_type_button = memnew(Button); edit_add_type_hb->add_child(edit_add_type_button); edit_add_type_button->connect("pressed", callable_mp(this, &ThemeItemEditorDialog::_add_theme_type), varray("")); @@ -2099,6 +2110,8 @@ ThemeItemEditorDialog::ThemeItemEditorDialog(ThemeTypeEditor *p_theme_type_edito confirm_closing_dialog->connect("confirmed", callable_mp(this, &ThemeItemEditorDialog::_close_dialog)); } +/////////////////////// + void ThemeTypeDialog::_dialog_about_to_show() { add_type_filter->set_text(""); add_type_filter->grab_focus(); @@ -2237,6 +2250,8 @@ ThemeTypeDialog::ThemeTypeDialog() { add_child(add_type_confirmation); } +/////////////////////// + VBoxContainer *ThemeTypeEditor::_create_item_list(Theme::DataType p_data_type) { VBoxContainer *items_tab = memnew(VBoxContainer); items_tab->set_custom_minimum_size(Size2(0, 160) * EDSCALE); @@ -2477,6 +2492,7 @@ void ThemeTypeEditor::_update_type_items() { if (E.value) { item_editor->set_pick_color(edited_theme->get_color(E.key, edited_type)); item_editor->connect("color_changed", callable_mp(this, &ThemeTypeEditor::_color_item_changed), varray(E.key)); + item_editor->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(item_editor->get_picker())); } else { item_editor->set_pick_color(Theme::get_default()->get_color(E.key, edited_type)); item_editor->set_disabled(true); @@ -3454,6 +3470,8 @@ ThemeTypeEditor::ThemeTypeEditor() { add_child(update_debounce_timer); } +/////////////////////// + void ThemeEditor::edit(const Ref<Theme> &p_theme) { if (theme == p_theme) { return; @@ -3672,6 +3690,8 @@ ThemeEditor::ThemeEditor() { theme_type_editor->set_custom_minimum_size(Size2(280, 0) * EDSCALE); } +/////////////////////// + void ThemeEditorPlugin::edit(Object *p_node) { if (Object::cast_to<Theme>(p_node)) { theme_editor->edit(Object::cast_to<Theme>(p_node)); diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index 543113a5eb..9f89a047cb 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -198,6 +198,7 @@ class ThemeItemEditorDialog : public AcceptDialog { Tree *edit_type_list = nullptr; LineEdit *edit_add_type_value = nullptr; + Button *edit_add_type_button = nullptr; String edited_item_type; Button *edit_items_add_color = nullptr; diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index ff46b7871f..196a642283 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -158,4 +158,4 @@ public: TileAtlasView(); }; -#endif // TILE_ATLAS_VIEW +#endif // TILE_ATLAS_VIEW_H diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index d914b9c363..69a3d4e937 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -3212,7 +3212,7 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() { terrains_tile_list->set_item_metadata(item_index, list_metadata_dict); item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_theme_icon(SNAME("TerrainPath"), SNAME("EditorIcons"))); - terrains_tile_list->set_item_tooltip(item_index, TTR("Path mode: paints a terrain, thens connects it to the previous tile painted withing the same stroke.")); + terrains_tile_list->set_item_tooltip(item_index, TTR("Path mode: paints a terrain, thens connects it to the previous tile painted within the same stroke.")); list_metadata_dict = Dictionary(); list_metadata_dict["type"] = SELECTED_TYPE_PATH; terrains_tile_list->set_item_metadata(item_index, list_metadata_dict); diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index ff586ebbfe..605fbe4823 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -377,4 +377,4 @@ public: static Vector<Vector2i> get_line(TileMap *p_tile_map, Vector2i p_from_cell, Vector2i p_to_cell); }; -#endif // TILE_MAP_EDITOR_PLUGIN_H +#endif // TILE_MAP_EDITOR_H diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 20e548acba..88bbd7f1dd 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -1822,7 +1822,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_unscaled_draw() { Vector2i position = texture_region.get_center() + tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0); Transform2D xform = tile_atlas_control->get_parent_control()->get_transform(); - xform.translate(position); + xform.translate_local(position); if (tools_button_group->get_pressed_button() == tool_select_button && selection.has({ coords, 0 })) { continue; @@ -1845,7 +1845,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_unscaled_draw() { Vector2i position = texture_region.get_center() + tile_set_atlas_source->get_tile_effective_texture_offset(E.tile, 0); Transform2D xform = tile_atlas_control->get_parent_control()->get_transform(); - xform.translate(position); + xform.translate_local(position); TileMapCell cell; cell.source_id = tile_set_atlas_source_id; @@ -1989,7 +1989,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { Vector2 position = rect.get_center(); Transform2D xform = alternative_tiles_control->get_parent_control()->get_transform(); - xform.translate(position); + xform.translate_local(position); if (tools_button_group->get_pressed_button() == tool_select_button && selection.has({ coords, alternative_tile })) { continue; @@ -2013,7 +2013,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_unscaled_draw() { Vector2 position = rect.get_center(); Transform2D xform = alternative_tiles_control->get_parent_control()->get_transform(); - xform.translate(position); + xform.translate_local(position); TileMapCell cell; cell.source_id = tile_set_atlas_source_id; diff --git a/editor/plugins/tiles/tile_set_editor.h b/editor/plugins/tiles/tile_set_editor.h index e633de37b0..c45240043e 100644 --- a/editor/plugins/tiles/tile_set_editor.h +++ b/editor/plugins/tiles/tile_set_editor.h @@ -108,4 +108,4 @@ public: ~TileSetEditor(); }; -#endif // TILE_SET_EDITOR_PLUGIN_H +#endif // TILE_SET_EDITOR_H diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h index 657bfca032..77a583e522 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.h @@ -142,4 +142,4 @@ public: ~TileSetScenesCollectionSourceEditor(); }; -#endif +#endif // TILE_SET_SCENES_COLLECTION_SOURCE_EDITOR_H diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index 419d0ffcfc..65dee0df1f 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -155,6 +155,9 @@ void TilesEditorPlugin::_update_editors() { // Update the viewport. CanvasItemEditor::get_singleton()->update_viewport(); + // Make sure the tile set editor is visible if we have one assigned. + tileset_editor_button->set_visible(is_visible && tile_set.is_valid()); + // Update visibility of bottom panel buttons. if (tileset_editor_button->is_pressed() && !tile_set.is_valid()) { if (tile_map) { @@ -181,12 +184,14 @@ void TilesEditorPlugin::_notification(int p_what) { } void TilesEditorPlugin::make_visible(bool p_visible) { - if (p_visible) { + is_visible = p_visible; + + if (is_visible) { // Disable and hide invalid editors. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id)); tileset_editor_button->set_visible(tile_set.is_valid()); tilemap_editor_button->set_visible(tile_map); - if (tile_map) { + if (tile_map && !is_editing_tile_set) { EditorNode::get_singleton()->make_bottom_panel_item_visible(tilemap_editor); } else { EditorNode::get_singleton()->make_bottom_panel_item_visible(tileset_editor); @@ -226,14 +231,14 @@ void TilesEditorPlugin::synchronize_sources_list(Object *p_current_list, Object } if (item_list->is_visible_in_tree()) { + // Make sure the selection is not overwritten after sorting. + int atlas_sources_lists_current_mem = atlas_sources_lists_current; + item_list->emit_signal(SNAME("sort_request")); + atlas_sources_lists_current = atlas_sources_lists_current_mem; + if (atlas_sources_lists_current < 0 || atlas_sources_lists_current >= item_list->get_item_count()) { item_list->deselect_all(); } else { - // Make sure the selection is not overwritten after sorting. - int atlas_sources_lists_current_mem = atlas_sources_lists_current; - item_list->emit_signal(SNAME("sort_request")); - atlas_sources_lists_current = atlas_sources_lists_current_mem; - item_list->set_current(atlas_sources_lists_current); item_list->ensure_current_is_visible(); item_list->emit_signal(SNAME("item_selected"), atlas_sources_lists_current); @@ -345,6 +350,8 @@ void TilesEditorPlugin::edit(Object *p_object) { // Update edited objects. tile_set = Ref<TileSet>(); + is_editing_tile_set = false; + if (p_object) { if (p_object->is_class("TileMap")) { tile_map_id = p_object->get_instance_id(); @@ -359,6 +366,7 @@ void TilesEditorPlugin::edit(Object *p_object) { tile_map_id = ObjectID(); } } + is_editing_tile_set = true; EditorNode::get_singleton()->make_bottom_panel_item_visible(tileset_editor); } } diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h index a22e782b34..b1fe6f8df6 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.h +++ b/editor/plugins/tiles/tiles_editor_plugin.h @@ -53,9 +53,12 @@ public: }; private: + bool is_visible = false; + bool tile_map_changed_needs_update = false; ObjectID tile_map_id; Ref<TileSet> tile_set; + bool is_editing_tile_set = false; Button *tilemap_editor_button = nullptr; TileMapEditor *tilemap_editor = nullptr; diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h index 39a56de772..fa721268ba 100644 --- a/editor/plugins/version_control_editor_plugin.h +++ b/editor/plugins/version_control_editor_plugin.h @@ -148,4 +148,4 @@ public: VARIANT_ENUM_CAST(VersionControlEditorPlugin::ChangeType); -#endif // !VERSION_CONTROL_EDITOR_PLUGIN_H +#endif // VERSION_CONTROL_EDITOR_PLUGIN_H diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 69a125a029..d6d45b8210 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -4563,9 +4563,9 @@ void VisualShaderEditor::_preview_size_changed() { preview_vbox->set_custom_minimum_size(preview_window->get_size()); } -static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable); - return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); +static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) { + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_variable); + return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); } void VisualShaderEditor::_update_preview() { @@ -4582,7 +4582,7 @@ void VisualShaderEditor::_update_preview() { info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode())); info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode())); info.shader_types = ShaderTypes::get_singleton()->get_types(); - info.global_variable_type_func = _get_global_variable_type; + info.global_shader_uniform_type_func = _get_global_shader_uniform_type; ShaderLanguage sl; diff --git a/editor/plugins/voxel_gi_editor_plugin.h b/editor/plugins/voxel_gi_editor_plugin.h index 621e98beef..43d6f71e26 100644 --- a/editor/plugins/voxel_gi_editor_plugin.h +++ b/editor/plugins/voxel_gi_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VOXEL_GIEDITORPLUGIN_H -#define VOXEL_GIEDITORPLUGIN_H +#ifndef VOXEL_GI_EDITOR_PLUGIN_H +#define VOXEL_GI_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" #include "scene/3d/voxel_gi.h" @@ -71,4 +71,4 @@ public: ~VoxelGIEditorPlugin(); }; -#endif // VOXEL_GIEDITORPLUGIN_H +#endif // VOXEL_GI_EDITOR_PLUGIN_H diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index 654ebf4573..97013da05e 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -120,7 +120,7 @@ static const char *enum_renames[][2] = { { "JOINT_PIN", "JOINT_TYPE_PIN" }, // PhysicsServer2D { "JOINT_SLIDER", "JOINT_TYPE_SLIDER" }, // PhysicsServer3D { "KEY_CONTROL", "KEY_CTRL" }, // Globals - { "LOOP_PING_PONG", "LOOP_PINGPONG" }, //AudioStreamSample + { "LOOP_PING_PONG", "LOOP_PINGPONG" }, // AudioStreamWAV { "MATH_RAND", "MATH_RANDF_RANGE" }, // VisualScriptBuiltinFunc { "MATH_RANDOM", "MATH_RANDI_RANGE" }, // VisualScriptBuiltinFunc { "MATH_STEPIFY", "MATH_STEP_DECIMALS" }, // VisualScriptBuiltinFunc @@ -1250,7 +1250,9 @@ static const char *class_renames[][2] = { { "AnimatedSprite", "AnimatedSprite2D" }, { "AnimationTreePlayer", "AnimationTree" }, { "Area", "Area3D" }, // Be careful, this will be used everywhere + { "AudioStreamOGGVorbis", "AudioStreamOggVorbis" }, { "AudioStreamRandomPitch", "AudioStreamRandomizer" }, + { "AudioStreamSample", "AudioStreamWAV" }, { "BakedLightmap", "LightmapGI" }, { "BakedLightmapData", "LightmapGIData" }, { "BitmapFont", "FontFile" }, @@ -2209,7 +2211,7 @@ bool ProjectConverter3To4::test_array_names() { // Callable is special class, to which normal classes may be renamed if (!ClassDB::class_exists(StringName(new_class)) && new_class != "Callable") { - ERR_PRINT(String("Class `") + new_class + "` doesn't exists in Godot 4.0, so cannot be used in convertion."); + ERR_PRINT(String("Class `") + new_class + "` doesn't exists in Godot 4.0, so cannot be used in conversion."); valid = false; // This probably should be only a warning, but not 100% sure - this would need to be added to CI } current_index++; @@ -2295,7 +2297,7 @@ bool ProjectConverter3To4::test_array_names() { } // Validate in one array if names don't do cyclic renames `Node` -> `Node2D` | `Node2D` -> `2DNode` -// Also checks if in name contains spaces at the end or beggining +// Also checks if in name contains spaces at the end or beginning bool ProjectConverter3To4::test_single_array(const char *array[][2], bool ignore_second_check) { bool valid = true; int current_index = 0; diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index a98578ad7d..327ff6bb2d 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1998,7 +1998,7 @@ void ProjectManager::shortcut_input(const Ref<InputEvent> &p_ev) { // Pressing Command + Q quits the Project Manager // This is handled by the platform implementation on macOS, // so only define the shortcut on other platforms -#ifndef OSX_ENABLED +#ifndef MACOS_ENABLED if (k->get_keycode_with_modifiers() == (KeyModifierMask::CMD | Key::Q)) { _dim_window(); get_tree()->quit(); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 49707355a0..be1ad1ca9c 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -31,7 +31,6 @@ #include "project_settings_editor.h" #include "core/config/project_settings.h" -#include "editor/editor_export.h" #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" @@ -670,10 +669,10 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { autoload_settings->connect("autoload_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); tab_container->add_child(autoload_settings); - shaders_global_variables_editor = memnew(ShaderGlobalsEditor); - shaders_global_variables_editor->set_name(TTR("Shader Globals")); - shaders_global_variables_editor->connect("globals_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); - tab_container->add_child(shaders_global_variables_editor); + shaders_global_shader_uniforms_editor = memnew(ShaderGlobalsEditor); + shaders_global_shader_uniforms_editor->set_name(TTR("Shader Globals")); + shaders_global_shader_uniforms_editor->connect("globals_changed", callable_mp(this, &ProjectSettingsEditor::queue_save)); + tab_container->add_child(shaders_global_shader_uniforms_editor); plugin_settings = memnew(EditorPluginSettings); plugin_settings->set_name(TTR("Plugins")); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index 24d61db443..455aaae11c 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -55,7 +55,7 @@ class ProjectSettingsEditor : public AcceptDialog { ActionMapEditor *action_map_editor = nullptr; LocalizationEditor *localization_editor = nullptr; EditorAutoloadSettings *autoload_settings = nullptr; - ShaderGlobalsEditor *shaders_global_variables_editor = nullptr; + ShaderGlobalsEditor *shaders_global_shader_uniforms_editor = nullptr; EditorPluginSettings *plugin_settings = nullptr; LineEdit *search_box = nullptr; diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 0693294316..86b6e4c6a5 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -43,7 +43,6 @@ #include "editor/array_property_edit.h" #include "editor/create_dialog.h" #include "editor/dictionary_property_edit.h" -#include "editor/editor_export.h" #include "editor/editor_file_dialog.h" #include "editor/editor_file_system.h" #include "editor/editor_help.h" @@ -828,13 +827,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: value_vbox->add_child(color_picker); color_picker->hide(); color_picker->connect("color_changed", callable_mp(this, &CustomPropertyEditor::_color_changed)); - - // get default color picker mode from editor settings - int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode"); - color_picker->set_color_mode((ColorPicker::ColorModeType)default_color_mode); - - int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape"); - color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape); + color_picker->connect("show", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker), varray(color_picker)); } color_picker->show(); diff --git a/editor/property_editor.h b/editor/property_editor.h index 3230834d00..27d1cabc3d 100644 --- a/editor/property_editor.h +++ b/editor/property_editor.h @@ -181,4 +181,4 @@ public: CustomPropertyEditor(); }; -#endif +#endif // PROPERTY_EDITOR_H diff --git a/editor/property_selector.h b/editor/property_selector.h index f42f5daa3f..e2bf5c02b7 100644 --- a/editor/property_selector.h +++ b/editor/property_selector.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PROPERTYSELECTOR_H -#define PROPERTYSELECTOR_H +#ifndef PROPERTY_SELECTOR_H +#define PROPERTY_SELECTOR_H #include "editor/editor_help.h" #include "editor/property_editor.h" @@ -80,4 +80,4 @@ public: PropertySelector(); }; -#endif // PROPERTYSELECTOR_H +#endif // PROPERTY_SELECTOR_H diff --git a/editor/register_exporters.h b/editor/register_exporters.h index 09076af978..9aa98f509f 100644 --- a/editor/register_exporters.h +++ b/editor/register_exporters.h @@ -33,4 +33,4 @@ void register_exporters(); -#endif +#endif // REGISTER_EXPORTERS_H diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index be37d50a2e..ca1771bedf 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -72,7 +72,7 @@ void SceneTreeDock::input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT)) { - if (mb->is_pressed() && scene_tree->get_rect().has_point(mb->get_position())) { + if (mb->is_pressed() && scene_tree->get_rect().has_point(scene_tree->get_local_mouse_position())) { tree_clicked = true; } else if (!mb->is_pressed()) { tree_clicked = false; @@ -1337,14 +1337,14 @@ void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root UndoRedo *undo_redo = &editor_data->get_undo_redo(); switch (p_mode) { case MODE_BIDI: { - bool is_unique = p_node->is_unique_name_in_owner() && p_base->get_node_or_null(UNIQUE_NODE_PREFIX + String(p_node->get_name())) != nullptr; - if (is_unique) { + bool disable_unique = p_node->is_unique_name_in_owner() && p_root->get_node_or_null(UNIQUE_NODE_PREFIX + String(p_node->get_name())) != nullptr; + if (disable_unique) { // Will create a unique name conflict. Disable before setting owner. undo_redo->add_do_method(p_node, "set_unique_name_in_owner", false); } undo_redo->add_do_method(p_node, "set_owner", p_root); undo_redo->add_undo_method(p_node, "set_owner", p_base); - if (is_unique) { + if (disable_unique) { // Will create a unique name conflict. Enable after setting owner. undo_redo->add_undo_method(p_node, "set_unique_name_in_owner", true); } diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index dc7f3476ee..e15865036b 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -33,8 +33,8 @@ #include "editor/create_dialog.h" #include "editor/editor_data.h" +#include "editor/editor_quick_open.h" #include "editor/groups_editor.h" -#include "editor/quick_open.h" #include "editor/reparent_dialog.h" #include "editor/script_create_dialog.h" #include "scene/animation/animation_player.h" diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 31a14e4667..31772e55b5 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -192,4 +192,4 @@ public: ~SceneTreeDialog(); }; -#endif +#endif // SCENE_TREE_EDITOR_H diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 28e1e9bf22..7ae03ee96f 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "editor/editor_file_dialog.h" #include "editor/editor_scale.h" +#include "scene/resources/shader_include.h" #include "scene/resources/visual_shader.h" #include "servers/rendering/shader_types.h" @@ -43,15 +44,15 @@ void ShaderCreateDialog::_notification(int p_what) { String last_lang = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_language", ""); if (!last_lang.is_empty()) { - for (int i = 0; i < language_menu->get_item_count(); i++) { - if (language_menu->get_item_text(i) == last_lang) { - language_menu->select(i); - current_language = i; + for (int i = 0; i < type_menu->get_item_count(); i++) { + if (type_menu->get_item_text(i) == last_lang) { + type_menu->select(i); + current_type = i; break; } } } else { - language_menu->select(default_language); + type_menu->select(default_type); } current_mode = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_mode", 0); @@ -67,12 +68,17 @@ void ShaderCreateDialog::_notification(int p_what) { void ShaderCreateDialog::_update_theme() { Ref<Texture2D> shader_icon = gc->get_theme_icon(SNAME("Shader"), SNAME("EditorIcons")); if (shader_icon.is_valid()) { - language_menu->set_item_icon(0, shader_icon); + type_menu->set_item_icon(0, shader_icon); } Ref<Texture2D> visual_shader_icon = gc->get_theme_icon(SNAME("VisualShader"), SNAME("EditorIcons")); if (visual_shader_icon.is_valid()) { - language_menu->set_item_icon(1, visual_shader_icon); + type_menu->set_item_icon(1, visual_shader_icon); + } + + Ref<Texture2D> include_icon = gc->get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")); + if (include_icon.is_valid()) { + type_menu->set_item_icon(2, include_icon); } path_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons"))); @@ -80,7 +86,7 @@ void ShaderCreateDialog::_update_theme() { } void ShaderCreateDialog::_update_language_info() { - language_data.clear(); + type_data.clear(); for (int i = 0; i < SHADER_TYPE_MAX; i++) { ShaderTypeData data; @@ -88,12 +94,15 @@ void ShaderCreateDialog::_update_language_info() { data.use_templates = true; data.extensions.push_back("gdshader"); data.default_extension = "gdshader"; + } else if (i == int(SHADER_TYPE_INC)) { + data.extensions.push_back("gdshaderinc"); + data.default_extension = "gdshaderinc"; } else { data.default_extension = "tres"; } data.extensions.push_back("res"); data.extensions.push_back("tres"); - language_data.push_back(data); + type_data.push_back(data); } } @@ -136,69 +145,97 @@ void ShaderCreateDialog::ok_pressed() { void ShaderCreateDialog::_create_new() { Ref<Resource> shader; - - if (language_menu->get_selected() == int(SHADER_TYPE_TEXT)) { - Ref<Shader> text_shader; - text_shader.instantiate(); - shader = text_shader; - - StringBuilder code; - code += vformat("shader_type %s;\n", mode_menu->get_text().replace(" ", "").camelcase_to_underscore()); - - if (current_template == 0) { // Default template. - code += "\n"; - switch (current_mode) { - case Shader::MODE_SPATIAL: - code += "void fragment() {\n"; - code += "\t// Place fragment code here.\n"; - code += "}\n"; - break; - case Shader::MODE_CANVAS_ITEM: - code += "void fragment() {\n"; - code += "\t// Place fragment code here.\n"; - code += "}\n"; - break; - case Shader::MODE_PARTICLES: - code += "void start() {\n"; - code += "\t// Place start code here.\n"; - code += "}\n"; - code += "\n"; - code += "void process() {\n"; - code += "\t// Place process code here.\n"; - code += "}\n"; - break; - case Shader::MODE_SKY: - code += "void sky() {\n"; - code += "\t// Place sky code here.\n"; - code += "}\n"; - break; - case Shader::MODE_FOG: - code += "void fog() {\n"; - code += "\t// Place fog code here.\n"; - code += "}\n"; - break; + Ref<Resource> shader_inc; + + switch (type_menu->get_selected()) { + case SHADER_TYPE_TEXT: { + Ref<Shader> text_shader; + text_shader.instantiate(); + shader = text_shader; + + StringBuilder code; + code += vformat("shader_type %s;\n", mode_menu->get_text().replace(" ", "").camelcase_to_underscore()); + + if (current_template == 0) { // Default template. + code += "\n"; + switch (current_mode) { + case Shader::MODE_SPATIAL: + code += "void fragment() {\n"; + code += "\t// Place fragment code here.\n"; + code += "}\n"; + break; + case Shader::MODE_CANVAS_ITEM: + code += "void fragment() {\n"; + code += "\t// Place fragment code here.\n"; + code += "}\n"; + break; + case Shader::MODE_PARTICLES: + code += "void start() {\n"; + code += "\t// Place start code here.\n"; + code += "}\n"; + code += "\n"; + code += "void process() {\n"; + code += "\t// Place process code here.\n"; + code += "}\n"; + break; + case Shader::MODE_SKY: + code += "void sky() {\n"; + code += "\t// Place sky code here.\n"; + code += "}\n"; + break; + case Shader::MODE_FOG: + code += "void fog() {\n"; + code += "\t// Place fog code here.\n"; + code += "}\n"; + break; + } } - } - text_shader->set_code(code.as_string()); - } else { - Ref<VisualShader> visual_shader; - visual_shader.instantiate(); - shader = visual_shader; - visual_shader->set_mode(Shader::Mode(current_mode)); + text_shader->set_code(code.as_string()); + } break; + case SHADER_TYPE_VISUAL: { + Ref<VisualShader> visual_shader; + visual_shader.instantiate(); + shader = visual_shader; + visual_shader->set_mode(Shader::Mode(current_mode)); + } break; + case SHADER_TYPE_INC: { + Ref<ShaderInclude> include; + include.instantiate(); + shader_inc = include; + } break; + default: { + } break; } - if (!is_built_in) { + if (shader.is_null()) { String lpath = ProjectSettings::get_singleton()->localize_path(file_path->get_text()); - shader->set_path(lpath); - Error err = ResourceSaver::save(lpath, shader, ResourceSaver::FLAG_CHANGE_PATH); - if (err != OK) { - alert->set_text(TTR("Error - Could not create shader in filesystem.")); + shader_inc->set_path(lpath); + + Error error = ResourceSaver::save(lpath, shader_inc, ResourceSaver::FLAG_CHANGE_PATH); + if (error != OK) { + alert->set_text(TTR("Error - Could not create shader include in filesystem.")); alert->popup_centered(); return; } + + emit_signal(SNAME("shader_include_created"), shader_inc); + } else { + if (!is_built_in) { + String lpath = ProjectSettings::get_singleton()->localize_path(file_path->get_text()); + shader->set_path(lpath); + + Error error = ResourceSaver::save(lpath, shader, ResourceSaver::FLAG_CHANGE_PATH); + if (error != OK) { + alert->set_text(TTR("Error - Could not create shader in filesystem.")); + alert->popup_centered(); + return; + } + } + + emit_signal(SNAME("shader_created"), shader); } - emit_signal(SNAME("shader_created"), shader); + file_path->set_text(file_path->get_text().get_base_dir()); hide(); } @@ -215,9 +252,9 @@ void ShaderCreateDialog::_load_exist() { hide(); } -void ShaderCreateDialog::_language_changed(int p_language) { - current_language = p_language; - ShaderTypeData data = language_data[p_language]; +void ShaderCreateDialog::_type_changed(int p_language) { + current_type = p_language; + ShaderTypeData data = type_data[p_language]; String selected_ext = "." + data.default_extension; String path = file_path->get_text(); @@ -238,6 +275,8 @@ void ShaderCreateDialog::_language_changed(int p_language) { _path_changed(path); file_path->set_text(path); + type_menu->set_item_disabled(int(SHADER_TYPE_INC), load_enabled); + mode_menu->set_disabled(p_language == SHADER_TYPE_INC); template_menu->set_disabled(!data.use_templates); template_menu->clear(); @@ -253,7 +292,7 @@ void ShaderCreateDialog::_language_changed(int p_language) { template_menu->add_item(TTR("N/A")); } - EditorSettings::get_singleton()->set_project_metadata("shader_setup", "last_selected_language", language_menu->get_item_text(language_menu->get_selected())); + EditorSettings::get_singleton()->set_project_metadata("shader_setup", "last_selected_language", type_menu->get_item_text(type_menu->get_selected())); _update_dialog(); } @@ -275,7 +314,7 @@ void ShaderCreateDialog::_browse_path() { file_browse->set_disable_overwrite_warning(true); file_browse->clear_filters(); - List<String> extensions = language_data[language_menu->get_selected()].extensions; + List<String> extensions = type_data[type_menu->get_selected()].extensions; for (const String &E : extensions) { file_browse->add_filter("*." + E); @@ -330,8 +369,8 @@ void ShaderCreateDialog::_path_submitted(const String &p_path) { void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled, int p_preferred_type, int p_preferred_mode) { if (!p_base_path.is_empty()) { initial_base_path = p_base_path.get_basename(); - file_path->set_text(initial_base_path + "." + language_data[language_menu->get_selected()].default_extension); - current_language = language_menu->get_selected(); + file_path->set_text(initial_base_path + "." + type_data[type_menu->get_selected()].default_extension); + current_type = type_menu->get_selected(); } else { initial_base_path = ""; file_path->set_text(""); @@ -342,8 +381,8 @@ void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabl load_enabled = p_load_enabled; if (p_preferred_type > -1) { - language_menu->select(p_preferred_type); - _language_changed(p_preferred_type); + type_menu->select(p_preferred_type); + _type_changed(p_preferred_type); } if (p_preferred_mode > -1) { @@ -351,7 +390,7 @@ void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabl _mode_changed(p_preferred_mode); } - _language_changed(current_language); + _type_changed(current_type); _path_changed(file_path->get_text()); } @@ -384,14 +423,14 @@ String ShaderCreateDialog::_validate_path(const String &p_path) { HashSet<String> extensions; for (int i = 0; i < SHADER_TYPE_MAX; i++) { - for (const String &ext : language_data[i].extensions) { + for (const String &ext : type_data[i].extensions) { if (!extensions.has(ext)) { extensions.insert(ext); } } } - ShaderTypeData data = language_data[language_menu->get_selected()]; + ShaderTypeData data = type_data[type_menu->get_selected()]; bool found = false; bool match = false; @@ -399,8 +438,8 @@ String ShaderCreateDialog::_validate_path(const String &p_path) { for (const String &ext : extensions) { if (ext.nocasecmp_to(extension) == 0) { found = true; - for (const String &lang_ext : language_data[current_language].extensions) { - if (lang_ext.nocasecmp_to(extension) == 0) { + for (const String &type_ext : type_data[current_type].extensions) { + if (type_ext.nocasecmp_to(extension) == 0) { match = true; break; } @@ -504,6 +543,7 @@ void ShaderCreateDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("config", "path", "built_in_enabled", "load_enabled"), &ShaderCreateDialog::config, DEFVAL(true), DEFVAL(true)); ADD_SIGNAL(MethodInfo("shader_created", PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader"))); + ADD_SIGNAL(MethodInfo("shader_include_created", PropertyInfo(Variant::OBJECT, "shader_include", PROPERTY_HINT_RESOURCE_TYPE, "ShaderInclude"))); } ShaderCreateDialog::ShaderCreateDialog() { @@ -547,24 +587,27 @@ ShaderCreateDialog::ShaderCreateDialog() { vb->add_child(status_panel); add_child(vb); - // Language. + // Type. - language_menu = memnew(OptionButton); - language_menu->set_custom_minimum_size(Size2(250, 0) * EDSCALE); - language_menu->set_h_size_flags(Control::SIZE_EXPAND_FILL); - gc->add_child(memnew(Label(TTR("Language:")))); - gc->add_child(language_menu); + type_menu = memnew(OptionButton); + type_menu->set_custom_minimum_size(Size2(250, 0) * EDSCALE); + type_menu->set_h_size_flags(Control::SIZE_EXPAND_FILL); + gc->add_child(memnew(Label(TTR("Type:")))); + gc->add_child(type_menu); for (int i = 0; i < SHADER_TYPE_MAX; i++) { - String language; + String type; bool invalid = false; switch (i) { case SHADER_TYPE_TEXT: - language = "Shader"; - default_language = i; + type = "Shader"; + default_type = i; break; case SHADER_TYPE_VISUAL: - language = "VisualShader"; + type = "VisualShader"; + break; + case SHADER_TYPE_INC: + type = "ShaderInclude"; break; case SHADER_TYPE_MAX: invalid = true; @@ -576,13 +619,13 @@ ShaderCreateDialog::ShaderCreateDialog() { if (invalid) { continue; } - language_menu->add_item(language); + type_menu->add_item(type); } - if (default_language >= 0) { - language_menu->select(default_language); + if (default_type >= 0) { + type_menu->select(default_type); } - current_language = default_language; - language_menu->connect("item_selected", callable_mp(this, &ShaderCreateDialog::_language_changed)); + current_type = default_type; + type_menu->connect("item_selected", callable_mp(this, &ShaderCreateDialog::_type_changed)); // Modes. diff --git a/editor/shader_create_dialog.h b/editor/shader_create_dialog.h index 6737ce4f10..bf031c3601 100644 --- a/editor/shader_create_dialog.h +++ b/editor/shader_create_dialog.h @@ -47,6 +47,7 @@ class ShaderCreateDialog : public ConfirmationDialog { enum ShaderType { SHADER_TYPE_TEXT, SHADER_TYPE_VISUAL, + SHADER_TYPE_INC, SHADER_TYPE_MAX, }; @@ -56,14 +57,14 @@ class ShaderCreateDialog : public ConfirmationDialog { bool use_templates = false; }; - List<ShaderTypeData> language_data; + List<ShaderTypeData> type_data; GridContainer *gc = nullptr; Label *error_label = nullptr; Label *path_error_label = nullptr; Label *builtin_warning_label = nullptr; PanelContainer *status_panel = nullptr; - OptionButton *language_menu = nullptr; + OptionButton *type_menu = nullptr; OptionButton *mode_menu = nullptr; OptionButton *template_menu = nullptr; CheckBox *internal = nullptr; @@ -79,8 +80,8 @@ class ShaderCreateDialog : public ConfirmationDialog { bool built_in_enabled = true; bool load_enabled = false; bool re_check_path = false; - int current_language = -1; - int default_language = -1; + int current_type = -1; + int default_type = -1; int current_mode = 0; int current_template = 0; @@ -89,7 +90,7 @@ class ShaderCreateDialog : public ConfirmationDialog { void _path_hbox_sorted(); void _path_changed(const String &p_path = String()); void _path_submitted(const String &p_path = String()); - void _language_changed(int p_language = 0); + void _type_changed(int p_type = 0); void _built_in_toggled(bool p_enabled); void _template_changed(int p_template = 0); void _mode_changed(int p_mode = 0); @@ -113,4 +114,4 @@ public: ShaderCreateDialog(); }; -#endif +#endif // SHADER_CREATE_DIALOG_H diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index bfabf269bf..5bf7e958f6 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -79,7 +79,7 @@ protected: } bool _set(const StringName &p_name, const Variant &p_value) { - Variant existing = RS::get_singleton()->global_variable_get(p_name); + Variant existing = RS::get_singleton()->global_shader_uniform_get(p_name); if (existing.get_type() == Variant::NIL) { return false; @@ -88,9 +88,9 @@ protected: UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); undo_redo->create_action(TTR("Set Shader Global Variable")); - undo_redo->add_do_method(RS::get_singleton(), "global_variable_set", p_name, p_value); - undo_redo->add_undo_method(RS::get_singleton(), "global_variable_set", p_name, existing); - RS::GlobalVariableType type = RS::get_singleton()->global_variable_get_type(p_name); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_set", p_name, p_value); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_set", p_name, existing); + RS::GlobalShaderUniformType type = RS::get_singleton()->global_shader_uniform_get_type(p_name); Dictionary gv; gv["type"] = global_var_type_names[type]; if (type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { @@ -117,17 +117,17 @@ protected: } bool _get(const StringName &p_name, Variant &r_ret) const { - r_ret = RS::get_singleton()->global_variable_get(p_name); + r_ret = RS::get_singleton()->global_shader_uniform_get(p_name); return r_ret.get_type() != Variant::NIL; } void _get_property_list(List<PropertyInfo> *p_list) const { Vector<StringName> variables; - variables = RS::get_singleton()->global_variable_get_list(); + variables = RS::get_singleton()->global_shader_uniform_get_list(); for (int i = 0; i < variables.size(); i++) { PropertyInfo pinfo; pinfo.name = variables[i]; - switch (RS::get_singleton()->global_variable_get_type(variables[i])) { + switch (RS::get_singleton()->global_shader_uniform_get_type(variables[i])) { case RS::GLOBAL_VAR_TYPE_BOOL: { pinfo.type = Variant::BOOL; } break; @@ -156,7 +156,7 @@ protected: pinfo.type = Variant::VECTOR3I; } break; case RS::GLOBAL_VAR_TYPE_IVEC4: { - pinfo.type = Variant::PACKED_INT32_ARRAY; + pinfo.type = Variant::VECTOR4I; } break; case RS::GLOBAL_VAR_TYPE_RECT2I: { pinfo.type = Variant::RECT2I; @@ -171,7 +171,7 @@ protected: pinfo.type = Variant::VECTOR3I; } break; case RS::GLOBAL_VAR_TYPE_UVEC4: { - pinfo.type = Variant::PACKED_INT32_ARRAY; + pinfo.type = Variant::VECTOR4I; } break; case RS::GLOBAL_VAR_TYPE_FLOAT: { pinfo.type = Variant::FLOAT; @@ -183,7 +183,7 @@ protected: pinfo.type = Variant::VECTOR3; } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - pinfo.type = Variant::QUATERNION; + pinfo.type = Variant::VECTOR4; } break; case RS::GLOBAL_VAR_TYPE_RECT2: { pinfo.type = Variant::RECT2; @@ -204,7 +204,7 @@ protected: pinfo.type = Variant::TRANSFORM3D; } break; case RS::GLOBAL_VAR_TYPE_MAT4: { - pinfo.type = Variant::PACKED_INT32_ARRAY; + pinfo.type = Variant::PROJECTION; } break; case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { pinfo.type = Variant::OBJECT; @@ -241,7 +241,7 @@ public: } }; -static Variant create_var(RS::GlobalVariableType p_type) { +static Variant create_var(RS::GlobalShaderUniformType p_type) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { return false; @@ -376,12 +376,12 @@ static Variant create_var(RS::GlobalVariableType p_type) { void ShaderGlobalsEditor::_variable_added() { String var = variable_name->get_text().strip_edges(); if (var.is_empty() || !var.is_valid_identifier()) { - EditorNode::get_singleton()->show_warning(TTR("Please specify a valid variable identifier name.")); + EditorNode::get_singleton()->show_warning(TTR("Please specify a valid shader uniform identifier name.")); return; } - if (RenderingServer::get_singleton()->global_variable_get(var).get_type() != Variant::NIL) { - EditorNode::get_singleton()->show_warning(vformat(TTR("Global variable '%s' already exists'"), var)); + if (RenderingServer::get_singleton()->global_shader_uniform_get(var).get_type() != Variant::NIL) { + EditorNode::get_singleton()->show_warning(vformat(TTR("Global shader uniform '%s' already exists'"), var)); return; } @@ -395,11 +395,11 @@ void ShaderGlobalsEditor::_variable_added() { UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); - Variant value = create_var(RS::GlobalVariableType(variable_type->get_selected())); + Variant value = create_var(RS::GlobalShaderUniformType(variable_type->get_selected())); - undo_redo->create_action(TTR("Add Shader Global Variable")); - undo_redo->add_do_method(RS::get_singleton(), "global_variable_add", var, RS::GlobalVariableType(variable_type->get_selected()), value); - undo_redo->add_undo_method(RS::get_singleton(), "global_variable_remove", var); + undo_redo->create_action(TTR("Add Shader Global Uniform")); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_add", var, RS::GlobalShaderUniformType(variable_type->get_selected()), value); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_remove", var); Dictionary gv; gv["type"] = global_var_type_names[variable_type->get_selected()]; gv["value"] = value; @@ -414,9 +414,9 @@ void ShaderGlobalsEditor::_variable_added() { void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) { UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo(); - undo_redo->create_action(TTR("Add Shader Global Variable")); - undo_redo->add_do_method(RS::get_singleton(), "global_variable_remove", p_variable); - undo_redo->add_undo_method(RS::get_singleton(), "global_variable_add", p_variable, RS::get_singleton()->global_variable_get_type(p_variable), RS::get_singleton()->global_variable_get(p_variable)); + undo_redo->create_action(TTR("Add Shader Global Uniform")); + undo_redo->add_do_method(RS::get_singleton(), "global_shader_uniform_remove", p_variable); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_uniform_add", p_variable, RS::get_singleton()->global_shader_uniform_get_type(p_variable), RS::get_singleton()->global_shader_uniform_get(p_variable)); undo_redo->add_do_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, Variant()); undo_redo->add_undo_property(ProjectSettings::get_singleton(), "shader_globals/" + p_variable, ProjectSettings::get_singleton()->get("shader_globals/" + p_variable)); diff --git a/editor/translations/af.po b/editor/translations/af.po index 78dd7f2140..55fe58e1b0 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -2191,14 +2191,15 @@ msgstr "Gunstelinge:" msgid "Recent:" msgstr "Onlangse:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Soek:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Passendes:" @@ -2260,8 +2261,8 @@ msgstr "Soek Vervanging Hulpbron:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5570,6 +5571,10 @@ msgid "Drag And Drop Selection" msgstr "Alle Seleksie" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11868,6 +11873,11 @@ msgid "New Animation" msgstr "Optimaliseer Animasie" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Eienskappe" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index 87266564f8..36e71f130e 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -66,13 +66,15 @@ # Abderrahim <abdoudido117@gmail.com>, 2022. # Jhon Smith <jhonsmaith3@gmail.com>, 2022. # Oo mohab oO <mohab9225@gmail.com>, 2022. +# عبد الرØÙ…Ù† أبو سعدة ||Abd Alrahman abo saada <abdalrahmanabs2005@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-09 21:11+0000\n" -"Last-Translator: Oo mohab oO <mohab9225@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: عبد الرØÙ…Ù† أبو سعدة ||Abd Alrahman abo saada " +"<abdalrahmanabs2005@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot/ar/>\n" "Language: ar\n" @@ -81,7 +83,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -452,7 +454,7 @@ msgstr "Ù…ÙØªØ§Ø Command" #: core/os/input_event.cpp #, fuzzy msgid "Physical" -msgstr " (Ùيزيائي)" +msgstr "(Ùيزيائي)" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -486,7 +488,7 @@ msgstr "الموقع العالمي" #: core/os/input_event.cpp msgid "Factor" -msgstr "المعامل" +msgstr "العامل" #: core/os/input_event.cpp msgid "Button Index" @@ -553,7 +555,7 @@ msgstr "قناة" #: core/os/input_event.cpp main/main.cpp msgid "Message" -msgstr "الرسالة" +msgstr "رسالة" #: core/os/input_event.cpp msgid "Pitch" @@ -585,7 +587,7 @@ msgstr "التطبيق" #: core/project_settings.cpp main/main.cpp msgid "Config" -msgstr "تعديل" +msgstr "إعداد" #: core/project_settings.cpp msgid "Project Settings Override" @@ -602,7 +604,7 @@ msgstr "تجاوز إعدادات المشروع" #: scene/3d/skeleton.cpp scene/main/node.cpp scene/resources/mesh_library.cpp #: scene/resources/skin.cpp msgid "Name" -msgstr "الأسم" +msgstr "الاسم" #: core/project_settings.cpp editor/editor_help.cpp #: modules/visual_script/visual_script_nodes.cpp platform/uwp/export/export.cpp @@ -862,9 +864,8 @@ msgid "Compression" msgstr "ضغط" #: core/project_settings.cpp -#, fuzzy msgid "Formats" -msgstr "البنية (اللاØÙ‚Ø©)" +msgstr "التنسيقات" #: core/project_settings.cpp #, fuzzy @@ -944,7 +945,7 @@ msgstr "المسار" #: core/script_language.cpp msgid "Source Code" -msgstr "مصدر الرمز" +msgstr "الكود المصدري || Ø§Ù„Ø´ÙØ±Ø© المصدرية" #: core/translation.cpp editor/project_settings_editor.cpp msgid "Locale" @@ -956,7 +957,7 @@ msgstr "إختبار" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "تقهقر" +msgstr "تراجع | Ø§Ù†Ø³ØØ§Ø¨" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -1014,7 +1015,7 @@ msgstr "ØØ¬Ù… Ùهرس المخزن المؤقت Ù„Ù„ÙˆØØ© المضلعات (K #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/visual_server.cpp msgid "2D" -msgstr "2D" +msgstr "ثنائي الأبعاد" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -2177,14 +2178,15 @@ msgstr "Ø§Ù„Ù…ÙØ¶Ù„Ø©:" msgid "Recent:" msgstr "Ø§Ù„ØØ§Ù„ÙŠ:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Ø¨ØØ«:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "يطابق:" @@ -2244,8 +2246,8 @@ msgstr "Ø§Ù„Ø¨ØØ« عن مورد بديل:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -4868,7 +4870,7 @@ msgstr "نظام Ø§Ù„Ù…Ù„ÙØ§Øª" #: editor/editor_node.cpp msgid "Expand Bottom Panel" -msgstr "توسيع التبويب السÙلي" +msgstr "توسيع القائمة السÙلية" #: editor/editor_node.cpp msgid "Don't Save" @@ -5608,6 +5610,10 @@ msgid "Drag And Drop Selection" msgstr "ØªØØ¯ÙŠØ¯ الملئ خريطة-الشبكة" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "المظهر" @@ -11847,6 +11853,11 @@ msgid "New Animation" msgstr "رسومية Ù…ØªØØ±ÙƒØ© جديدة" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ØªØ±Ø´ÙŠØ Ø§Ù„Ø¯ÙˆØ§Ù„" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "السرعة:" @@ -16283,26 +16294,24 @@ msgid "Set Room Point Position" msgstr "ØØ¯Ø¯ موقع نقطة الإنØÙ†Ø§Ø¡" #: editor/spatial_editor_gizmos.cpp scene/3d/portal.cpp -#, fuzzy msgid "Portal Margin" -msgstr "ØªØØ¯ÙŠØ¯ الهامش" +msgstr "هامش البوابة" #: editor/spatial_editor_gizmos.cpp msgid "Portal Edge" -msgstr "" +msgstr "ØØ§ÙØ© Ø§Ù„ØºØ±ÙØ©" #: editor/spatial_editor_gizmos.cpp msgid "Portal Arrow" -msgstr "" +msgstr "سهم البوابة" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Set Portal Point Position" -msgstr "ØØ¯Ø¯ موقع نقطة الإنØÙ†Ø§Ø¡" +msgstr "ØØ¯Ø¯ موقع نقطة البوابة" #: editor/spatial_editor_gizmos.cpp msgid "Portal Front" -msgstr "" +msgstr "واجهة البوابة" #: editor/spatial_editor_gizmos.cpp #, fuzzy @@ -16341,18 +16350,16 @@ msgid "Occluder Polygon Front" msgstr "أنشئ شكل Ù…ÙØ·Ø¨Ù‚" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Polygon Back" -msgstr "أنشئ شكل Ù…ÙØ·Ø¨Ù‚" +msgstr "" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Hole" -msgstr "أنشئ شكل Ù…ÙØ·Ø¨Ù‚" +msgstr "" #: main/main.cpp msgid "Godot Physics" -msgstr "" +msgstr "Ùيزيائيات جودو" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp @@ -16431,9 +16438,8 @@ msgid "Driver" msgstr "" #: main/main.cpp -#, fuzzy msgid "Driver Name" -msgstr "اسم النص البرمجي:" +msgstr "اسم النص البرمجي" #: main/main.cpp msgid "Fallback To GLES2" @@ -16452,22 +16458,20 @@ msgid "Allow hiDPI" msgstr "" #: main/main.cpp -#, fuzzy msgid "V-Sync" -msgstr "مزامنة" +msgstr "مزامنة (مزامنة كرت الشاشة)" #: main/main.cpp -#, fuzzy msgid "Use V-Sync" -msgstr "استخدام Ø§Ù„Ù…ØØ§Ø°Ø§Ø©" +msgstr "استخدام مزامنة كرت الشاشة" #: main/main.cpp msgid "Per Pixel Transparency" -msgstr "" +msgstr "Ø´ÙØ§Ùية بيكسل القلم" #: main/main.cpp msgid "Allowed" -msgstr "" +msgstr "مسموØ" #: main/main.cpp msgid "Intended Usage" @@ -16479,18 +16483,16 @@ msgid "Framebuffer Allocation" msgstr "ØªØØ¯ÙŠØ¯ الإطار" #: main/main.cpp platform/uwp/os_uwp.cpp -#, fuzzy msgid "Energy Saving" -msgstr "خطأ ÙÙŠ الØÙظ" +msgstr "توÙير الطاقة" #: main/main.cpp msgid "Threads" -msgstr "" +msgstr "مسارات" #: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h -#, fuzzy msgid "Thread Model" -msgstr "أظهر المود" +msgstr "نوع المسار" #: main/main.cpp msgid "Thread Safe BVH" @@ -16508,9 +16510,8 @@ msgstr "الوثائق الإلكترونية" #: main/main.cpp scene/gui/scroll_container.cpp scene/gui/text_edit.cpp #: scene/main/scene_tree.cpp scene/register_scene_types.cpp -#, fuzzy msgid "Common" -msgstr "المجتمع" +msgstr "شائع" #: main/main.cpp #, fuzzy @@ -16530,7 +16531,7 @@ msgstr "" #: scene/gui/scroll_container.cpp scene/gui/text_edit.cpp scene/gui/tree.cpp #: scene/main/viewport.cpp scene/register_scene_types.cpp msgid "GUI" -msgstr "" +msgstr "واجهة المستخدم الرسومية" #: main/main.cpp msgid "Drop Mouse On GUI Input Disabled" @@ -16554,9 +16555,8 @@ msgid "Physics Interpolation" msgstr "وضعية Ø§Ù„Ø£Ø³ØªÙŠÙØ§Ø¡" #: main/main.cpp -#, fuzzy msgid "Enable Warnings" -msgstr "تمكين Ø§Ù„ØªØ±Ø´ÙŠØ Filtering" +msgstr "ØªÙØ¹ÙŠÙ„ Ø§Ù„ØªØØ°ÙŠØ±Ø§Øª" #: main/main.cpp #, fuzzy @@ -16573,25 +16573,23 @@ msgstr "" #: main/main.cpp msgid "iOS" -msgstr "" +msgstr "IOS" #: main/main.cpp msgid "Hide Home Indicator" msgstr "" #: main/main.cpp -#, fuzzy msgid "Input Devices" -msgstr "جميع الأجهزة" +msgstr "أجهزة الإدخال" #: main/main.cpp -#, fuzzy msgid "Pointing" -msgstr "نقطة" +msgstr "يشير" #: main/main.cpp msgid "Touch Delay" -msgstr "" +msgstr "تأخير اللمس" #: main/main.cpp servers/visual_server.cpp msgid "GLES3" @@ -16633,7 +16631,7 @@ msgstr "" #: main/main.cpp msgid "Fullsize" -msgstr "" +msgstr "Ø§Ù„ØØ¬Ù… الكامل" #: main/main.cpp scene/resources/dynamic_font.cpp #, fuzzy @@ -16706,21 +16704,20 @@ msgstr "انتهت المهلة." #: main/main.cpp msgid "Runtime" -msgstr "" +msgstr "اثناء التشغيل" #: main/main.cpp msgid "Unhandled Exception Policy" msgstr "" #: main/main.cpp -#, fuzzy msgid "Main Loop Type" -msgstr "إيجاد نوع العÙقدة" +msgstr "نوع الØÙ„قة الرئيسية" #: main/main.cpp scene/gui/texture_progress.cpp #: scene/gui/viewport_container.cpp msgid "Stretch" -msgstr "" +msgstr "تمدد" #: main/main.cpp #, fuzzy @@ -16775,38 +16772,33 @@ msgstr "تغيير نص٠قطر الدائرة الداخلي" #: modules/csg/csg_gizmos.cpp msgid "Change Torus Outer Radius" -msgstr "تعديل نص٠القطر الخارجي للطارة Torus Outer Radius" +msgstr "تعديل نص٠القطر الخارجي للمسنن" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Operation" -msgstr "الإعدادات" +msgstr "عملية" #: modules/csg/csg_shape.cpp msgid "Calculate Tangents" -msgstr "" +msgstr "Ø§ØØ³Ø¨ الظلال" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Use Collision" -msgstr "التصادم" +msgstr "استخدم التصادم" #: modules/csg/csg_shape.cpp servers/physics_2d_server.cpp -#, fuzzy msgid "Collision Layer" -msgstr "وضع التصادم" +msgstr "" #: modules/csg/csg_shape.cpp scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp #: scene/3d/ray_cast.cpp scene/3d/spring_arm.cpp #: scene/resources/navigation_mesh.cpp servers/physics_server.cpp -#, fuzzy msgid "Collision Mask" -msgstr "وضع التصادم" +msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Invert Faces" -msgstr "ØØ§Ù„Ø© التØÙˆÙŠÙ„" +msgstr "اقلب الوجوه" #: modules/csg/csg_shape.cpp scene/2d/navigation_agent_2d.cpp #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_agent.cpp @@ -16826,37 +16818,32 @@ msgid "Radial Segments" msgstr "معاملات المشهد الرئيس:" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Rings" -msgstr "ØªØØ°ÙŠØ±Ø§Øª" +msgstr "خواتم" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Smooth Faces" -msgstr "خطوة ناعمة" +msgstr "وجوه ناعمة" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Sides" -msgstr "أظهر الموجهات" +msgstr "جهات" #: modules/csg/csg_shape.cpp msgid "Cone" msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Inner Radius" -msgstr "تغيير نص٠قطر الدائرة الداخلي" +msgstr "القطر الداخلي" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Outer Radius" -msgstr "تعديل نص٠القطر الخارجي للطارة Torus Outer Radius" +msgstr "القطر الخارجي" #: modules/csg/csg_shape.cpp msgid "Ring Sides" -msgstr "" +msgstr "جهات الخاتم" #: modules/csg/csg_shape.cpp scene/2d/collision_polygon_2d.cpp #: scene/2d/light_occluder_2d.cpp scene/2d/polygon_2d.cpp @@ -16867,16 +16854,15 @@ msgstr "Ø§Ù„Ù…ÙØ¶Ù„عات" #: modules/csg/csg_shape.cpp msgid "Spin Degrees" -msgstr "" +msgstr "درجة الدوران" #: modules/csg/csg_shape.cpp msgid "Spin Sides" -msgstr "" +msgstr "جهة الدوران" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Node" -msgstr "لصق العÙقد" +msgstr "مسار العقدة" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16907,9 +16893,8 @@ msgid "Path Continuous U" msgstr "متواصل" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path U Distance" -msgstr "اختر Ø§Ù„Ù…Ø³Ø§ÙØ©:" +msgstr "المسار المØÙ„ÙŠ" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16917,28 +16902,26 @@ msgid "Path Joined" msgstr "دوران عشوائي:" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Compression Mode" -msgstr "وضع التصادم" +msgstr "وضع الضغط" #: modules/enet/networked_multiplayer_enet.cpp #, fuzzy msgid "Transfer Channel" -msgstr "تعديل التØÙˆÙ„ات" +msgstr "نقل القنوات" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Channel Count" -msgstr "كائن" +msgstr "عدد القنوات" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Always Ordered" -msgstr "إظهار الشبكة دوماً" +msgstr "مطلوب دائمًا" #: modules/enet/networked_multiplayer_enet.cpp +#, fuzzy msgid "Server Relay" -msgstr "" +msgstr "تناوب الخادم" #: modules/enet/networked_multiplayer_enet.cpp msgid "DTLS Verify" @@ -16962,30 +16945,25 @@ msgid "Use FBX" msgstr "" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Config File" -msgstr "تخزين الملÙ:" +msgstr "مل٠التهيئة" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Load Once" -msgstr "تØÙ…يل المورد" +msgstr "ØÙ…Ù„ مرة ÙˆØ§ØØ¯Ø©" #: modules/gdnative/gdnative.cpp #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Singleton" -msgstr "الهيكل" +msgstr "" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Symbol Prefix" -msgstr "بادئة:" +msgstr "رمز البادئة" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Reloadable" -msgstr "إعادة تØÙ…يل" +msgstr "قابل لإعادة التØÙ…يل" #: modules/gdnative/gdnative.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp @@ -17003,7 +16981,7 @@ msgstr "اختر تبعيات المكتبة لأجل هذا الإدخال" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Remove current entry" -msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ø¯Ø®Ù„Ø© Ø§Ù„ØØ§Ù„ية" +msgstr "Ù…Ø³Ø Ø§Ù„Ù…Ø¯Ø®Ù„Ø§Øª Ø§Ù„ØØ§Ù„ية" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Double click to create a new entry" @@ -17052,9 +17030,8 @@ msgid "Script Class" msgstr "اسم النص البرمجي:" #: modules/gdnative/nativescript/nativescript.cpp -#, fuzzy msgid "Icon Path" -msgstr "مسار التركيز" +msgstr "مسار الأيقونة" #: modules/gdnative/register_types.cpp msgid "GDNative" @@ -17062,18 +17039,16 @@ msgstr "لغة البرمجة GDNative" #: modules/gdscript/editor/gdscript_highlighter.cpp #: modules/gdscript/gdscript.cpp -#, fuzzy msgid "GDScript" -msgstr "النص البرمجي" +msgstr "لغة جي دي" #: modules/gdscript/editor/gdscript_highlighter.cpp msgid "Function Definition Color" -msgstr "" +msgstr "لون تعري٠الدالة" #: modules/gdscript/editor/gdscript_highlighter.cpp -#, fuzzy msgid "Node Path Color" -msgstr "نسخ مسار العÙقدة" +msgstr "لون مسار العقدة" #: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp msgid "Max Call Stack" @@ -17101,11 +17076,11 @@ msgstr "ليس نص برمجي مع نموذج" #: modules/gdscript/gdscript_functions.cpp msgid "Not based on a script" -msgstr "لا تستند الى نص برمجي" +msgstr "غير مبني على نص برمجي" #: modules/gdscript/gdscript_functions.cpp msgid "Not based on a resource file" -msgstr "لا يعتمد على مل٠موارد" +msgstr "غير مبني على مل٠موارد" #: modules/gdscript/gdscript_functions.cpp msgid "Invalid instance dictionary format (missing @path)" @@ -17128,14 +17103,12 @@ msgid "Object can't provide a length." msgstr "لا يمكن للكائن أن ÙŠÙ…Ù†Ø Ø·ÙˆÙ„Ø§Ù‹." #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Language Server" -msgstr "اللغة:" +msgstr "لغة الخادك" #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Enable Smart Resolve" -msgstr "لا يمكن الØÙ„" +msgstr "ØªÙØ¹ÙŠÙ„ الØÙ„ الذكي" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Show Native Symbols In Editor" @@ -17143,7 +17116,7 @@ msgstr "" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Use Thread" -msgstr "" +msgstr "استخدم المسار" #: modules/gltf/editor_scene_exporter_gltf_plugin.cpp #, fuzzy @@ -17166,14 +17139,12 @@ msgid "Byte Offset" msgstr "مقدار Ø¥Ø²Ø§ØØ© الشبكة:" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Component Type" -msgstr "مكونات" +msgstr "نوع المكون" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Normalized" -msgstr "البنية (اللاØÙ‚Ø©)" +msgstr "" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17181,14 +17152,12 @@ msgid "Count" msgstr "الكمية:" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Min" -msgstr "ميبي بايت (MiB)" +msgstr "أقل" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Max" -msgstr "خلط" +msgstr "أعلى" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17238,7 +17207,7 @@ msgstr "جميع الأجهزة" #: modules/gltf/gltf_camera.cpp #, fuzzy msgid "FOV Size" -msgstr "Ø§Ù„ØØ¬Ù…:" +msgstr "ØØ¬Ù… Ù…Ø³Ø§ØØ©Ø§Ù„رؤية" #: modules/gltf/gltf_camera.cpp msgid "Zfar" @@ -17257,27 +17226,25 @@ msgstr "خطي" #: scene/resources/environment.cpp scene/resources/material.cpp #: scene/resources/particles_material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Color" msgstr "الألوان" #: modules/gltf/gltf_light.cpp scene/3d/reflection_probe.cpp #: scene/resources/environment.cpp msgid "Intensity" -msgstr "" +msgstr "Ø§Ù„ÙƒØ«Ø§ÙØ© | الشدة" #: modules/gltf/gltf_light.cpp scene/2d/light_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Range" -msgstr "تغير" +msgstr "نطاق" #: modules/gltf/gltf_light.cpp msgid "Inner Cone Angle" -msgstr "" +msgstr "زاوية المخروط الداخلية" #: modules/gltf/gltf_light.cpp msgid "Outer Cone Angle" -msgstr "" +msgstr "زاوية المخروط الخارجية" #: modules/gltf/gltf_mesh.cpp #, fuzzy @@ -17290,9 +17257,8 @@ msgid "Instance Materials" msgstr "تغيرات المادة:" #: modules/gltf/gltf_node.cpp scene/3d/skeleton.cpp -#, fuzzy msgid "Parent" -msgstr "إعادة اختيار الأبوة" +msgstr "أب" #: modules/gltf/gltf_node.cpp #, fuzzy @@ -17316,20 +17282,20 @@ msgstr "أبناء قابلين للتعديل" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp #, fuzzy msgid "Joints" -msgstr "نقطة" +msgstr "Ø§Ù„Ù…ÙØ§ØµÙ„" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp msgid "Roots" -msgstr "" +msgstr "الجذور" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_state.cpp msgid "Unique Names" -msgstr "" +msgstr "أسماء مميزة" #: modules/gltf/gltf_skeleton.cpp #, fuzzy msgid "Godot Bone Node" -msgstr "عقدة التنقل الزمني" +msgstr "عقدة جودو العظمية" #: modules/gltf/gltf_skin.cpp #, fuzzy @@ -17346,9 +17312,8 @@ msgid "Inverse Binds" msgstr "" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Non Joints" -msgstr "ØªØØ±ÙŠÙƒ النÙقطة" +msgstr "بلا Ù…ÙØ§ØµÙ„" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Bone I" @@ -17372,12 +17337,11 @@ msgstr "" #: modules/gltf/gltf_spec_gloss.cpp msgid "Gloss Factor" -msgstr "" +msgstr "عامل اللمعان" #: modules/gltf/gltf_spec_gloss.cpp -#, fuzzy msgid "Specular Factor" -msgstr "Ù…ÙØ´ØºÙ„ الكمية القياسية Scalar." +msgstr "عامل ال" #: modules/gltf/gltf_spec_gloss.cpp msgid "Spec Gloss Img" @@ -17385,17 +17349,15 @@ msgstr "" #: modules/gltf/gltf_state.cpp msgid "Json" -msgstr "" +msgstr "جيسون" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Major Version" -msgstr "الإصدار" +msgstr "إصدار رئيسي" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Minor Version" -msgstr "الإصدار" +msgstr "إصدار ÙØ±Ø¹ÙŠ" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17416,9 +17378,8 @@ msgid "Accessors" msgstr "" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Scene Name" -msgstr "المسار للمشهد:" +msgstr "اسم المشهد" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17433,21 +17394,19 @@ msgstr "المزايا" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" -msgstr "" +msgstr "الصور" #: modules/gltf/gltf_state.cpp msgid "Cameras" -msgstr "" +msgstr "الكاميرات" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp -#, fuzzy msgid "Lights" -msgstr "ضوء" +msgstr "الأضواء" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Unique Animation Names" -msgstr "إسم رسم Ø§Ù„Ù…ØªØØ±Ùƒ جديد:" +msgstr "أسماء ØØ±ÙƒØ§Øª مميزة" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17455,37 +17414,32 @@ msgid "Skeletons" msgstr "الهيكل" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeleton To Node" -msgstr "اختر عÙقدة" +msgstr "هيكل إلى عقدة" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Animations" -msgstr "الرسومات Ø§Ù„Ù…ØªØØ±ÙƒØ©:" +msgstr "Ø§Ù„ØØ±ÙƒØ§Øª" #: modules/gltf/gltf_texture.cpp -#, fuzzy msgid "Src Image" -msgstr "إظهار العظام" +msgstr "مصدر الصورة" #: modules/gridmap/grid_map.cpp msgid "Mesh Library" msgstr "مكتبة المجسم" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Physics Material" -msgstr "نسبة الإطار الÙيزيائي %" +msgstr "مادة" #: modules/gridmap/grid_map.cpp scene/3d/visual_instance.cpp -#, fuzzy msgid "Use In Baked Light" -msgstr "طبخ (إعداد) خرائط الضوء" +msgstr "استخدام ÙÙŠ الإضاءة المطبوخة" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" -msgstr "" +msgstr "خلية" #: modules/gridmap/grid_map.cpp #, fuzzy @@ -17493,19 +17447,16 @@ msgid "Octant Size" msgstr "الواجهة View الأمامية" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center X" -msgstr "المنتصÙ" +msgstr "منتص٠س" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Y" -msgstr "المنتصÙ" +msgstr "منتص٠ص" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Z" -msgstr "المنتصÙ" +msgstr "منتصÙ" #: modules/gridmap/grid_map.cpp scene/2d/collision_object_2d.cpp #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp @@ -17671,14 +17622,12 @@ msgid "Generate buffers" msgstr "ولد AABB" #: 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 @@ -17714,27 +17663,24 @@ msgstr "" #: modules/minimp3/resource_importer_mp3.cpp #: modules/stb_vorbis/audio_stream_ogg_vorbis.cpp #: modules/stb_vorbis/resource_importer_ogg_vorbis.cpp -#, fuzzy msgid "Loop Offset" -msgstr "Ø§Ù„Ù…ÙØ¹Ø§Ø¯Ù„:" +msgstr "Ø¥Ø²Ø§ØØ© الØÙ„قة" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Eye Height" -msgstr "" +msgstr "Ø§Ø±ØªÙØ§Ø¹ الغين" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "IOD" msgstr "" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Display Width" -msgstr "عرض Ø§Ù„Ù…ÙØ®Ø·Ø· Wireframe" +msgstr "عرض الشاشة" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Display To Lens" -msgstr "عرض من غير ظلال" +msgstr "شاشة إلى عدسة" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Oversample" @@ -17753,14 +17699,12 @@ msgid "Class name can't be a reserved keyword" msgstr "لا يمكن أن يكون اسم الص٠كلمة Ù…ØØ¬ÙˆØ²Ø©" #: modules/mono/csharp_script.cpp -#, fuzzy msgid "Build Solution" -msgstr "تعبئة Ø§Ù„Ù…ÙØØ¯Ø¯" +msgstr "" #: modules/mono/editor/csharp_project.cpp -#, fuzzy msgid "Auto Update Project" -msgstr "مشروع غير مسمى" +msgstr "ØªØØ¯ÙŠØ« المشروع تلقائيًا" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17837,9 +17781,8 @@ msgid "Seamless" msgstr "" #: modules/opensimplex/noise_texture.cpp -#, fuzzy msgid "As Normal Map" -msgstr "ØØ¬Ù… عشوائي:" +msgstr "كخريطة عادية" #: modules/opensimplex/noise_texture.cpp msgid "Bump Strength" @@ -17847,7 +17790,7 @@ msgstr "" #: modules/opensimplex/noise_texture.cpp msgid "Noise" -msgstr "" +msgstr "ضوضاء" #: modules/opensimplex/noise_texture.cpp #, fuzzy @@ -17860,7 +17803,7 @@ msgstr "" #: modules/opensimplex/open_simplex_noise.cpp msgid "Period" -msgstr "" +msgstr "ÙØªØ±Ø©" #: modules/opensimplex/open_simplex_noise.cpp #, fuzzy @@ -17876,14 +17819,12 @@ msgid "Subject" msgstr "" #: modules/regex/regex.cpp -#, fuzzy msgid "Names" -msgstr "الأسم" +msgstr "الأسماء" #: modules/regex/regex.cpp -#, fuzzy msgid "Strings" -msgstr "الإعدادات:" +msgstr "النصوص" #: modules/upnp/upnp.cpp msgid "Discover Multicast If" @@ -17898,14 +17839,12 @@ msgid "Discover IPv6" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Description URL" -msgstr "الوصÙ" +msgstr "وص٠الرابط" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Service Type" -msgstr "تØÙŠØ¯ نوع المتغير" +msgstr "نوع الخدمة" #: modules/upnp/upnp_device.cpp msgid "IGD Control URL" @@ -17959,9 +17898,8 @@ msgid "Stack overflow with stack depth:" msgstr "ØØ¯ÙˆØ« تجاوز للتكدس ( Stack overflow) مع عمق التكدس:" #: modules/visual_script/visual_script.cpp -#, fuzzy msgid "Visual Script" -msgstr "Ø¨ØØ« VisualScript" +msgstr "البرمجة المرئية" #: modules/visual_script/visual_script_editor.cpp msgid "Change Signal Arguments" @@ -17992,14 +17930,12 @@ msgid "Add Output Port" msgstr "Ø£Ø¶Ù Ù…Ù†ÙØ° إخراج" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Port Type" -msgstr "تغيير النوع" +msgstr "تغيير نوع Ø§Ù„Ù…Ù†ÙØ°" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Change Port Name" -msgstr "غيّر اسم Ù…Ù†ÙØ° Ø§Ù„Ù…ÙØ¯Ø®Ù„ات" +msgstr "تغيير اسم Ø§Ù„Ù…Ù†ÙØ°" #: modules/visual_script/visual_script_editor.cpp msgid "Override an existing built-in function." @@ -18185,7 +18121,7 @@ msgstr "تعديل قيمة الإدخال" #: modules/visual_script/visual_script_editor.cpp msgid "Resize Comment" -msgstr "تغيير ØØ¬Ù… التعليق" +msgstr "تغيير ØØ¬Ù… Ø§Ù„Ù…Ù„Ø§ØØ¸Ø©" #: modules/visual_script/visual_script_editor.cpp msgid "Can't create function with a function node." @@ -22836,9 +22772,8 @@ msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Pixel Size" -msgstr "Ù…ØØ§Ø°Ø§Ø© البكسل" +msgstr "ØØ¬Ù… البكسل" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Billboard" @@ -23377,9 +23312,8 @@ msgid "Solver" msgstr "" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Exclude Nodes" -msgstr "ØØ°Ù العÙقد" +msgstr "استثناء العÙقد" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23445,14 +23379,12 @@ msgid "Linear Ortho" msgstr "نظر من الخل٠(متعامد/ليس له بعد ثالث)" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper Angle" -msgstr "Ø§Ù„Ø£ØØ±Ù الكبيرة (Uppercase)" +msgstr "الزاوية العلوية" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower Angle" -msgstr "Ø§Ù„Ø£ØØ±Ù الصغيرة (Lowercase)" +msgstr "الزاوية السÙلية" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23608,9 +23540,8 @@ msgid "Thickness" msgstr "" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp -#, fuzzy msgid "Update Mode" -msgstr "وضع التدوير" +msgstr "وضع Ø§Ù„ØªØØ¯ÙŠØ«" #: scene/3d/reflection_probe.cpp #, fuzzy @@ -23709,7 +23640,7 @@ msgstr "يجب ØªÙˆØ§ÙØ± مدير-غر٠(RoomManager) ÙˆØ§ØØ¯ Ùقط ÙÙŠ Ø´Ø #: scene/3d/room_manager.cpp msgid "Main" -msgstr "" +msgstr "رئيسي | الرئيسي" #: scene/3d/room_manager.cpp scene/animation/animation_blend_tree.cpp #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp @@ -23972,13 +23903,12 @@ msgid "Per-Wheel Motion" msgstr "زر العجلة للأسÙÙ„" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Engine Force" -msgstr "مستندات الإنترنت" +msgstr "قوة Ø§Ù„Ù…ØØ±Ùƒ" #: scene/3d/vehicle_body.cpp msgid "Brake" -msgstr "" +msgstr "ÙØ±Ø§Ù…Ù„ | مكابØ" #: scene/3d/vehicle_body.cpp msgid "Steering" @@ -23998,9 +23928,8 @@ msgid "Use As Steering" msgstr "" #: scene/3d/vehicle_body.cpp -#, fuzzy msgid "Wheel" -msgstr "العجلة Ù†ØÙˆ الأقصى." +msgstr "عجلة" #: scene/3d/vehicle_body.cpp msgid "Roll Influence" @@ -24130,14 +24059,12 @@ msgid "Fadeout Time" msgstr "وقت التلاشي X (ثواني):" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Auto Restart" -msgstr "إعادة تشغيل تلقائية:" +msgstr "إعادة تشغيل تلقائية" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Autorestart" -msgstr "إعادة تشغيل تلقائية:" +msgstr "إعادة تشغيل تلقائية" #: scene/animation/animation_blend_tree.cpp msgid "Delay" diff --git a/editor/translations/az.po b/editor/translations/az.po index cd3e8def9b..3a59e8aa41 100644 --- a/editor/translations/az.po +++ b/editor/translations/az.po @@ -2163,14 +2163,15 @@ msgstr "FavoritlÉ™r:" msgid "Recent:" msgstr "Son:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Axtar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "UyÄŸunlaÅŸmalar:" @@ -2230,8 +2231,8 @@ msgstr "ÆvÉ™zetmÉ™ mÉ™nbÉ™yini axtarı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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5410,6 +5411,10 @@ msgid "Drag And Drop Selection" msgstr "ÖlçmÉ™ seçimi" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11445,6 +11450,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Animasiyanı TÉ™mizlÉ™mÉ™" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/bg.po b/editor/translations/bg.po index 06d16ebe96..877823c869 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -2177,14 +2177,15 @@ msgstr "Любими:" msgid "Recent:" msgstr "ПоÑледни:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "ТърÑене:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "СъвпадениÑ:" @@ -2244,8 +2245,8 @@ msgstr "ТърÑене на замеÑтващ реÑурÑ:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5494,6 +5495,10 @@ msgid "Drag And Drop Selection" msgstr "ÐаÑтройки" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11659,6 +11664,11 @@ msgid "New Animation" msgstr "Ðова анимациÑ" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Филтриране на методите" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "СкороÑÑ‚:" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index c2ed1a7596..8379e2de5b 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -2233,14 +2233,15 @@ msgstr "ফেবরিট/পà§à¦°à¦¿à¦¯à¦¼-সমূহ:" msgid "Recent:" msgstr "সামà§à¦ªà§à¦°à¦¤à¦¿à¦•:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "মিলসমূহ:" @@ -2302,8 +2303,8 @@ msgstr "পà§à¦°à¦¤à¦¿à¦¸à§à¦¥à¦¾à¦ªà¦• রিসোরà§à¦¸-à¦à¦° অনৠ#: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5821,6 +5822,10 @@ msgid "Drag And Drop Selection" msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12482,6 +12487,11 @@ msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "ফিলà§à¦Ÿà¦¾à¦°à¦¸à¦®à§‚হ" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "গতি (FPS):" diff --git a/editor/translations/br.po b/editor/translations/br.po index 2d7b6fe900..f86b01cc44 100644 --- a/editor/translations/br.po +++ b/editor/translations/br.po @@ -2108,14 +2108,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2171,8 +2172,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5318,6 +5319,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11309,6 +11314,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Tro Fiñvskeudenn" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index 67f0296b05..b1ee6245f6 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -2143,14 +2143,15 @@ msgstr "Favorits:" msgid "Recent:" msgstr "Recents:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cerca:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Coincidències:" @@ -2210,8 +2211,8 @@ msgstr "Cerca Recurs Reemplaçant:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5607,6 +5608,10 @@ msgid "Drag And Drop Selection" msgstr "Elimina la Selecció del GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11962,6 +11967,11 @@ msgstr "Nova Animació" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "Filtrar mètodes" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "Velocitat (FPS):" diff --git a/editor/translations/cs.po b/editor/translations/cs.po index a166951396..c27334b374 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -2238,14 +2238,15 @@ msgstr "OblÃbené:" msgid "Recent:" msgstr "Nedávné:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Hledat:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Shody:" @@ -2305,8 +2306,8 @@ msgstr "Hledat náhradnà zdroj:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5681,6 +5682,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap Vyplnit výbÄ›r" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11953,6 +11958,11 @@ msgid "New Animation" msgstr "Nová animace" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrovat metody" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Rychlost:" diff --git a/editor/translations/da.po b/editor/translations/da.po index b4f7334278..3dc6f52da1 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -2227,14 +2227,15 @@ msgstr "Favoritter:" msgid "Recent:" msgstr "Seneste:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Søgning:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Matches:" @@ -2296,8 +2297,8 @@ msgstr "Søg Erstatnings Ressource:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5734,6 +5735,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap Slet Markerede" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12145,6 +12150,11 @@ msgid "New Animation" msgstr "Ny Animation Navn:" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filter mode:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/de.po b/editor/translations/de.po index 64b8268adb..5035a7aa5d 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -87,7 +87,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-09 21:11+0000\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" "Last-Translator: So Wieso <sowieso@dukun.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" @@ -96,7 +96,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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -520,9 +520,8 @@ msgid "Pressure" msgstr "Druck" #: core/os/input_event.cpp -#, fuzzy msgid "Pen Inverted" -msgstr "Umkehren" +msgstr "Stift invertiert" #: core/os/input_event.cpp msgid "Relative" @@ -2169,14 +2168,15 @@ msgstr "Favoriten:" msgid "Recent:" msgstr "Kürzlich:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Suche:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Treffer:" @@ -2236,8 +2236,8 @@ msgstr "Ersatzressource suchen:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5568,6 +5568,10 @@ msgid "Drag And Drop Selection" msgstr "Auswahl ziehen und fallen lassen" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Aussehen" @@ -11693,6 +11697,11 @@ msgid "New Animation" msgstr "Neue Animation" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Methoden filtern" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Geschwindigkeit:" @@ -23109,9 +23118,8 @@ msgstr "" "geändert werden." #: scene/3d/spatial.cpp -#, fuzzy msgid "Global Translation" -msgstr "Globales Transform" +msgstr "Globale Verschiebung" #: scene/3d/spatial.cpp msgid "Matrix" diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index 231863615b..c207124fcb 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -2060,14 +2060,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2123,8 +2124,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5256,6 +5257,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11206,6 +11211,10 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +msgid "Filter animations" +msgstr "" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/el.po b/editor/translations/el.po index 8511b4fdd2..85005d903a 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -2184,14 +2184,15 @@ msgstr "ΑγαπημÎνα:" msgid "Recent:" msgstr "Î Ïόσφατα:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Αναζήτηση:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Αντιστοιχίες:" @@ -2251,8 +2252,8 @@ msgstr "Αναζήτηση αντικαταστάτη πόÏου:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5663,6 +5664,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap ΓÎμισμα Επιλογής" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12044,6 +12049,11 @@ msgid "New Animation" msgstr "ÎÎα Κίνηση" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ΦιλτÏάÏισμα μεθόδων" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "ΤαχÏτητα:" diff --git a/editor/translations/en_Shaw.po b/editor/translations/en_Shaw.po index d69ca8d97f..45d0549a81 100644 --- a/editor/translations/en_Shaw.po +++ b/editor/translations/en_Shaw.po @@ -2083,14 +2083,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2146,8 +2147,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5284,6 +5285,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11257,6 +11262,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ð‘¦ð‘¯ð‘‘ð‘»ð‘ð‘©ð‘¤ð‘±ð‘–ð‘©ð‘¯ ð‘¥ð‘´ð‘›" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/eo.po b/editor/translations/eo.po index 3b651b3e97..5a251ba489 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -2206,14 +2206,15 @@ msgstr "Favoritaj:" msgid "Recent:" msgstr "Lastatempe:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Serĉo:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Matĉoj:" @@ -2273,8 +2274,8 @@ msgstr "Serĉi anstataÅiga risurco:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5656,6 +5657,10 @@ msgid "Drag And Drop Selection" msgstr "Enkadrigi elekton" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11939,6 +11944,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Forigi animacion?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/es.po b/editor/translations/es.po index 3c21955a46..872fedfdac 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -86,8 +86,8 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-06-29 10:04+0000\n" -"Last-Translator: Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>\n" +"PO-Revision-Date: 2022-07-27 13:26+0000\n" +"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -95,7 +95,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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -467,9 +467,8 @@ msgid "Command" msgstr "Command" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr " (FÃsica)" +msgstr "FÃsica" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -523,7 +522,7 @@ msgstr "Presionado" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Pluma Invertida" #: core/os/input_event.cpp msgid "Relative" @@ -725,14 +724,12 @@ msgid "Script Templates Search Path" msgstr "Ruta de Búsqueda de Plantillas de Scripts" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Autoload On Startup" -msgstr "Cargar automáticamente al inicio" +msgstr "Carga Automática de Control de Versiones al Inicio" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Plugin Name" -msgstr "Control de Versiones" +msgstr "Nombre del Plugin de Control de Versiones" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -1222,21 +1219,19 @@ msgid "Type" msgstr "Tipo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Establecer Manipulador" +msgstr "En el Manipulador" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" -msgstr "Establecer Manipulador" +msgstr "Fuera del Manipulador" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp msgid "Stream" -msgstr "" +msgstr "Stream" #: editor/animation_track_editor.cpp msgid "Start Offset" @@ -1257,9 +1252,8 @@ msgid "Animation" msgstr "Animación" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing" -msgstr "Entrada-Salida Suave" +msgstr "Suavizar" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1414,19 +1408,16 @@ msgid "Stream:" msgstr "Stream:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start (s):" -msgstr "Reiniciar (s):" +msgstr "Inicio (s):" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End (s):" -msgstr "Fundido de entrada (s):" +msgstr "Fin (s):" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Clip:" -msgstr "Animaciones:" +msgstr "Clip de Animación:" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -2180,14 +2171,15 @@ msgstr "Favoritos:" msgid "Recent:" msgstr "Recientes:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.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 +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Coincidencias:" @@ -2247,8 +2239,8 @@ msgstr "Buscar Recurso de Reemplazo:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2257,7 +2249,7 @@ msgstr "Abrir" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Propietarios de: %s (Total: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2984,9 +2976,8 @@ msgid "Custom release template not found." msgstr "Plantilla release personalizada no encontrada." #: editor/editor_export.cpp -#, fuzzy msgid "Prepare Template" -msgstr "Administrar Plantillas" +msgstr "Preparar Plantilla" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "The given export path doesn't exist." @@ -3002,9 +2993,8 @@ msgstr "Fallo al copiar la plantilla de exportación." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp -#, fuzzy msgid "PCK Embedding" -msgstr "Relleno" +msgstr "Integrar PCK" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." @@ -3403,7 +3393,7 @@ msgstr "Mostrar/Ocultar archivos ocultos." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." -msgstr "Ver elementos como una cuadrÃcula de miniaturas." +msgstr "Sesgo del nivel de división de la cuadrÃcula." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a list." @@ -4583,7 +4573,7 @@ msgstr "Exportar…" #: editor/editor_node.cpp msgid "Install Android Build Template..." -msgstr "Instalar plantilla de compilación de Android..." +msgstr "Instalar Plantilla de Compilación de Android..." #: editor/editor_node.cpp msgid "Open User Data Folder" @@ -4902,8 +4892,8 @@ msgstr "" "personalizado al exportarlo (agregando módulos, cambiando el AndroidManifest." "xml, etc.).\n" "Ten en cuenta que para realizar compilaciones personalizadas en lugar de " -"usar APKs predefinidos, la opción \"Use Custom Build\" deberÃa estar " -"habilitada en la configuración de exportación de Android." +"usar APKs predefinidos, la opción \"Usar Compilación Personalizada\" deberÃa " +"estar habilitada en la configuración de exportación de Android." #: editor/editor_node.cpp msgid "" @@ -5285,9 +5275,8 @@ msgstr "" "preset existente como ejecutable." #: editor/editor_run_native.cpp -#, fuzzy msgid "Project Run" -msgstr "Proyecto" +msgstr "Ejecutar Proyecto" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." @@ -5359,11 +5348,11 @@ msgstr "Atenuar Editor en Diálogo de Popup" #: editor/editor_settings.cpp main/main.cpp msgid "Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Modo de Reposo en Consumo Bajo del Procesador (µsec)" #: editor/editor_settings.cpp msgid "Unfocused Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Modo de Bajo Uso del Procesador Desconectado (µseg)" #: editor/editor_settings.cpp msgid "Separate Distraction Mode" @@ -5375,7 +5364,7 @@ msgstr "Abrir Capturas De Pantalla Automáticamente" #: editor/editor_settings.cpp msgid "Max Array Dictionary Items Per Page" -msgstr "" +msgstr "Cantidad Máxima de Elementos del Diccionario por Página" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp @@ -5453,7 +5442,7 @@ msgstr "Comprimir Recursos Binarios" #: editor/editor_settings.cpp msgid "Safe Save On Backup Then Rename" -msgstr "" +msgstr "Guardar de Forma Segura en el Backup y luego Renombrar" #: editor/editor_settings.cpp msgid "File Dialog" @@ -5465,7 +5454,7 @@ msgstr "Tamaño de las Miniaturas" #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "Paneles" #: editor/editor_settings.cpp msgid "Scene Tree" @@ -5488,9 +5477,8 @@ msgid "Auto Refresh Interval" msgstr "Intervalo de Auto Refrescar" #: editor/editor_settings.cpp -#, fuzzy msgid "Subresource Hue Tint" -msgstr "Sub-Recursos" +msgstr "Subrecurso Tinte del Tono" #: editor/editor_settings.cpp msgid "Color Theme" @@ -5570,9 +5558,12 @@ msgid "Mouse Extra Buttons Navigate History" msgstr "Botones Extra del Ratón Navegar por el Historial" #: editor/editor_settings.cpp -#, fuzzy msgid "Drag And Drop Selection" -msgstr "Seleccionar GridMap" +msgstr "Arrastrar y Soltar la Selección" + +#: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" #: editor/editor_settings.cpp msgid "Appearance" @@ -5616,7 +5607,7 @@ msgstr "Directriz de longitud de LÃnea de Columna Flexible" #: editor/editor_settings.cpp msgid "Line Length Guideline Hard Column" -msgstr "" +msgstr "Longitud de LÃnea de la GuÃa de la Columna RÃgida" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp msgid "Script List" @@ -5806,7 +5797,7 @@ msgstr "Nivel MÃnimo de División de CuadrÃcula" #: editor/editor_settings.cpp msgid "Grid Division Level Bias" -msgstr "" +msgstr "Sesgo del Nivel de División de la CuadrÃcula" #: editor/editor_settings.cpp msgid "Grid XZ Plane" @@ -5865,23 +5856,20 @@ msgid "Orbit Modifier" msgstr "Modificador de Órbita" #: editor/editor_settings.cpp -#, fuzzy msgid "Pan Modifier" -msgstr "Modo desplazamiento lateral" +msgstr "Modificador Panorámico" #: editor/editor_settings.cpp -#, fuzzy msgid "Zoom Modifier" -msgstr "Modificado/s" +msgstr "Modificador de Zoom" #: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Warped Mouse Panning" -msgstr "" +msgstr "Paneo del Mouse Deformado" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Feel" -msgstr "Modo de Navegación" +msgstr "Sensación de Navegación" #: editor/editor_settings.cpp msgid "Orbit Sensitivity" @@ -5924,9 +5912,8 @@ msgid "Freelook Activation Modifier" msgstr "Modificador de Activación de Vista Libre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Speed Zoom Link" -msgstr "Modificador de Velocidad de Vista Libre" +msgstr "Velocidad de Zoom de Vista Libre" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Grid Color" @@ -5974,7 +5961,7 @@ msgstr "Color del Borde del Viewport" #: editor/editor_settings.cpp msgid "Constrain Editor View" -msgstr "" +msgstr "Vista del Editor de Restricciones" #: editor/editor_settings.cpp msgid "Simple Panning" @@ -6035,14 +6022,12 @@ msgstr "Ubicación de la Ventana" #: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp #: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp #: scene/gui/control.cpp -#, fuzzy msgid "Rect" -msgstr "Completo" +msgstr "Rect" #: editor/editor_settings.cpp -#, fuzzy msgid "Rect Custom Position" -msgstr "Establecer Posición de Salida de Curva" +msgstr "Posición Personalizada de Rect" #: editor/editor_settings.cpp platform/android/export/export_plugin.cpp msgid "Screen" @@ -6108,24 +6093,23 @@ msgstr "Color de Palabra Clave" #: editor/editor_settings.cpp msgid "Control Flow Keyword Color" -msgstr "" +msgstr "Control de Flujo Color de Palabra Clave" #: editor/editor_settings.cpp -#, fuzzy msgid "Base Type Color" -msgstr "Tipo Base" +msgstr "Tipo de Color Base" #: editor/editor_settings.cpp msgid "Engine Type Color" -msgstr "" +msgstr "Tipo de Color del Engine" #: editor/editor_settings.cpp msgid "User Type Color" -msgstr "" +msgstr "Tipo de Color del Usuario" #: editor/editor_settings.cpp msgid "Comment Color" -msgstr "" +msgstr "Color de los Comentarios" #: editor/editor_settings.cpp msgid "String Color" @@ -6142,25 +6126,24 @@ msgid "Completion Background Color" msgstr "Completar Color de Fondo" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Completion Selected Color" -msgstr "Importar Seleccionado" +msgstr "Completar Color Seleccionado" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Existing Color" -msgstr "" +msgstr "Completar Color Existente" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Scroll Color" -msgstr "" +msgstr "Completar Color de Scroll" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Font Color" -msgstr "" +msgstr "Completar Color de la Fuente" #: editor/editor_settings.cpp msgid "Text Color" -msgstr "Color de Texto" +msgstr "Color del Texto" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Line Number Color" @@ -6199,33 +6182,28 @@ msgid "Line Length Guideline Color" msgstr "" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Word Highlighted Color" -msgstr "Resaltador de Sintaxis" +msgstr "Color de la Palabra Resaltada" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Number Color" msgstr "" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Function Color" -msgstr "Función" +msgstr "Función Color" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Member Variable Color" -msgstr "Cambiar nombre de variable" +msgstr "Color de la Variable Miembro" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Mark Color" -msgstr "Seleccionar Color" +msgstr "Marcar Color" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Bookmark Color" -msgstr "Marcadores" +msgstr "Color del Marcador" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Breakpoint Color" @@ -6240,14 +6218,12 @@ msgid "Code Folding Color" msgstr "" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Color" -msgstr "Resultados de la Búsqueda" +msgstr "Color del Resultado de Búsqueda" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Border Color" -msgstr "Resultados de la Búsqueda" +msgstr "Color de los Bordes del Resultado de Búsqueda" #: editor/editor_spin_slider.cpp msgid "Hold %s to round to integers. Hold Shift for more precise changes." @@ -6256,14 +6232,12 @@ msgstr "" "la tecla Mayús para cambios más precisos." #: editor/editor_spin_slider.cpp scene/gui/button.cpp -#, fuzzy msgid "Flat" -msgstr "Plano 0" +msgstr "Plano" #: editor/editor_spin_slider.cpp -#, fuzzy msgid "Hide Slider" -msgstr "Modo de Colisión" +msgstr "Ocultar Deslizador" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" @@ -6941,9 +6915,8 @@ msgid "Use Ambient" msgstr "" #: editor/import/resource_importer_bitmask.cpp -#, fuzzy msgid "Create From" -msgstr "Crear Carpeta" +msgstr "Crear Desde" #: editor/import/resource_importer_bitmask.cpp #: servers/audio/effects/audio_effect_compressor.cpp @@ -6963,9 +6936,8 @@ msgid "Delimiter" msgstr "Delimitador" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "ColorCorrect" -msgstr "Corrección del Color" +msgstr "Corrección de Color" #: editor/import/resource_importer_layered_texture.cpp msgid "No BPTC If RGB" @@ -6993,9 +6965,8 @@ msgstr "Filtro" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Mipmaps" -msgstr "Señales" +msgstr "Mipmaps" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp @@ -7026,14 +6997,12 @@ msgid "Vertical" msgstr "Vertical" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Generate Tangents" -msgstr "Generar puntos" +msgstr "Generar Tangentes" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Scale Mesh" -msgstr "Modo de Escalado" +msgstr "Escalar Mesh" #: editor/import/resource_importer_obj.cpp msgid "Offset Mesh" @@ -7041,14 +7010,12 @@ msgstr "Offset de Malla" #: editor/import/resource_importer_obj.cpp #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Octahedral Compression" -msgstr "Compresión" +msgstr "Compresión Octaédrica" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Optimize Mesh Flags" -msgstr "Tamaño de los Indicadores" +msgstr "Optimizar Marcadores de Malla" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" @@ -7092,29 +7059,24 @@ msgstr "Importar como Escenas y Materiales Múltiples" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Nodes" msgstr "Nodos" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Type" -msgstr "Regresar" +msgstr "Tipo de RaÃz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Name" -msgstr "Nombre Remoto" +msgstr "Nombre de RaÃz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Scale" -msgstr "Escala" +msgstr "Escala de RaÃz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Custom Script" -msgstr "CustomNode" +msgstr "Script Personalizado" #: editor/import/resource_importer_scene.cpp scene/resources/texture.cpp msgid "Storage" @@ -7129,62 +7091,52 @@ msgid "Materials" msgstr "Materiales" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep On Reimport" -msgstr "Reimportar" +msgstr "Seguir Reimportando" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp -#, fuzzy msgid "Meshes" -msgstr "Malla" +msgstr "Meshes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Ensure Tangents" -msgstr "Modificar Tangente de Curva" +msgstr "Asegurar Tangentes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Light Baking" -msgstr "Lightmapping" +msgstr "Bake de Luces" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Lightmap Texel Size" -msgstr "Calcular Lightmaps" +msgstr "Tamaño Lightmap Texel" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Skins" msgstr "" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Named Skins" -msgstr "Usar Ajuste de Escalado" +msgstr "Usar Skins con Nombre" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "External Files" -msgstr "Abrir un Archivo" +msgstr "Archivos Externos" #: editor/import/resource_importer_scene.cpp msgid "Store In Subdir" msgstr "" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Filter Script" -msgstr "Filtrar scripts" +msgstr "Filtrar Script" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep Custom Tracks" -msgstr "Transformar" +msgstr "Mantener Pistas Personalizadas" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Optimizer" -msgstr "Optimizar" +msgstr "Optimizador" #: editor/import/resource_importer_scene.cpp #: editor/plugins/item_list_editor_plugin.cpp main/main.cpp @@ -7198,9 +7150,8 @@ msgstr "Optimizar" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp #: scene/gui/rich_text_label.cpp scene/resources/curve.cpp #: scene/resources/environment.cpp scene/resources/material.cpp -#, fuzzy msgid "Enabled" -msgstr "Activar" +msgstr "Activado" #: editor/import/resource_importer_scene.cpp msgid "Max Linear Error" @@ -7211,19 +7162,16 @@ msgid "Max Angular Error" msgstr "Error Angular Máximo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Max Angle" -msgstr "Valor" +msgstr "Ãngulo Máximo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Remove Unused Tracks" -msgstr "Eliminar Pista de Animación" +msgstr "Eliminar Pistas Sin Usar" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Clips" -msgstr "Clips de Animación" +msgstr "Clips" #: editor/import/resource_importer_scene.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/area.cpp scene/3d/cpu_particles.cpp @@ -7290,18 +7238,16 @@ msgid "2D, Detect 3D" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "2D Pixel" -msgstr "Pixeles Sólidos" +msgstr "Pixel 2D" #: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp msgid "Lossy Quality" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "HDR Mode" -msgstr "Modo de Selección" +msgstr "Modo HDR" #: editor/import/resource_importer_texture.cpp msgid "BPTC LDR" @@ -7315,45 +7261,40 @@ msgid "Normal Map" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Process" -msgstr "Post procesado" +msgstr "Proceso" #: editor/import/resource_importer_texture.cpp msgid "Fix Alpha Border" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Premult Alpha" -msgstr "Editar PolÃgono" +msgstr "Premult Alpha" #: editor/import/resource_importer_texture.cpp msgid "Hdr As Srgb" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Invert Color" -msgstr "Vértice" +msgstr "Invertir Color" #: editor/import/resource_importer_texture.cpp msgid "Normal Map Invert Y" msgstr "Invertir Y en Mapa Normal" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Size Limit" -msgstr "LÃmites" +msgstr "Tamaño LÃmite" #: editor/import/resource_importer_texture.cpp msgid "Detect 3D" msgstr "" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "SVG" -msgstr "HSV" +msgstr "SVG" #: editor/import/resource_importer_texture.cpp msgid "" @@ -7370,18 +7311,16 @@ msgid "Import Mode" msgstr "Modo de Importación" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Crop To Region" -msgstr "Establecer Región de Tile" +msgstr "Recortar la Región" #: editor/import/resource_importer_texture_atlas.cpp msgid "Trim Alpha Border From Region" msgstr "" #: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp -#, fuzzy msgid "Force" -msgstr "Forzar Push" +msgstr "Fuerza" #: editor/import/resource_importer_wav.cpp msgid "8 Bit" @@ -7393,41 +7332,35 @@ msgid "Mono" msgstr "" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Max Rate" -msgstr "Nodo Mix" +msgstr "Tasa Máxima" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Max Rate Hz" -msgstr "Nodo Mix" +msgstr "Tasa Máxima Hz" #: editor/import/resource_importer_wav.cpp msgid "Trim" msgstr "" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Normalize" -msgstr "Formato" +msgstr "Normalizar" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Mode" -msgstr "Modo de Movimiento" +msgstr "Modo Bucle" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Begin" -msgstr "Modo de Movimiento" +msgstr "Inicio del Bucle" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop End" -msgstr "Modo de Movimiento" +msgstr "Fin del Bucle" #: editor/import_defaults_editor.cpp msgid "Select Importer" @@ -7514,14 +7447,12 @@ msgid "Raw" msgstr "Raw" #: editor/inspector_dock.cpp -#, fuzzy msgid "Capitalized" -msgstr "Capitalizar" +msgstr "Capitalización" #: editor/inspector_dock.cpp -#, fuzzy msgid "Localized" -msgstr "Idioma" +msgstr "Localizado" #: editor/inspector_dock.cpp msgid "Localization not available for current language." @@ -8075,9 +8006,8 @@ msgid "New" msgstr "Nuevo" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Paste As Reference" -msgstr "%s Referencia de Clase" +msgstr "Pegar Como Referencia" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -8569,25 +8499,21 @@ msgid "Loading..." msgstr "Cargar..." #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "First" msgstr "Primero" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Previous" msgstr "Anterior" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Next" msgstr "Siguiente" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Last" msgstr "Último" @@ -9206,9 +9132,8 @@ msgid "View" msgstr "Ver" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show" -msgstr "Ver CuadrÃcula" +msgstr "Mostrar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show When Snapping" @@ -9216,12 +9141,11 @@ msgstr "Mostrar Al Ajustar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Hide" -msgstr "" +msgstr "Ocultar" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Toggle Grid" -msgstr "Cambiar Modo" +msgstr "Cambiar CuadrÃcula" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -9843,7 +9767,6 @@ msgstr "" "%s" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "MeshLibrary" msgstr "LibrerÃa de Mallas" @@ -9868,14 +9791,12 @@ msgid "Update from Scene" msgstr "Actualizar desde escena" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply without Transforms" -msgstr "Aplicar Transformaciones al MeshInstance" +msgstr "Aplicar sin Transformaciones" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply with Transforms" -msgstr "Aplicar Transformaciones al MeshInstance" +msgstr "Aplicar con Transformaciones" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." @@ -10744,19 +10665,16 @@ msgid "External" msgstr "" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Use External Editor" -msgstr "Depurar con Editor Externo" +msgstr "Usar un Editor Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Exec Path" -msgstr "Ruta de Exportación" +msgstr "Ruta de Ejecución" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Script Temperature Enabled" -msgstr "Seleccionar el archivo de la plantilla" +msgstr "Temperatura del Script Activada" #: editor/plugins/script_editor_plugin.cpp msgid "Highlight Current Script" @@ -10771,14 +10689,12 @@ msgid "Current Script Background Color" msgstr "Color de Fondo del Script Actual" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Group Help Pages" -msgstr "Agrupar Seleccionados" +msgstr "Páginas de Ayuda para Grupos" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Sort Scripts By" -msgstr "Crear Script" +msgstr "Ordenar Scripts por" #: editor/plugins/script_editor_plugin.cpp msgid "List Script Names As" @@ -10995,8 +10911,8 @@ msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Este shader ha sido modificado en disco.\n" -"¿Qué acciones deben tomarse?" +"Este shader ha sido modificado en el disco.\n" +"¿Qué acción debe tomarse?" #: editor/plugins/shader_editor_plugin.cpp scene/resources/material.cpp msgid "Shader" @@ -11610,9 +11526,8 @@ msgid "Manipulator Gizmo Opacity" msgstr "" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Show Viewport Rotation Gizmo" -msgstr "Bloquear Rotación de Vista" +msgstr "Mostrar Gizmo de Rotación del Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "Unnamed Gizmo" @@ -11664,9 +11579,8 @@ msgid "Invalid geometry, can't replace by mesh." msgstr "GeometrÃa inválida, no puede ser reemplazada por una malla." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to MeshInstance2D" -msgstr "Convertir a Mesh2D" +msgstr "Convertir a MeshInstance2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." @@ -11769,6 +11683,11 @@ msgid "New Animation" msgstr "Nueva Animación" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrar métodos" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidad:" @@ -12066,9 +11985,8 @@ msgstr "" "¿Cerrar de todos modos?" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Type" -msgstr "Eliminar Tile" +msgstr "Eliminar Tipo" #: editor/plugins/theme_editor_plugin.cpp msgid "" @@ -12112,14 +12030,12 @@ msgstr "" "Añade más propiedades manualmente o impórtalas desde otro Theme." #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Add Theme Type" -msgstr "Añadir Tipo de Elemento" +msgstr "Añadir Tipo de Theme" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Theme Type" -msgstr "Eliminar Remoto" +msgstr "Eliminar Tipo de Theme" #: editor/plugins/theme_editor_plugin.cpp msgid "Add Color Item" @@ -12566,55 +12482,46 @@ msgid "Clear Transform" msgstr "Reestablecer Transformación" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Tile Map" -msgstr "Dibujar TileMap" +msgstr "Mapa de Tiles" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Palette Min Width" -msgstr "" +msgstr "Ancho MÃnimo de la Paleta" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Palette Item H Separation" -msgstr "Separador con nombre" +msgstr "Separación del Elemento H de la Paleta" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Names" -msgstr "Mostrar Todos los Idiomas" +msgstr "Mostrar Nombres de Tiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Ids" -msgstr "Mostrar Reglas" +msgstr "Mostrar ID de los Tiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Sort Tiles By Name" -msgstr "Ordenar archivos" +msgstr "Ordenar Tiles por Nombre" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Bucket Fill Preview" -msgstr "Bote de Relleno" +msgstr "Vista previa del Bote de Relleno" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Editor Side" -msgstr "Editor" +msgstr "Lado del Editor" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Display Grid" -msgstr "Mostrar Overdraw" +msgstr "Mostrar CuadrÃcula" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Axis Color" -msgstr "Seleccionar Color" +msgstr "Color de los Ejes" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Texture(s) to TileSet." @@ -12953,7 +12860,6 @@ msgid "This property can't be changed." msgstr "Esta propiedad no se puede cambiar." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Snap Options" msgstr "Opciones de Ajuste" @@ -12982,9 +12888,8 @@ msgid "Separation" msgstr "Separación" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Tile" -msgstr "Seleccionar" +msgstr "Tiles Seleccionados" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/light_2d.cpp scene/2d/line_2d.cpp scene/2d/mesh_instance_2d.cpp @@ -12993,14 +12898,12 @@ msgstr "Seleccionar" #: scene/gui/nine_patch_rect.cpp scene/gui/texture_rect.cpp #: scene/resources/material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Texture" -msgstr "Texto" +msgstr "Textura" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tex Offset" -msgstr "Desplazamiento de Byte" +msgstr "Desplazamiento de Textura" #: editor/plugins/tile_set_editor_plugin.cpp modules/csg/csg_shape.cpp #: scene/2d/canvas_item.cpp scene/2d/particles_2d.cpp @@ -13010,79 +12913,64 @@ msgstr "Material" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/canvas_item.cpp #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Modulate" -msgstr "Rellenar" +msgstr "Modular" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Mode" -msgstr "Cambiar Modo" +msgstr "Modo Tile" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Autotile Bitmask Mode" -msgstr "Modo de Bitmask" +msgstr "Modo Bitmask Automático" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Size" -msgstr "Tamaño del Contorno" +msgstr "Tamaño de Subtile" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Spacing" -msgstr "Espaciado de LÃnea" +msgstr "Espaciado de Subtile" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occluder Offset" -msgstr "Crear PolÃgono Oclusor" +msgstr "Desplazamiento del Oclusor" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Offset" -msgstr "Modo de Navegación" +msgstr "Desplazamiento de Navegación" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Offset" -msgstr "Desplazamiento Base" +msgstr "Desplazamiento del Shape" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Transform" -msgstr "Transformar" +msgstr "Transformar Shape" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision" -msgstr "Colisión" +msgstr "Colisión Seleccionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way" -msgstr "Sólo selección" +msgstr "Colisión Seleccionada en Una Dirección" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision One Way Margin" -msgstr "Modo de Colisión" +msgstr "Margen Seleccionado de Colisión en Una Dirección" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Navigation" -msgstr "Navegación Visible" +msgstr "Navegación Seleccionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Occlusion" -msgstr "Seleccionar" +msgstr "Oclusión Seleccionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tileset Script" -msgstr "Filtrar scripts" +msgstr "Script de Tileset" #: editor/plugins/tile_set_editor_plugin.cpp msgid "TileSet" @@ -14293,9 +14181,8 @@ msgid "" msgstr "" #: editor/project_export.cpp -#, fuzzy msgid "More Info..." -msgstr "Mover a..." +msgstr "Más información..." #: editor/project_export.cpp msgid "Export PCK/Zip..." @@ -14322,18 +14209,16 @@ msgid "ZIP File" msgstr "Archivo ZIP" #: editor/project_export.cpp -#, fuzzy msgid "Godot Project Pack" -msgstr "Godot Game Pack" +msgstr "Paquete de Proyectos de Godot" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" msgstr "Faltan plantillas de exportación para esta plataforma:" #: editor/project_export.cpp -#, fuzzy msgid "Project Export" -msgstr "Fundadores del Proyecto" +msgstr "Exportación del Proyecto" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -14648,7 +14533,6 @@ msgstr "" #. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp -#, fuzzy msgctxt "Application" msgid "Project Manager" msgstr "Administrador de Proyectos" @@ -15456,14 +15340,12 @@ msgid "Another node already uses this unique name in the scene." msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Enable Scene Unique Name" -msgstr "Nombre Único" +msgstr "Activar Nombre Único de Escena" #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp -#, fuzzy msgid "Disable Scene Unique Name" -msgstr "Nombre Único" +msgstr "Desactivar Nombre Único de Escena" #: editor/scene_tree_dock.cpp msgid "New Scene Root" @@ -15638,18 +15520,16 @@ msgid "Clear Inheritance? (No Undo!)" msgstr "¿Quieres limpiar la herencia? (No se puede deshacer)" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Show Scene Tree Root Selection" -msgstr "Centrar Selección" +msgstr "Mostrar Selección de la RaÃz del Ãrbol de Escenas" #: editor/scene_tree_dock.cpp msgid "Derive Script Globals By Name" msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Use Favorites Root Selection" -msgstr "Seleccionar Fotogramas" +msgstr "Usar Selección de RaÃces Favoritas" #: editor/scene_tree_editor.cpp msgid "Toggle Visible" @@ -16108,23 +15988,20 @@ msgid "Change Particles AABB" msgstr "Cambiar partÃculas AABB" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Reflection Probe" -msgstr "Seleccionar Propiedad" +msgstr "Sonda de Reflexión" #: editor/spatial_editor_gizmos.cpp msgid "Change Probe Extents" msgstr "Cambiar Alcance de la Sonda" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "GI Probe" -msgstr "Calcular GI Probe" +msgstr "Sonda GI" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Baked Indirect Light" -msgstr "Iluminación indirecta" +msgstr "Iluminación Indirecta Bakeada" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Sphere Shape Radius" @@ -16155,24 +16032,20 @@ msgid "Change Ray Shape Length" msgstr "Cambiar Longitud de la Forma del Rayo" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Edge" -msgstr "Modo de Navegación" +msgstr "Borde de Navegación" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Edge Disabled" -msgstr "Modo de Navegación" +msgstr "Borde de Navegación Desactivado" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid" -msgstr "Modo de Navegación" +msgstr "Navegación Sólida" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid Disabled" -msgstr "Modo de Navegación" +msgstr "Navegación Sólida Desactivada" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body A" @@ -16195,9 +16068,8 @@ msgid "Set Room Point Position" msgstr "Establecer Posición del Room Point" #: editor/spatial_editor_gizmos.cpp scene/3d/portal.cpp -#, fuzzy msgid "Portal Margin" -msgstr "Asignar Margen" +msgstr "Margen del Portal" #: editor/spatial_editor_gizmos.cpp msgid "Portal Edge" @@ -16216,15 +16088,13 @@ msgid "Portal Front" msgstr "" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Portal Back" -msgstr "Retroceder" +msgstr "Portal de Regreso" #: editor/spatial_editor_gizmos.cpp scene/2d/light_occluder_2d.cpp #: scene/2d/tile_map.cpp -#, fuzzy msgid "Occluder" -msgstr "Modo de Oclusión" +msgstr "Oclusor" #: editor/spatial_editor_gizmos.cpp msgid "Set Occluder Sphere Radius" @@ -16243,19 +16113,16 @@ msgid "Set Occluder Hole Point Position" msgstr "Establecer posición del orificio del oclusor" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Polygon Front" -msgstr "Crear PolÃgono Oclusor" +msgstr "Frente del PolÃgono Oclusor" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Polygon Back" -msgstr "Crear PolÃgono Oclusor" +msgstr "Posterior del PolÃgono Oclusor" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Occluder Hole" -msgstr "Crear PolÃgono Oclusor" +msgstr "Orificio Oclusor" #: main/main.cpp msgid "Godot Physics" @@ -16264,32 +16131,28 @@ msgstr "" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp msgid "Use BVH" -msgstr "" +msgstr "Usar BVH" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp -#, fuzzy msgid "BVH Collision Margin" -msgstr "Modo de Colisión" +msgstr "Margen de Colisión BVH" #: main/main.cpp -#, fuzzy msgid "Crash Handler" -msgstr "Establecer Manipulador" +msgstr "Manipulador de Colisiones" #: main/main.cpp -#, fuzzy msgid "Multithreaded Server" -msgstr "Establecer multinodo" +msgstr "Servidor Multihilo" #: main/main.cpp msgid "RID Pool Prealloc" msgstr "" #: main/main.cpp -#, fuzzy msgid "Debugger stdout" -msgstr "Depurador" +msgstr "Depurador stdout" #: main/main.cpp msgid "Max Chars Per Second" @@ -16320,14 +16183,12 @@ msgid "File Logging" msgstr "" #: main/main.cpp -#, fuzzy msgid "Enable File Logging" -msgstr "Habilitar Filtrado" +msgstr "Activar Registro de Archivos" #: main/main.cpp -#, fuzzy msgid "Log Path" -msgstr "Copiar Ruta" +msgstr "Ruta del Registro" #: main/main.cpp msgid "Max Log Files" @@ -16358,14 +16219,12 @@ msgid "Allow hiDPI" msgstr "" #: main/main.cpp -#, fuzzy msgid "V-Sync" -msgstr "Sincronizar" +msgstr "Sincronización Vertical" #: main/main.cpp -#, fuzzy msgid "Use V-Sync" -msgstr "Usar Snap" +msgstr "Usar Sincronización Vertical" #: main/main.cpp msgid "Per Pixel Transparency" @@ -16380,23 +16239,20 @@ msgid "Intended Usage" msgstr "" #: main/main.cpp -#, fuzzy msgid "Framebuffer Allocation" -msgstr "Seleccionar Fotogramas" +msgstr "Asignación del Buffer de Imágenes" #: main/main.cpp platform/uwp/os_uwp.cpp -#, fuzzy msgid "Energy Saving" -msgstr "Error al Guardar" +msgstr "Ahorro de EnergÃa" #: main/main.cpp msgid "Threads" msgstr "" #: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h -#, fuzzy msgid "Thread Model" -msgstr "Cambiar Modo" +msgstr "Modelo de Hilo" #: main/main.cpp msgid "Thread Safe BVH" @@ -16408,25 +16264,21 @@ msgstr "" #: main/main.cpp platform/javascript/export/export.cpp #: platform/uwp/export/export.cpp -#, fuzzy msgid "Orientation" -msgstr "Documentación en lÃnea" +msgstr "Orientación" #: main/main.cpp scene/gui/scroll_container.cpp scene/gui/text_edit.cpp #: scene/main/scene_tree.cpp scene/register_scene_types.cpp -#, fuzzy msgid "Common" -msgstr "Comunidad" +msgstr "Común" #: main/main.cpp -#, fuzzy msgid "Physics FPS" -msgstr "Fotogramas de FÃsica %" +msgstr "FÃsica FPS" #: main/main.cpp -#, fuzzy msgid "Force FPS" -msgstr "Forzar Push" +msgstr "Forzar FPS" #: main/main.cpp msgid "Enable Pause Aware Picking" @@ -16455,19 +16307,16 @@ msgid "Verbose stdout" msgstr "" #: main/main.cpp scene/main/scene_tree.cpp scene/resources/multimesh.cpp -#, fuzzy msgid "Physics Interpolation" -msgstr "Modo de Interpolación" +msgstr "Interpolación de FÃsica" #: main/main.cpp -#, fuzzy msgid "Enable Warnings" -msgstr "Habilitar Filtrado" +msgstr "Activar Advertencias" #: main/main.cpp -#, fuzzy msgid "Frame Delay Msec" -msgstr "Seleccionar Fotogramas" +msgstr "Retraso de los Fotogramas Msec" #: main/main.cpp msgid "Low Processor Mode" @@ -16486,14 +16335,12 @@ msgid "Hide Home Indicator" msgstr "" #: main/main.cpp -#, fuzzy msgid "Input Devices" -msgstr "Todos los Dispositivos" +msgstr "Dispositivos de Entrada" #: main/main.cpp -#, fuzzy msgid "Pointing" -msgstr "Punto" +msgstr "Apuntador" #: main/main.cpp msgid "Touch Delay" @@ -16504,21 +16351,18 @@ msgid "GLES3" msgstr "" #: main/main.cpp servers/visual_server.cpp -#, fuzzy msgid "Shaders" -msgstr "Shader" +msgstr "Shaders" #: main/main.cpp -#, fuzzy msgid "Debug Shader Fallbacks" -msgstr "Forzar Shader Fallbacks" +msgstr "Depurar Fallbacks de Shader" #: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp #: scene/3d/world_environment.cpp scene/main/scene_tree.cpp #: scene/resources/world.cpp -#, fuzzy msgid "Environment" -msgstr "Ver Entorno" +msgstr "Entorno" #: main/main.cpp msgid "Default Clear Color" @@ -16529,9 +16373,8 @@ msgid "Boot Splash" msgstr "" #: main/main.cpp -#, fuzzy msgid "Show Image" -msgstr "Mostrar Huesos" +msgstr "Mostrar Imagen" #: main/main.cpp msgid "Image" @@ -16546,14 +16389,12 @@ msgid "Use Filter" msgstr "Usar Filtro" #: main/main.cpp scene/resources/style_box.cpp -#, fuzzy msgid "BG Color" -msgstr "Colores" +msgstr "Color de Fondo" #: main/main.cpp -#, fuzzy msgid "macOS Native Icon" -msgstr "Establecer Icono de Tile" +msgstr "Icono Nativo de macOS" #: main/main.cpp msgid "Windows Native Icon" @@ -16576,14 +16417,12 @@ msgid "Emulate Mouse From Touch" msgstr "" #: main/main.cpp -#, fuzzy msgid "Mouse Cursor" -msgstr "Botón del Mouse" +msgstr "Cursor del Mouse" #: main/main.cpp -#, fuzzy msgid "Custom Image" -msgstr "CustomNode" +msgstr "Imagen Personalizada" #: main/main.cpp msgid "Custom Image Hotspot" @@ -16594,14 +16433,12 @@ msgid "Tooltip Position Offset" msgstr "Offset de la Posición del Tooltip" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp -#, fuzzy msgid "Debugger Agent" -msgstr "Depurador" +msgstr "Agente de Depuración" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp -#, fuzzy msgid "Wait For Debugger" -msgstr "Depurador" +msgstr "Esperar al Depurador" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp msgid "Wait Timeout" @@ -16616,20 +16453,17 @@ msgid "Unhandled Exception Policy" msgstr "" #: main/main.cpp -#, fuzzy msgid "Main Loop Type" -msgstr "Buscar Tipo de Nodo" +msgstr "Tipo de Bucle Principal" #: main/main.cpp scene/gui/texture_progress.cpp #: scene/gui/viewport_container.cpp -#, fuzzy msgid "Stretch" -msgstr "Buscar" +msgstr "Estirar" #: main/main.cpp -#, fuzzy msgid "Aspect" -msgstr "Inspector" +msgstr "Aspecto" #: main/main.cpp msgid "Shrink" @@ -16640,14 +16474,12 @@ msgid "Auto Accept Quit" msgstr "" #: main/main.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Quit On Go Back" -msgstr "Retroceder" +msgstr "Salir y Regresar" #: main/main.cpp scene/main/viewport.cpp -#, fuzzy msgid "Snap Controls To Pixels" -msgstr "Ajustar a los Lados del Nodo" +msgstr "Ajustar Controles a PÃxeles" #: main/main.cpp msgid "Dynamic Fonts" @@ -16682,35 +16514,30 @@ msgid "Change Torus Outer Radius" msgstr "Cambiar Radio Externo de Torus" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Operation" -msgstr "Opciones" +msgstr "Operación" #: modules/csg/csg_shape.cpp msgid "Calculate Tangents" msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Use Collision" -msgstr "Colisión" +msgstr "Usar Colisión" #: modules/csg/csg_shape.cpp servers/physics_2d_server.cpp -#, fuzzy msgid "Collision Layer" -msgstr "Modo de Colisión" +msgstr "Capa de Colisión" #: modules/csg/csg_shape.cpp scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp #: scene/3d/ray_cast.cpp scene/3d/spring_arm.cpp #: scene/resources/navigation_mesh.cpp servers/physics_server.cpp -#, fuzzy msgid "Collision Mask" -msgstr "Modo de Colisión" +msgstr "Máscara de Colisión" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Invert Faces" -msgstr "Convertir Mayúsculas/Minúsculas" +msgstr "Invertir Caras" #: modules/csg/csg_shape.cpp scene/2d/navigation_agent_2d.cpp #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_agent.cpp @@ -16728,33 +16555,28 @@ msgid "Radial Segments" msgstr "Segmentos Radiales" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Rings" -msgstr "Advertencias" +msgstr "Anillos" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Smooth Faces" -msgstr "Suavizado" +msgstr "Caras Suaves" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Sides" -msgstr "Mostrar GuÃas" +msgstr "Lados" #: modules/csg/csg_shape.cpp msgid "Cone" msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Inner Radius" -msgstr "Cambiar Radio Interno de Torus" +msgstr "Radio Interior" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Outer Radius" -msgstr "Cambiar Radio Externo de Torus" +msgstr "Radio Exterior" #: modules/csg/csg_shape.cpp msgid "Ring Sides" @@ -16763,9 +16585,8 @@ msgstr "" #: modules/csg/csg_shape.cpp scene/2d/collision_polygon_2d.cpp #: scene/2d/light_occluder_2d.cpp scene/2d/polygon_2d.cpp #: scene/3d/collision_polygon.cpp -#, fuzzy msgid "Polygon" -msgstr "PolÃgonos" +msgstr "PolÃgono" #: modules/csg/csg_shape.cpp msgid "Spin Degrees" @@ -16776,14 +16597,12 @@ msgid "Spin Sides" msgstr "" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Node" -msgstr "Pegar Nodos" +msgstr "Ruta del Nodo" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Interval Type" -msgstr "Crear Vértice Interno" +msgstr "Tipo de Intervalo de Ruta" #: modules/csg/csg_shape.cpp msgid "Path Interval" @@ -16798,14 +16617,12 @@ msgid "Path Rotation" msgstr "Rotación de Trayectoria" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Local" -msgstr "Crear Local" +msgstr "Ruta Local" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Continuous U" -msgstr "Continuo" +msgstr "Ruta Continua U" #: modules/csg/csg_shape.cpp msgid "Path U Distance" @@ -16816,24 +16633,20 @@ msgid "Path Joined" msgstr "Ruta Unida" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Compression Mode" -msgstr "Modo de Colisión" +msgstr "Modo de Compresión" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Transfer Channel" -msgstr "Cambio de Transformación" +msgstr "Canal de Transferencia" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Channel Count" -msgstr "Instanciar" +msgstr "Conteo de Canales" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Always Ordered" -msgstr "Mostrar Siempre la CuadrÃcula" +msgstr "Siempre Ordenado" #: modules/enet/networked_multiplayer_enet.cpp msgid "Server Relay" @@ -16848,9 +16661,8 @@ msgid "DTLS Hostname" msgstr "" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Use DTLS" -msgstr "Usar Snap" +msgstr "Usar DTLS" #: modules/fbx/editor_scene_importer_fbx.cpp msgid "FBX" @@ -16865,24 +16677,21 @@ msgid "Config File" msgstr "Archivo de Configuración" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Load Once" -msgstr "Cargar Recurso" +msgstr "Cargar Una Vez" #: modules/gdnative/gdnative.cpp #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Singleton" -msgstr "Esqueleto" +msgstr "Singleton" #: modules/gdnative/gdnative.cpp msgid "Symbol Prefix" msgstr "Prefijo de SÃmbolo" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Reloadable" -msgstr "Recargar" +msgstr "Recargable" #: modules/gdnative/gdnative.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp @@ -16947,9 +16756,8 @@ msgid "Script Class" msgstr "Clase del Script" #: modules/gdnative/nativescript/nativescript.cpp -#, fuzzy msgid "Icon Path" -msgstr "Foco en Ruta" +msgstr "Ruta del Icono" #: modules/gdnative/register_types.cpp msgid "GDNative" @@ -16957,18 +16765,16 @@ msgstr "GDNative" #: modules/gdscript/editor/gdscript_highlighter.cpp #: modules/gdscript/gdscript.cpp -#, fuzzy msgid "GDScript" -msgstr "Script" +msgstr "GDScript" #: modules/gdscript/editor/gdscript_highlighter.cpp msgid "Function Definition Color" msgstr "" #: modules/gdscript/editor/gdscript_highlighter.cpp -#, fuzzy msgid "Node Path Color" -msgstr "Copiar Ruta del Nodo" +msgstr "Color de la Ruta del Nodo" #: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp msgid "Max Call Stack" @@ -17031,9 +16837,8 @@ msgid "Language Server" msgstr "Servidor de Lenguaje" #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Enable Smart Resolve" -msgstr "No se puede resolver" +msgstr "Activar Smart Resolve" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Show Native Symbols In Editor" @@ -17052,42 +16857,36 @@ msgid "Export GLTF..." msgstr "Exportar GLTF..." #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Buffer View" -msgstr "Vista Trasera" +msgstr "Vista del Buffer" #: modules/gltf/gltf_accessor.cpp modules/gltf/gltf_buffer_view.cpp msgid "Byte Offset" msgstr "Desplazamiento de Byte" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Component Type" -msgstr "Componentes" +msgstr "Tipo de Componente" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Normalized" -msgstr "Formato" +msgstr "Normalizado" #: modules/gltf/gltf_accessor.cpp msgid "Count" msgstr "Cuenta" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Min" -msgstr "MiB" +msgstr "Min" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Max" -msgstr "Mix" +msgstr "Max" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Sparse Count" -msgstr "Instanciar" +msgstr "Recuento Parcial" #: modules/gltf/gltf_accessor.cpp msgid "Sparse Indices Buffer View" @@ -17110,23 +16909,20 @@ msgid "Sparse Values Byte Offset" msgstr "" #: modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Buffer" -msgstr "Vista Trasera" +msgstr "Buffer" #: modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Byte Length" -msgstr "Theme Predeterminado" +msgstr "Longitud de Bytes" #: modules/gltf/gltf_buffer_view.cpp msgid "Byte Stride" msgstr "" #: modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Indices" -msgstr "Todos los Dispositivos" +msgstr "Ãndices" #: modules/gltf/gltf_camera.cpp msgid "FOV Size" @@ -17137,9 +16933,8 @@ msgid "Zfar" msgstr "" #: modules/gltf/gltf_camera.cpp -#, fuzzy msgid "Znear" -msgstr "Lineal" +msgstr "Znear" #: modules/gltf/gltf_light.cpp scene/2d/canvas_modulate.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/light_2d.cpp scene/2d/polygon_2d.cpp @@ -17149,9 +16944,8 @@ msgstr "Lineal" #: scene/resources/environment.cpp scene/resources/material.cpp #: scene/resources/particles_material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Color" -msgstr "Colores" +msgstr "Color" #: modules/gltf/gltf_light.cpp scene/3d/reflection_probe.cpp #: scene/resources/environment.cpp @@ -17159,9 +16953,8 @@ msgid "Intensity" msgstr "" #: modules/gltf/gltf_light.cpp scene/2d/light_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Range" -msgstr "Cambiar" +msgstr "Rango" #: modules/gltf/gltf_light.cpp msgid "Inner Cone Angle" @@ -17172,42 +16965,36 @@ msgid "Outer Cone Angle" msgstr "" #: modules/gltf/gltf_mesh.cpp -#, fuzzy msgid "Blend Weights" -msgstr "Calcular Lightmaps" +msgstr "Mezcla de Pesos" #: modules/gltf/gltf_mesh.cpp msgid "Instance Materials" msgstr "Materiales de Instancia" #: modules/gltf/gltf_node.cpp scene/3d/skeleton.cpp -#, fuzzy msgid "Parent" -msgstr "Reemparentar" +msgstr "Padre" #: modules/gltf/gltf_node.cpp -#, fuzzy msgid "Xform" -msgstr "Plataforma" +msgstr "Xform" #: modules/gltf/gltf_node.cpp scene/3d/mesh_instance.cpp msgid "Skin" msgstr "" #: modules/gltf/gltf_node.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Translation" -msgstr "Traducciones" +msgstr "Traducción" #: modules/gltf/gltf_node.cpp -#, fuzzy msgid "Children" -msgstr "Hijos Editables" +msgstr "Hijos" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints" -msgstr "Punto" +msgstr "Articulaciones" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp msgid "Roots" @@ -17218,28 +17005,24 @@ msgid "Unique Names" msgstr "" #: modules/gltf/gltf_skeleton.cpp -#, fuzzy msgid "Godot Bone Node" -msgstr "Obtener Nodo de Escena" +msgstr "Nodo de Huesos de Godot" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Skin Root" -msgstr "Nueva RaÃz de Escena" +msgstr "RaÃz de la Skin" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints Original" -msgstr "Foco en Origen" +msgstr "Articulaciones Originales" #: modules/gltf/gltf_skin.cpp msgid "Inverse Binds" msgstr "" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Non Joints" -msgstr "Mover Unión" +msgstr "Sin Articulaciones" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Bone I" @@ -17278,28 +17061,24 @@ msgid "Json" msgstr "" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Major Version" -msgstr "Versión" +msgstr "Versión Mayor" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Minor Version" -msgstr "Versión" +msgstr "Versión Menor" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "GLB Data" -msgstr "Con Datos" +msgstr "Datos GLB" #: modules/gltf/gltf_state.cpp msgid "Use Named Skin Binds" msgstr "" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Buffer Views" -msgstr "Vista Trasera" +msgstr "Vistas del Buffer" #: modules/gltf/gltf_state.cpp msgid "Accessors" @@ -17310,15 +17089,13 @@ msgid "Scene Name" msgstr "Nombre de la Escena" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Root Nodes" -msgstr "Nombre del nodo raÃz" +msgstr "Nodos RaÃz" #: modules/gltf/gltf_state.cpp scene/2d/particles_2d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_progress.cpp -#, fuzzy msgid "Textures" -msgstr "CaracterÃsticas" +msgstr "Texturas" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" @@ -17329,70 +17106,60 @@ msgid "Cameras" msgstr "" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp -#, fuzzy msgid "Lights" -msgstr "Luz" +msgstr "Luces" #: modules/gltf/gltf_state.cpp msgid "Unique Animation Names" msgstr "Nombres Únicos de Animación" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeletons" -msgstr "Esqueleto" +msgstr "Esqueletos" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeleton To Node" -msgstr "Selecciona un Nodo" +msgstr "Esqueleto a Nodo" #: modules/gltf/gltf_state.cpp msgid "Animations" msgstr "Animaciones" #: modules/gltf/gltf_texture.cpp -#, fuzzy msgid "Src Image" -msgstr "Mostrar Huesos" +msgstr "Imagen de Origen" #: modules/gridmap/grid_map.cpp msgid "Mesh Library" msgstr "LibrerÃa de Mallas" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Physics Material" -msgstr "Fotogramas de FÃsica %" +msgstr "Material de FÃsica" #: modules/gridmap/grid_map.cpp scene/3d/visual_instance.cpp -#, fuzzy msgid "Use In Baked Light" -msgstr "Calcular Lightmaps" +msgstr "Uso en Luz Bakeada" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" msgstr "" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Octant Size" -msgstr "Vista Frontal" +msgstr "Tamaño del Octante" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center X" -msgstr "Centro" +msgstr "Centro X" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Y" -msgstr "Centro" +msgstr "Centro Y" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Z" -msgstr "Centro" +msgstr "Centro Z" #: modules/gridmap/grid_map.cpp scene/2d/collision_object_2d.cpp #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp @@ -17401,17 +17168,15 @@ msgid "Mask" msgstr "" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp -#, fuzzy msgid "Bake Navigation" -msgstr "Navegación" +msgstr "Bakear Navegación" #: modules/gridmap/grid_map.cpp scene/2d/navigation_2d.cpp #: scene/2d/navigation_agent_2d.cpp scene/2d/navigation_polygon.cpp #: scene/2d/tile_map.cpp scene/3d/navigation.cpp scene/3d/navigation_agent.cpp #: scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Navigation Layers" -msgstr "Modo de Navegación" +msgstr "Capas de Navegación" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Plane" @@ -17571,9 +17336,8 @@ msgid "Plotting lightmaps" msgstr "Trazar lightmaps" #: modules/lightmapper_cpu/register_types.cpp -#, fuzzy msgid "CPU Lightmapper" -msgstr "Calcular Lightmaps" +msgstr "CPU Lightmapper" #: modules/lightmapper_cpu/register_types.cpp msgid "Low Quality Ray Count" @@ -17607,14 +17371,12 @@ msgid "IOD" msgstr "" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Display Width" -msgstr "Mostrar Wireframe" +msgstr "Ancho de Pantalla" #: modules/mobile_vr/mobile_vr_interface.cpp -#, fuzzy msgid "Display To Lens" -msgstr "Mostrar Sin Sombreado" +msgstr "Pantalla a Lente" #: modules/mobile_vr/mobile_vr_interface.cpp msgid "Oversample" @@ -17637,9 +17399,8 @@ msgid "Build Solution" msgstr "Crear Solución" #: modules/mono/editor/csharp_project.cpp -#, fuzzy msgid "Auto Update Project" -msgstr "Proyecto Sin Nombre" +msgstr "Actualización Automática del Proyecto" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" @@ -17741,9 +17502,8 @@ msgid "Period" msgstr "" #: modules/opensimplex/open_simplex_noise.cpp -#, fuzzy msgid "Persistence" -msgstr "Perspectiva" +msgstr "Persistencia" #: modules/opensimplex/open_simplex_noise.cpp msgid "Lacunarity" @@ -17754,9 +17514,8 @@ msgid "Subject" msgstr "" #: modules/regex/regex.cpp -#, fuzzy msgid "Names" -msgstr "Nombre" +msgstr "Nombres" #: modules/regex/regex.cpp msgid "Strings" @@ -17775,32 +17534,28 @@ msgid "Discover IPv6" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Description URL" -msgstr "Descripción" +msgstr "Descripción URL" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "Service Type" -msgstr "Establecer Tipo de la Variable" +msgstr "Tipo de Servicio" #: modules/upnp/upnp_device.cpp msgid "IGD Control URL" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "IGD Service Type" -msgstr "Establecer Tipo de la Variable" +msgstr "Tipo de Servicio IGD" #: modules/upnp/upnp_device.cpp msgid "IGD Our Addr" msgstr "" #: modules/upnp/upnp_device.cpp -#, fuzzy msgid "IGD Status" -msgstr "Estado" +msgstr "Estado del IGD" #: modules/visual_script/visual_script.cpp msgid "" @@ -17841,9 +17596,8 @@ msgid "Stack overflow with stack depth:" msgstr "Desbordamiento de pila con profundidad de pila:" #: modules/visual_script/visual_script.cpp -#, fuzzy msgid "Visual Script" -msgstr "Buscar en VisualScript" +msgstr "Visual Script" #: modules/visual_script/visual_script_editor.cpp msgid "Change Signal Arguments" @@ -18173,14 +17927,12 @@ msgid "Return" msgstr "Regresar" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Return Enabled" -msgstr "Ejecutable" +msgstr "Retorno Activado" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Return Type" -msgstr "Regresar" +msgstr "Tipo de Retorno" #: modules/visual_script/visual_script_flow_control.cpp #: scene/resources/visual_shader_nodes.cpp @@ -18228,9 +17980,8 @@ msgid "in order:" msgstr "en orden:" #: modules/visual_script/visual_script_flow_control.cpp -#, fuzzy msgid "Steps" -msgstr "Paso" +msgstr "Pasos" #: modules/visual_script/visual_script_flow_control.cpp msgid "Switch" @@ -18250,9 +18001,8 @@ msgstr "¿Es %s?" #: modules/visual_script/visual_script_flow_control.cpp #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Base Script" -msgstr "Nuevo Script" +msgstr "Script Base" #: modules/visual_script/visual_script_func_nodes.cpp msgid "On %s" @@ -18264,36 +18014,31 @@ msgstr "Sobre Sà Mismo" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_yield_nodes.cpp -#, fuzzy msgid "Call Mode" -msgstr "Modo de Escalado" +msgstr "Modo de Llamada" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Basic Type" -msgstr "Tipo Base" +msgstr "Tipo Básico" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_yield_nodes.cpp -#, fuzzy msgid "Node Path" -msgstr "Copiar Ruta del Nodo" +msgstr "Ruta del Nodo" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Use Default Args" -msgstr "Restablecer Valores por Defecto" +msgstr "Usar Argumentos por Defecto" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Validate" msgstr "Validar" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "RPC Call Mode" -msgstr "Modo de Escalado" +msgstr "Modo de Llamada RPC" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Subtract %s" @@ -18332,14 +18077,12 @@ msgid "BitXor %s" msgstr "BitXor %s" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Set Mode" -msgstr "Modo de Selección" +msgstr "Modo de Ajuste" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Assign Op" -msgstr "Asignar" +msgstr "Asignar Op" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp @@ -18356,9 +18099,8 @@ msgid "Base object is not a Node!" msgstr "¡El objeto base no es un nodo!" #: modules/visual_script/visual_script_func_nodes.cpp -#, fuzzy msgid "Path does not lead to Node!" -msgstr "¡La ruta no apunta a un Nodo!" +msgstr "¡La ruta no lleva al nodo!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." @@ -18374,9 +18116,8 @@ msgstr "Ordenar Array" #: modules/visual_script/visual_script_nodes.cpp scene/resources/material.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Operator" -msgstr "Iterador" +msgstr "Operador" #: modules/visual_script/visual_script_nodes.cpp msgid "Invalid argument of type:" @@ -18391,9 +18132,8 @@ msgid "a if cond, else b" msgstr "a si cond, sino b" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Var Name" -msgstr "Nombre" +msgstr "Nombre de la Variable" #: modules/visual_script/visual_script_nodes.cpp msgid "VariableGet not found in script:" @@ -18518,9 +18258,8 @@ msgid "%s sec(s)" msgstr "%s seg(s)" #: modules/visual_script/visual_script_yield_nodes.cpp scene/main/timer.cpp -#, fuzzy msgid "Wait Time" -msgstr "Dibujar Tile" +msgstr "Tiempo de Espera" #: modules/visual_script/visual_script_yield_nodes.cpp msgid "WaitSignal" @@ -18535,18 +18274,16 @@ msgid "WaitInstanceSignal" msgstr "WaitInstanceSignal" #: modules/webrtc/webrtc_data_channel.cpp -#, fuzzy msgid "Write Mode" -msgstr "Modo de Prioridad" +msgstr "Modo de Escritura" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" msgstr "" #: modules/webrtc/webrtc_data_channel.h -#, fuzzy msgid "Max Channel In Buffer (KB)" -msgstr "Tamaño del buffer del Ãndice del polÃgono del lienzo (KB)" +msgstr "Buffer de Canal Máximo (KB)" #: modules/websocket/websocket_client.cpp msgid "Verify SSL" @@ -18557,59 +18294,52 @@ msgid "Trusted SSL Certificate" msgstr "" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Client" -msgstr "Red de Pares" +msgstr "Cliente WebSocket" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max In Buffer (KB)" -msgstr "Tamaño Máximo (KB)" +msgstr "Buffer de Entrada Máximo (KB)" #: modules/websocket/websocket_macros.h msgid "Max In Packets" msgstr "" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max Out Buffer (KB)" -msgstr "Tamaño Máximo (KB)" +msgstr "Buffer de Salida Máximo (KB)" #: modules/websocket/websocket_macros.h msgid "Max Out Packets" msgstr "" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Server" -msgstr "Red de Pares" +msgstr "Servidor WebSocket" #: modules/websocket/websocket_server.cpp msgid "Bind IP" msgstr "" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "Private Key" -msgstr "Ruta de la Clave Privada SSH" +msgstr "Clave Privada" #: modules/websocket/websocket_server.cpp platform/javascript/export/export.cpp msgid "SSL Certificate" msgstr "" #: modules/websocket/websocket_server.cpp -#, fuzzy msgid "CA Chain" -msgstr "Reestrablecer cadena IK" +msgstr "Cadena CA" #: modules/websocket/websocket_server.cpp msgid "Handshake Timeout" msgstr "Tiempo de Espera del Handshake" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Session Mode" -msgstr "Modo de Región" +msgstr "Modo de Sesión" #: modules/webxr/webxr_interface.cpp msgid "Required Features" @@ -18628,28 +18358,24 @@ msgid "Reference Space Type" msgstr "" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Visibility State" -msgstr "Cambiar Visibilidad" +msgstr "Estado de Visibilidad" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Bounds Geometry" -msgstr "Reintentar" +msgstr "LÃmites Geométricos" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "XR Standard Mapping" -msgstr "Ajuste Inteligente" +msgstr "Mapeo Estándar XR" #: platform/android/export/export.cpp msgid "Android SDK Path" msgstr "" #: platform/android/export/export.cpp -#, fuzzy msgid "Debug Keystore" -msgstr "Depurador" +msgstr "Debug Keystore" #: platform/android/export/export.cpp msgid "Debug Keystore User" @@ -18711,84 +18437,72 @@ msgid "The package must have at least one '.' separator." msgstr "El paquete debe tener al menos un '.' como separador." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Custom Build" -msgstr "CustomNode" +msgstr "Build Personalizada" #: platform/android/export/export_plugin.cpp msgid "Use Custom Build" -msgstr "" +msgstr "Usar Compilación Personalizada" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Export Format" -msgstr "Ruta de Exportación" +msgstr "Formato de Exportación" #: platform/android/export/export_plugin.cpp msgid "Min SDK" msgstr "SDK MÃnimo" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Target SDK" -msgstr "Objetivo de FPS" +msgstr "SDK de Destino" #: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp -#, fuzzy msgid "Architectures" -msgstr "Añadir una entrada de arquitectura" +msgstr "Arquitecturas" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Keystore" -msgstr "Depurador" +msgstr "Keystore" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Debug User" -msgstr "Depurador" +msgstr "Usuario de Depuración" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Debug Password" -msgstr "Contraseña" +msgstr "Contraseña de Depuración" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Release User" -msgstr "Release" +msgstr "Usuario de Release" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Release Password" -msgstr "Contraseña" +msgstr "Contraseña de Release" #: platform/android/export/export_plugin.cpp msgid "One Click Deploy" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Clear Previous Install" -msgstr "Inspeccionar Instancia Anterior" +msgstr "Limpiar Instalación Previa" #: platform/android/export/export_plugin.cpp msgid "Code" msgstr "" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Package" -msgstr "Empaquetando" +msgstr "Paquete" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp msgid "Unique Name" msgstr "Nombre Único" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Signed" -msgstr "Señal" +msgstr "Firmado" #: platform/android/export/export_plugin.cpp msgid "Classify As Game" @@ -18799,33 +18513,28 @@ msgid "Retain Data On Uninstall" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Exclude From Recents" -msgstr "Eliminar Nodos" +msgstr "Excluir de los Recientes" #: platform/android/export/export_plugin.cpp msgid "Graphics" msgstr "Gráficos" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "OpenGL Debug" -msgstr "Abrir" +msgstr "Depuración de OpenGL" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "XR Features" -msgstr "CaracterÃsticas" +msgstr "CaracterÃsticas del XR" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "XR Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo XR" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Hand Tracking" -msgstr "Empaquetando" +msgstr "Seguimiento de Manos" #: platform/android/export/export_plugin.cpp msgid "Hand Tracking Frequency" @@ -18836,71 +18545,60 @@ msgid "Passthrough" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Immersive Mode" -msgstr "Modo de Prioridad" +msgstr "Modo Inmersivo" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Small" -msgstr "Soporte" +msgstr "Soporte Pequeño" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Normal" -msgstr "Soporte" +msgstr "Soporte Normal" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Large" -msgstr "Soporte" +msgstr "Soporte Grande" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Support Xlarge" -msgstr "Soporte" +msgstr "Soporte Xlarge" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "User Data Backup" -msgstr "Interfaz de usuario" +msgstr "Backup de Datos del Usuario" #: platform/android/export/export_plugin.cpp msgid "Allow" msgstr "" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Command Line" -msgstr "Command" +msgstr "LÃnea de Comandos" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp msgid "Extra Args" msgstr "Argumentos extras" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "APK Expansion" -msgstr "Expresión" +msgstr "Expansión del APK" #: platform/android/export/export_plugin.cpp msgid "Salt" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Public Key" -msgstr "Ruta de la clave pública SSH" +msgstr "Clave Pública" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Permissions" -msgstr "Máscara de Emisión" +msgstr "Permisos" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Custom Permissions" -msgstr "Reproducir Escena Personalizada" +msgstr "Permisos Personalizados" #: platform/android/export/export_plugin.cpp msgid "Select device from the list" @@ -19029,34 +18727,33 @@ msgstr "" #: platform/android/export/export_plugin.cpp msgid "\"Use Custom Build\" must be enabled to use the plugins." -msgstr "\"Use Custom Build\" debe estar activado para usar los plugins." +msgstr "" +"\"Usar Compilación Personalizada\" debe estar activado para usar los plugins." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "\"Hand Tracking\" is only valid when \"XR Mode\" is \"Oculus Mobile VrApi\" " "or \"OpenXR\"." msgstr "" -"\"Hand Tracking\" solo es válido cuando \"Xr Mode\" es \"Oculus Mobile " -"VrApi\" u \"OpenXR\"." +"\"Seguimiento de Manos\" solo es válido cuando el \"Modo XR\" es \"Oculus " +"Mobile VrApi\" u \"OpenXR\"." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "\"Passthrough\" is only valid when \"XR Mode\" is \"OpenXR\"." -msgstr "\"Passthrough\" solo es válido cuando \"Xr Mode\" es \"OpenXR\"." +msgstr "\"Passthrough\" solo es válido cuando el \"Modo XR\" es \"OpenXR\"." #: platform/android/export/export_plugin.cpp msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled." msgstr "" -"\"Export AAB\" sólo es válido cuando \"Use Custom Build\" está activado." +"\"Exportar AAB\" solo es válido cuando \"Usar Compilación Personalizada\" " +"está activado." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "\"Min SDK\" can only be overridden when \"Use Custom Build\" is enabled." msgstr "" -"Cambiar el \"Min Sdk\" solo es válido cuando \"Use Custom Build\" está " -"activado." +"\"Min SDK\" solo puede sobrescribirse cuando está activada la opción \"Usar " +"Compilación Personalizada\"." #: platform/android/export/export_plugin.cpp msgid "\"Min SDK\" should be a valid integer, but got \"%s\" which is invalid." @@ -19069,36 +18766,36 @@ msgid "" msgstr "" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "\"Target SDK\" can only be overridden when \"Use Custom Build\" is enabled." msgstr "" -"Cambiar el \"Target Sdk\" solo es válido cuando \"Use Custom Build\" está " -"activado." +"\"SDK de Destino\" solo se puede sobrescribir cuando \"Usar Compilación " +"Personalizada\" está activado." #: platform/android/export/export_plugin.cpp msgid "" "\"Target SDK\" should be a valid integer, but got \"%s\" which is invalid." msgstr "" +"\"SDK de Destino\" deberÃa ser un entero válido, pero obtuvo \"%s\" inválido." #: platform/android/export/export_plugin.cpp msgid "" "\"Target SDK\" %d is higher than the default version %d. This may work, but " "wasn't tested and may be unstable." msgstr "" +"\"SDK de Destino\" %d es superior a la versión por defecto %d. PodrÃa " +"funcionar, pero no se ha probado y puede ser inestable." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "\"Target SDK\" version must be greater or equal to \"Min SDK\" version." msgstr "" -"La versión de \"Target Sdk\" debe ser mayor o igual que la versión de \"Min " -"Sdk\"." +"La versión \"SDK de Destino\" debe ser mayor o igual a la versión \"Min " +"SDK\"." #: platform/android/export/export_plugin.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Code Signing" -msgstr "Firma de código DMG" +msgstr "Firma del Código" #: platform/android/export/export_plugin.cpp msgid "" @@ -19328,9 +19025,8 @@ msgid "Code Sign Identity Debug" msgstr "" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Export Method Debug" -msgstr "Exportar Con Depuración" +msgstr "Exportar Método de Depuración" #: platform/iphone/export/export.cpp msgid "Provisioning Profile UUID Release" @@ -19357,39 +19053,33 @@ msgid "Identifier" msgstr "Identificador" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Signature" -msgstr "Señal" +msgstr "Firma" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Short Version" -msgstr "Versión" +msgstr "Versión Corta" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Copyright" -msgstr "Superior Derecha" +msgstr "Copyright" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Capabilities" -msgstr "Capitalizar Propiedades" +msgstr "Capacidades" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Access Wi-Fi" -msgstr "Acceso" +msgstr "Acceso Wi-Fi" #: platform/iphone/export/export.cpp msgid "Push Notifications" msgstr "Notificaciones Push" #: platform/iphone/export/export.cpp -#, fuzzy msgid "User Data" -msgstr "Interfaz de usuario" +msgstr "Datos de Usuario" #: platform/iphone/export/export.cpp msgid "Accessible From Files App" @@ -19400,24 +19090,20 @@ msgid "Accessible From iTunes Sharing" msgstr "" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Privacy" -msgstr "Ruta de la Clave Privada SSH" +msgstr "Privacidad" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Camera Usage Description" -msgstr "Descripción" +msgstr "Descripción del Uso de la Cámara" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Microphone Usage Description" -msgstr "Descripciones de Propiedades" +msgstr "Descripción del Uso del Micrófono" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Photolibrary Usage Description" -msgstr "Descripciones de Propiedades" +msgstr "Descripción del Uso de la FotolibrerÃa" #: platform/iphone/export/export.cpp msgid "iPhone 120 X 120" @@ -19460,40 +19146,33 @@ msgid "Use Launch Screen Storyboard" msgstr "" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Image Scale Mode" -msgstr "Modo de Escalado" +msgstr "Modo de Escalado de Imagen" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom Image @2x" -msgstr "CustomNode" +msgstr "Imagen Personalizada @2x" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom Image @3x" -msgstr "CustomNode" +msgstr "Imagen Personalizada @3x" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Use Custom BG Color" -msgstr "CustomNode" +msgstr "Usar Color de Fondo Personalizado" #: platform/iphone/export/export.cpp -#, fuzzy msgid "Custom BG Color" -msgstr "CustomNode" +msgstr "Color de Fondo Personalizado" #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp #: platform/osx/export/export.cpp -#, fuzzy msgid "Prepare Templates" -msgstr "Administrar Plantillas" +msgstr "Preparar Plantillas" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Export template not found." -msgstr "Plantilla release personalizada no encontrada." +msgstr "No se ha encontrado la plantilla de exportación." #: platform/iphone/export/export.cpp msgid "App Store Team ID not specified - cannot configure the project." @@ -19529,9 +19208,8 @@ msgid "Could not write file: \"%s\"." msgstr "No se pudo escribir el archivo: \"%s\"." #: platform/javascript/export/export.cpp platform/osx/export/export.cpp -#, fuzzy msgid "Icon Creation" -msgstr "Asignar Margen" +msgstr "Creación de Iconos" #: platform/javascript/export/export.cpp msgid "Could not read file: \"%s\"." @@ -19546,14 +19224,12 @@ msgid "Variant" msgstr "Variante" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Export Type" -msgstr "Exportar" +msgstr "Tipo de Exportación" #: platform/javascript/export/export.cpp -#, fuzzy msgid "VRAM Texture Compression" -msgstr "Expresión" +msgstr "Compresión de Texturas en la VRAM" #: platform/javascript/export/export.cpp msgid "For Desktop" @@ -19568,14 +19244,12 @@ msgid "HTML" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Export Icon" -msgstr "Expandir Todo" +msgstr "Icono de Exportación" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Custom HTML Shell" -msgstr "CustomNode" +msgstr "HTML Shell Personalizado" #: platform/javascript/export/export.cpp msgid "Head Include" @@ -19590,9 +19264,8 @@ msgid "Focus Canvas On Start" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Experimental Virtual Keyboard" -msgstr "Filtrar señales" +msgstr "Teclado Virtual Experimental" #: platform/javascript/export/export.cpp msgid "Progressive Web App" @@ -19639,9 +19312,8 @@ msgid "HTTP Port" msgstr "" #: platform/javascript/export/export.cpp -#, fuzzy msgid "Use SSL" -msgstr "Usar Snap" +msgstr "Usar SSL" #: platform/javascript/export/export.cpp msgid "SSL Key" @@ -19728,33 +19400,28 @@ msgid "High Res" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Location Usage Description" -msgstr "Descripción" +msgstr "Ubicación de la Descripción de Uso" #: platform/osx/export/export.cpp msgid "Address Book Usage Description" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Calendar Usage Description" -msgstr "Descripción" +msgstr "Descripción del Uso del Calendario" #: platform/osx/export/export.cpp -#, fuzzy msgid "Photos Library Usage Description" -msgstr "Descripciones de Propiedades" +msgstr "Descripción de Uso de la LibrerÃa de Fotos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Desktop Folder Usage Description" -msgstr "Descripciones de Métodos" +msgstr "Descripción de Uso de la Carpeta de Escritorio" #: platform/osx/export/export.cpp -#, fuzzy msgid "Documents Folder Usage Description" -msgstr "Descripciones de Métodos" +msgstr "Descripción de Uso de la Carpeta de Documentos" #: platform/osx/export/export.cpp msgid "Downloads Folder Usage Description" @@ -19769,39 +19436,33 @@ msgid "Removable Volumes Usage Description" msgstr "" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Codesign" -msgstr "Firma de código DMG" +msgstr "Codesign" #: platform/osx/export/export.cpp platform/uwp/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Identity" -msgstr "Indentar a la Izquierda" +msgstr "Identidad" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Timestamp" -msgstr "Tiempo" +msgstr "Marca de Tiempo" #: platform/osx/export/export.cpp msgid "Hardened Runtime" -msgstr "" +msgstr "Hardened Runtime" #: platform/osx/export/export.cpp -#, fuzzy msgid "Replace Existing Signature" -msgstr "Reemplazar en Archivos" +msgstr "Reemplazar Firma Existente" #: platform/osx/export/export.cpp -#, fuzzy msgid "Entitlements" -msgstr "Gizmos" +msgstr "Derechos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Custom File" -msgstr "CustomNode" +msgstr "Archivo Personalizado" #: platform/osx/export/export.cpp msgid "Allow JIT Code Execution" @@ -19816,14 +19477,12 @@ msgid "Allow Dyld Environment Variables" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Disable Library Validation" -msgstr "Botón Desactivado" +msgstr "Desactivar Validación de Bibliotecas" #: platform/osx/export/export.cpp -#, fuzzy msgid "Audio Input" -msgstr "Añadir Entrada" +msgstr "Entrada de Audio" #: platform/osx/export/export.cpp msgid "Address Book" @@ -19834,81 +19493,68 @@ msgid "Calendars" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Photos Library" -msgstr "Exportar LibrerÃa" +msgstr "LibrerÃa de Fotos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Apple Events" -msgstr "Añadir Evento" +msgstr "Eventos de Apple" #: platform/osx/export/export.cpp -#, fuzzy msgid "Debugging" -msgstr "Depurar" +msgstr "Depuración" #: platform/osx/export/export.cpp msgid "App Sandbox" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Network Server" -msgstr "Red de Pares" +msgstr "Servidor de Red" #: platform/osx/export/export.cpp -#, fuzzy msgid "Network Client" -msgstr "Red de Pares" +msgstr "Cliente de Red" #: platform/osx/export/export.cpp -#, fuzzy msgid "Device USB" -msgstr "Dispositivo" +msgstr "Dispositivo USB" #: platform/osx/export/export.cpp msgid "Device Bluetooth" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Downloads" -msgstr "Descargar" +msgstr "Descargas de Archivos" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Pictures" -msgstr "CaracterÃsticas" +msgstr "Archivos de Imágenes" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Music" -msgstr "Archivo" +msgstr "Archivos de Música" #: platform/osx/export/export.cpp -#, fuzzy msgid "Files Movies" -msgstr "Filtrar tiles" +msgstr "Archivos de VÃdeo" #: platform/osx/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Custom Options" -msgstr "Opciones de Bus" +msgstr "Opciones Personalizadas" #: platform/osx/export/export.cpp -#, fuzzy msgid "Notarization" -msgstr "Traducciones" +msgstr "Notarización" #: platform/osx/export/export.cpp msgid "Apple ID Name" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "Apple ID Password" -msgstr "Contraseña" +msgstr "Contraseña del ID de Apple" #: platform/osx/export/export.cpp msgid "Apple Team ID" @@ -19931,13 +19577,12 @@ msgid "Notarization request UUID: \"%s\"" msgstr "" #: platform/osx/export/export.cpp -#, fuzzy msgid "" "The notarization process generally takes less than an hour. When the process " "is completed, you'll receive an email." msgstr "" -"Nota: El proceso de notarización generalmente toma menos de una hora. Cuando " -"se complete el proceso, recibirá un correo electrónico." +"El proceso de notarización suele durar menos de una hora. Cuando el proceso " +"haya finalizado, recibirás un correo electrónico." #: platform/osx/export/export.cpp msgid "" @@ -19956,17 +19601,15 @@ msgstr "" "notarial a la aplicación exportada (opcional):" #: platform/osx/export/export.cpp -#, fuzzy msgid "Timestamping is not compatible with ad-hoc signature, and was disabled!" msgstr "" -"El sellado de tiempo no es compatible con la firma ad-hoc, y se desactivará!" +"¡La marca de tiempo no es compatible con la firma ad-hoc, y fue desactivada!" #: platform/osx/export/export.cpp -#, fuzzy msgid "" "Hardened Runtime is not compatible with ad-hoc signature, and was disabled!" msgstr "" -"Hardened Runtime no es compatible con la firma ad-hoc, y se desactivará!" +"¡Hardened Runtime no es compatible con la firma ad-hoc, y fue desactivado!" #: platform/osx/export/export.cpp msgid "Built-in CodeSign failed with error \"%s\"." @@ -19991,16 +19634,14 @@ msgid "Cannot sign file %s." msgstr "No se puede firmar el archivo %s." #: platform/osx/export/export.cpp -#, fuzzy msgid "Relative symlinks are not supported, exported \"%s\" might be broken!" msgstr "" -"Los enlaces simbólicos relativos no son compatibles con este sistema " -"operativo, ¡el proyecto exportado podrÃa estar dañado!" +"Los enlaces simbólicos relativos no son compatibles, ¡los \"%s\" exportados " +"podrÃan estar rotos!" #: platform/osx/export/export.cpp -#, fuzzy msgid "DMG Creation" -msgstr "Direcciones" +msgstr "Creación de DMG" #: platform/osx/export/export.cpp msgid "Could not start hdiutil executable." @@ -20036,13 +19677,12 @@ msgstr "" "operativo, ¡el proyecto exportado podrÃa estar dañado!" #: platform/osx/export/export.cpp -#, fuzzy msgid "" "Requested template binary \"%s\" not found. It might be missing from your " "template archive." msgstr "" -"Plantilla binaria solicitada '%s' no encontrada. Es posible que falte en el " -"archivo de plantillas." +"No se ha encontrado la plantilla binaria \"%s\" solicitada. Es posible que " +"no se encuentre en el archivo de plantillas." #: platform/osx/export/export.cpp msgid "Making PKG" @@ -20085,9 +19725,8 @@ msgid "Sending archive for notarization" msgstr "Enviando archivo para notarización" #: platform/osx/export/export.cpp -#, fuzzy msgid "ZIP Creation" -msgstr "Proyecto" +msgstr "Creación de ZIP" #: platform/osx/export/export.cpp msgid "Could not open file to read from path \"%s\"." @@ -20126,9 +19765,7 @@ msgstr "Notarización: Se requiere la firma del código para la notarización." #: platform/osx/export/export.cpp msgid "Notarization: Hardened runtime is required for notarization." -msgstr "" -"Notarización: se requiere tiempo de ejecución endurecido para la " -"certificación notarial." +msgstr "Notarización: Se requiere Hardened runtime para la notarización." #: platform/osx/export/export.cpp msgid "Notarization: Timestamp runtime is required for notarization." @@ -20165,7 +19802,7 @@ msgid "" "Hardened Runtime is not compatible with ad-hoc signature, and will be " "disabled!" msgstr "" -"Hardened Runtime no es compatible con la firma ad-hoc, y se desactivará!" +"¡Hardened Runtime no es compatible con la firma ad-hoc, y se desactivará!" #: platform/osx/export/export.cpp msgid "" @@ -20237,14 +19874,12 @@ msgid "Force Builtin Codesign" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Architecture" -msgstr "Añadir una entrada de arquitectura" +msgstr "Arquitectura" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Display Name" -msgstr "Escala de Visualización" +msgstr "Nombre a Mostrar" #: platform/uwp/export/export.cpp msgid "Short Name" @@ -20263,24 +19898,20 @@ msgid "Product GUID" msgstr "GUID del producto" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Publisher GUID" -msgstr "Limpiar GuÃas" +msgstr "GUID del Editor" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Signing" -msgstr "Señal" +msgstr "Firmando" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Certificate" -msgstr "Certificados" +msgstr "Certificado" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Algorithm" -msgstr "Depurador" +msgstr "Algoritmo" #: platform/uwp/export/export.cpp msgid "Major" @@ -20291,23 +19922,20 @@ msgid "Minor" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Build" -msgstr "Modo de Regla" +msgstr "Compilación" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Revision" -msgstr "Expresión" +msgstr "Revisión" #: platform/uwp/export/export.cpp msgid "Landscape" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Portrait" -msgstr "Voltear Portales" +msgstr "Retrato" #: platform/uwp/export/export.cpp msgid "Landscape Flipped" @@ -20318,9 +19946,8 @@ msgid "Portrait Flipped" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Store Logo" -msgstr "Modo de Escalado" +msgstr "Logo de Tienda" #: platform/uwp/export/export.cpp msgid "Square 44 X 44 Logo" @@ -20347,9 +19974,8 @@ msgid "Splash Screen" msgstr "Pantalla de Bienvenida" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Tiles" -msgstr "Archivo" +msgstr "Tiles" #: platform/uwp/export/export.cpp msgid "Show Name On Square 150 X 150" @@ -20433,18 +20059,16 @@ msgid "UWP" msgstr "" #: platform/uwp/export/export.cpp platform/windows/export/export.cpp -#, fuzzy msgid "Signtool" -msgstr "Señal" +msgstr "Signtool" #: platform/uwp/export/export.cpp msgid "Debug Certificate" msgstr "" #: platform/uwp/export/export.cpp -#, fuzzy msgid "Debug Algorithm" -msgstr "Depurador" +msgstr "Algoritmo de Depuración" #: platform/windows/export/export.cpp msgid "Failed to rename temporary file \"%s\"." @@ -20459,19 +20083,16 @@ msgid "Timestamp Server URL" msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Digest Algorithm" -msgstr "Depurador" +msgstr "Algoritmo de Compilación" #: platform/windows/export/export.cpp -#, fuzzy msgid "Modify Resources" -msgstr "Copiar Recurso" +msgstr "Modificar Recursos" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Version" -msgstr "Versión" +msgstr "Versión del Archivo" #: platform/windows/export/export.cpp msgid "Product Version" @@ -20486,38 +20107,32 @@ msgid "Product Name" msgstr "Nombre del Producto" #: platform/windows/export/export.cpp -#, fuzzy msgid "File Description" -msgstr "Descripción" +msgstr "Descripción del Archivo" #: platform/windows/export/export.cpp msgid "Trademarks" msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Resources Modification" -msgstr "Notificaciones Push" +msgstr "Modificación de los Recursos" #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find rcedit executable at \"%s\"." -msgstr "No se pudo encontrar la keystore, no se puedo exportar." +msgstr "No se pudo encontrar el ejecutable rcedit en \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find wine executable at \"%s\"." -msgstr "No se pudo encontrar la keystore, no se puedo exportar." +msgstr "No se pudo encontrar el ejecutable de wine en \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "" "Could not start rcedit executable, configure rcedit path in the Editor " "Settings (Export > Windows > Rcedit)." msgstr "" -"La herramienta rcedit debe configurarse en la configuración del editor " -"(Exportar > Windows > Rcedit) para cambiar los datos de información del " -"Ãcono o la aplicación." +"No se ha podido iniciar el ejecutable rcedit, configura la ruta de rcedit en " +"la configuración del editor (Exportar > Windows > Rcedit)." #: platform/windows/export/export.cpp msgid "" @@ -20526,33 +20141,28 @@ msgid "" msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find signtool executable at \"%s\"." -msgstr "No se pudo encontrar la keystore, no se puedo exportar." +msgstr "No se pudo encontrar el ejecutable de signtool en \"%s\"." #: platform/windows/export/export.cpp -#, fuzzy msgid "Could not find osslsigncode executable at \"%s\"." -msgstr "No se pudo encontrar la keystore, no se puedo exportar." +msgstr "No se pudo encontrar el ejecutable osslsigncode en \"%s\"." #: platform/windows/export/export.cpp msgid "Invalid identity type." msgstr "Tipo de identificador inválido." #: platform/windows/export/export.cpp -#, fuzzy msgid "Invalid timestamp server." -msgstr "Nombre inválido." +msgstr "Servidor de marcas de tiempo inválido." #: platform/windows/export/export.cpp -#, fuzzy msgid "" "Could not start signtool executable, configure signtool path in the Editor " "Settings (Export > Windows > Signtool)." msgstr "" -"La herramienta rcedit debe configurarse en la configuración del editor " -"(Exportar > Windows > Rcedit) para cambiar los datos de información del " -"Ãcono o la aplicación." +"No se ha podido iniciar el ejecutable de signtool, configura la ruta de " +"signtool en la configuración del editor (Exportar > Windows > Signtool)." #: platform/windows/export/export.cpp msgid "" @@ -20590,9 +20200,8 @@ msgid "Windows executables cannot be >= 4 GiB." msgstr "" #: platform/windows/export/export.cpp platform/x11/export/export.cpp -#, fuzzy msgid "Failed to open executable file \"%s\"." -msgstr "Archivo ejecutable no válido." +msgstr "Fallo al abrir el archivo ejecutable \"%s\"." #: platform/windows/export/export.cpp platform/x11/export/export.cpp msgid "Executable file header corrupted." @@ -20603,9 +20212,8 @@ msgid "Executable \"pck\" section not found." msgstr "" #: platform/windows/export/export.cpp -#, fuzzy msgid "Windows" -msgstr "Nueva Ventana" +msgstr "Windows" #: platform/windows/export/export.cpp msgid "Rcedit" @@ -20625,9 +20233,8 @@ msgstr "" #: scene/2d/animated_sprite.cpp scene/3d/sprite_3d.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Frames" -msgstr "Fotograma %" +msgstr "Fotogramas" #: scene/2d/animated_sprite.cpp msgid "" @@ -20639,21 +20246,18 @@ msgstr "" #: scene/2d/animated_sprite.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Speed Scale" -msgstr "Escala" +msgstr "Escala de Velocidad" #: scene/2d/animated_sprite.cpp scene/2d/audio_stream_player_2d.cpp #: scene/3d/audio_stream_player_3d.cpp scene/3d/sprite_3d.cpp #: scene/audio/audio_stream_player.cpp -#, fuzzy msgid "Playing" msgstr "Reproducir" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Centered" -msgstr "Centro" +msgstr "Centrado" #: scene/2d/animated_sprite.cpp scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_rect.cpp @@ -20666,39 +20270,32 @@ msgid "Flip V" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Monitoring" -msgstr "Monitor" +msgstr "Monitorización" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Monitorable" -msgstr "Monitor" +msgstr "Monitorizable" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Physics Overrides" -msgstr "Anulaciones" +msgstr "Anulaciones de FÃsicas" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Space Override" -msgstr "Anulaciones" +msgstr "Anulación de Espacio" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Point" -msgstr "Generar puntos" +msgstr "Punto de Gravedad" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Distance Scale" -msgstr "WaitInstanceSignal" +msgstr "Escala de Distancia de la Gravedad" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Gravity Vec" -msgstr "Vista Previa Por Defecto" +msgstr "Velocidad de la Gravedad" #: scene/2d/area_2d.cpp scene/2d/cpu_particles_2d.cpp scene/3d/area.cpp #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp @@ -20706,42 +20303,36 @@ msgid "Gravity" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Linear Damp" -msgstr "Lineal" +msgstr "Amortiguación Lineal" #: scene/2d/area_2d.cpp scene/3d/area.cpp msgid "Angular Damp" msgstr "" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Audio Bus" -msgstr "Añadir Bus de Audio" +msgstr "Bus de Audio" #: scene/2d/area_2d.cpp scene/3d/area.cpp -#, fuzzy msgid "Override" -msgstr "Anulaciones" +msgstr "Anular" #: scene/2d/audio_stream_player_2d.cpp scene/audio/audio_stream_player.cpp #: scene/gui/video_player.cpp servers/audio/effects/audio_effect_amplify.cpp -#, fuzzy msgid "Volume dB" -msgstr "Volumen" +msgstr "Volumen dB" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp #: servers/audio/effects/audio_effect_pitch_shift.cpp -#, fuzzy msgid "Pitch Scale" -msgstr "Escala" +msgstr "Escala de Tono" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp -#, fuzzy msgid "Autoplay" -msgstr "Act./Desact. Reproducción Automática" +msgstr "Reproducción Automática" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp @@ -20756,29 +20347,25 @@ msgid "Max Distance" msgstr "Distancia Maxima" #: scene/2d/audio_stream_player_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Attenuation" -msgstr "Animación" +msgstr "Atenuación" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp -#, fuzzy msgid "Bus" -msgstr "Añadir Bus" +msgstr "Bus" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp msgid "Area Mask" msgstr "" #: scene/2d/back_buffer_copy.cpp -#, fuzzy msgid "Copy Mode" -msgstr "Copiar Nodos" +msgstr "Modo de Copia" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Anchor Mode" -msgstr "Modo de Icono" +msgstr "Modo de Anclaje" #: scene/2d/camera_2d.cpp msgid "Rotating" @@ -20790,83 +20377,70 @@ msgid "Current" msgstr "Actual" #: scene/2d/camera_2d.cpp scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom" -msgstr "Acercar Zoom" +msgstr "Zoom" #: scene/2d/camera_2d.cpp scene/main/canvas_layer.cpp -#, fuzzy msgid "Custom Viewport" -msgstr "1 Viewport" +msgstr "Vista Personalizada" #: scene/2d/camera_2d.cpp scene/3d/camera.cpp scene/3d/interpolated_camera.cpp #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp #: scene/animation/animation_tree_player.cpp scene/main/timer.cpp -#, fuzzy msgid "Process Mode" -msgstr "Modo de Movimiento" +msgstr "Modo de Proceso" #: scene/2d/camera_2d.cpp msgid "Limit" -msgstr "" +msgstr "Limite" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Left" -msgstr "UI Izquierda" +msgstr "Izquierda" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp -#, fuzzy msgid "Right" -msgstr "Luz" +msgstr "Derecha" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/dynamic_font.cpp scene/resources/style_box.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Bottom" -msgstr "Inferior Izquierda" +msgstr "Inferior" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Smoothed" msgstr "Suavizado" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Draw Margin" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Drag Margin H Enabled" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre H Activado" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Drag Margin V Enabled" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre V Activado" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Smoothing" -msgstr "Suavizado" +msgstr "Suavizar" #: scene/2d/camera_2d.cpp msgid "H" msgstr "" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "V" -msgstr "UV" +msgstr "V" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Drag Margin" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre" #: scene/2d/camera_2d.cpp msgid "Draw Screen" @@ -20877,25 +20451,21 @@ msgid "Draw Limits" msgstr "LÃmites de Dibujo" #: scene/2d/camera_2d.cpp -#, fuzzy msgid "Draw Drag Margin" -msgstr "Asignar Margen" +msgstr "Margen de Arrastre del Trazado" #: scene/2d/canvas_item.cpp scene/resources/environment.cpp #: scene/resources/material.cpp -#, fuzzy msgid "Blend Mode" -msgstr "Nodo Blend2" +msgstr "Modo de Fusión" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Light Mode" -msgstr "Ancho Derecha" +msgstr "Modo de Iluminación" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Particles Animation" -msgstr "PartÃculas" +msgstr "Animación de PartÃculas" #: scene/2d/canvas_item.cpp msgid "Particles Anim H Frames" @@ -20906,40 +20476,34 @@ msgid "Particles Anim V Frames" msgstr "" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Particles Anim Loop" -msgstr "PartÃculas" +msgstr "Bucle de Animación de PartÃculas" #: scene/2d/canvas_item.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Visibility" -msgstr "Cambiar Visibilidad" +msgstr "Visibilidad" #: scene/2d/canvas_item.cpp scene/3d/spatial.cpp scene/gui/progress_bar.cpp #: scene/gui/rich_text_effect.cpp scene/main/canvas_layer.cpp -#, fuzzy msgid "Visible" -msgstr "Cambiar Visibilidad" +msgstr "Visible" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Self Modulate" -msgstr "Rellenar" +msgstr "Modulación Automática" #: scene/2d/canvas_item.cpp msgid "Show Behind Parent" msgstr "" #: scene/2d/canvas_item.cpp -#, fuzzy msgid "Show On Top" -msgstr "Mostrar Origen" +msgstr "Mostrar Arriba" #: scene/2d/canvas_item.cpp scene/2d/light_occluder_2d.cpp #: scene/2d/tile_map.cpp -#, fuzzy msgid "Light Mask" -msgstr "Luz" +msgstr "Máscara de Luz" #: scene/2d/canvas_item.cpp msgid "Use Parent Material" @@ -20966,9 +20530,8 @@ msgstr "" "CollisionPolygon2D para definir su forma." #: scene/2d/collision_object_2d.cpp -#, fuzzy msgid "Pickable" -msgstr "Elegir Tile" +msgstr "Seleccionable" #: scene/2d/collision_polygon_2d.cpp msgid "" @@ -21001,29 +20564,27 @@ msgstr "" msgid "" "The One Way Collision property will be ignored when the parent is an Area2D." msgstr "" +"La propiedad Colisión en Una Dirección será ignorada cuando el padre sea un " +"Area2D." #: scene/2d/collision_polygon_2d.cpp -#, fuzzy msgid "Build Mode" -msgstr "Modo de Regla" +msgstr "Modo de Compilación" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp #: scene/3d/collision_polygon.cpp scene/3d/collision_shape.cpp #: scene/animation/animation_node_state_machine.cpp scene/gui/base_button.cpp #: scene/gui/texture_button.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Disabled" -msgstr "Desactivar Elemento" +msgstr "Desactivado" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp -#, fuzzy msgid "One Way Collision" -msgstr "Crear PolÃgono de Colisión" +msgstr "Colisión en Una Dirección" #: scene/2d/collision_polygon_2d.cpp scene/2d/collision_shape_2d.cpp -#, fuzzy msgid "One Way Collision Margin" -msgstr "Crear PolÃgono de Colisión" +msgstr "Margen de Colisión en Una Dirección" #: scene/2d/collision_shape_2d.cpp msgid "" @@ -21072,15 +20633,13 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp scene/main/timer.cpp -#, fuzzy msgid "One Shot" -msgstr "Nodo OneShot" +msgstr "Un Disparo" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Preprocess" -msgstr "Post procesado" +msgstr "Preproceso" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21099,9 +20658,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Fixed FPS" -msgstr "Ver FPS" +msgstr "FPS Fijos" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21115,9 +20673,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp -#, fuzzy msgid "Local Coords" -msgstr "Proyectos Locales" +msgstr "Coordenadas Locales" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21126,9 +20683,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Emission Shape" -msgstr "Máscara de Emisión" +msgstr "Forma de la Emisión" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21136,26 +20692,22 @@ msgid "Sphere Radius" msgstr "Radio de la Esfera" #: scene/2d/cpu_particles_2d.cpp -#, fuzzy msgid "Rect Extents" -msgstr "Gizmos" +msgstr "Extender Completo" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp -#, fuzzy msgid "Normals" -msgstr "Formato" +msgstr "Normales" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Align Y" -msgstr "Asignar" +msgstr "Alineación Y" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Direction" -msgstr "Direcciones" +msgstr "Dirección" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21165,15 +20717,13 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Initial Velocity" -msgstr "Inicializar" +msgstr "Velocidad Inicial" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity Random" -msgstr "Velocidad" +msgstr "Velocidad Aleatoria" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp @@ -21183,27 +20733,23 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Velocity Curve" -msgstr "Velocidad" +msgstr "Curva de Velocidad" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Orbit Velocity" -msgstr "Vista de Órbita Derecha" +msgstr "Velocidad de la Órbita" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Linear Accel" -msgstr "Lineal" +msgstr "Aceleración Lineal" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Accel" -msgstr "Acceso" +msgstr "Aceleración" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21212,9 +20758,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Accel Curve" -msgstr "Partir Curva" +msgstr "Curva de Aceleración" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21241,9 +20786,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Damping Curve" -msgstr "Partir Curva" +msgstr "Curva de Amortiguación" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/light.cpp #: scene/resources/particles_material.cpp @@ -21257,9 +20801,8 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Angle Curve" -msgstr "Cerrar Curva" +msgstr "Curva de Ãngulo" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp msgid "Scale Amount" @@ -21270,15 +20813,13 @@ msgid "Scale Amount Random" msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp -#, fuzzy msgid "Scale Amount Curve" -msgstr "Escalar Desde Cursor" +msgstr "Curva de Cantidad de Escala" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Color Ramp" -msgstr "Colores" +msgstr "Rampa de Color" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21307,15 +20848,13 @@ msgstr "Curva de Variación" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed Random" -msgstr "Escala" +msgstr "Velocidad Aleatoria" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Speed Curve" -msgstr "Partir Curva" +msgstr "Curva de Velocidad" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21324,9 +20863,8 @@ msgstr "Desplazamiento Aleatorio" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp -#, fuzzy msgid "Offset Curve" -msgstr "Cerrar Curva" +msgstr "Curva de Desplazamiento" #: scene/2d/joints_2d.cpp msgid "Node A and Node B must be PhysicsBody2Ds" @@ -21349,14 +20887,12 @@ msgid "Node A and Node B must be different PhysicsBody2Ds" msgstr "El Nodo A y el Nodo B deben ser diferentes PhysicsBody2D" #: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Node A" -msgstr "Nodos" +msgstr "Nodo A" #: scene/2d/joints_2d.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Node B" -msgstr "Nodos" +msgstr "Nodo B" #: scene/2d/joints_2d.cpp scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/light.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp @@ -21365,9 +20901,8 @@ msgid "Bias" msgstr "" #: scene/2d/joints_2d.cpp -#, fuzzy msgid "Disable Collision" -msgstr "Botón Desactivado" +msgstr "Desactivar Colisión" #: scene/2d/joints_2d.cpp scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Softness" @@ -21379,9 +20914,8 @@ msgid "Length" msgstr "" #: scene/2d/joints_2d.cpp -#, fuzzy msgid "Initial Offset" -msgstr "Inicializar" +msgstr "Desplazamiento Inicial" #: scene/2d/joints_2d.cpp scene/3d/vehicle_body.cpp msgid "Rest Length" @@ -21400,14 +20934,12 @@ msgstr "" "Texture\"." #: scene/2d/light_2d.cpp scene/3d/light.cpp scene/gui/reference_rect.cpp -#, fuzzy msgid "Editor Only" -msgstr "Editor" +msgstr "Sólo para el Editor" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Texture Scale" -msgstr "Región de Textura" +msgstr "Escala de Textura" #: scene/2d/light_2d.cpp scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/light.cpp scene/resources/environment.cpp @@ -21424,48 +20956,40 @@ msgid "Z Max" msgstr "" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Layer Min" -msgstr "Cambiar Tamaño de Cámara" +msgstr "Capa MÃnima" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Layer Max" -msgstr "Capa" +msgstr "Capa Máxima" #: scene/2d/light_2d.cpp msgid "Item Cull Mask" msgstr "" #: scene/2d/light_2d.cpp scene/3d/light.cpp scene/resources/style_box.cpp -#, fuzzy msgid "Shadow" -msgstr "Shader" +msgstr "Sombra" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Buffer Size" -msgstr "Vista Trasera" +msgstr "Tamaño del Buffer" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Gradient Length" -msgstr "Degradado Editado" +msgstr "Longitud del Gradiente" #: scene/2d/light_2d.cpp -#, fuzzy msgid "Filter Smooth" -msgstr "Filtrar métodos" +msgstr "Filtro Suavizado" #: scene/2d/light_occluder_2d.cpp -#, fuzzy msgid "Closed" -msgstr "Cerrar" +msgstr "Cerrado" #: scene/2d/light_occluder_2d.cpp scene/resources/material.cpp -#, fuzzy msgid "Cull Mode" -msgstr "Modo de Regla" +msgstr "Modo de Sacrificio" #: scene/2d/light_occluder_2d.cpp msgid "" @@ -21481,47 +21005,40 @@ msgstr "" "polÃgono." #: scene/2d/line_2d.cpp -#, fuzzy msgid "Width Curve" -msgstr "Partir Curva" +msgstr "Curva de Ancho" #: scene/2d/line_2d.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Default Color" -msgstr "Por defecto" +msgstr "Color por Defecto" #: scene/2d/line_2d.cpp scene/resources/texture.cpp msgid "Fill" -msgstr "" +msgstr "Rellenar" #: scene/2d/line_2d.cpp scene/resources/texture.cpp -#, fuzzy msgid "Gradient" -msgstr "Degradado Editado" +msgstr "Gradiente" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Texture Mode" -msgstr "Región de Textura" +msgstr "Modo de Textura" #: scene/2d/line_2d.cpp msgid "Capping" -msgstr "" +msgstr "Tapado" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Joint Mode" -msgstr "Modo de Icono" +msgstr "Modo de Unión" #: scene/2d/line_2d.cpp -#, fuzzy msgid "Begin Cap Mode" -msgstr "Modo de Región" +msgstr "Iniciar Modo Cap" #: scene/2d/line_2d.cpp -#, fuzzy msgid "End Cap Mode" -msgstr "Modo de Ajuste:" +msgstr "Modo Tapón" #: scene/2d/line_2d.cpp scene/2d/polygon_2d.cpp scene/resources/style_box.cpp msgid "Border" @@ -21537,14 +21054,12 @@ msgstr "" #: scene/2d/line_2d.cpp scene/2d/polygon_2d.cpp #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Antialiased" -msgstr "Inicializar" +msgstr "Suavizado Espacial" #: scene/2d/multimesh_instance_2d.cpp scene/3d/multimesh_instance.cpp -#, fuzzy msgid "Multimesh" -msgstr "Multiplicar %s" +msgstr "Multimesh" #: scene/2d/navigation_2d.cpp scene/3d/baked_lightmap.cpp #: scene/3d/navigation.cpp scene/animation/root_motion_view.cpp @@ -21564,60 +21079,54 @@ msgid "" msgstr "" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Pathfinding" -msgstr "Vinculación" +msgstr "Pathfinding" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Path Desired Distance" -msgstr "Distancia de la Ruta U" +msgstr "Ruta Distancia Deseada" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Target Desired Distance" -msgstr "" +msgstr "Distancia Deseada del Objetivo" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Path Max Distance" -msgstr "Distancia Máxima de Ruta" +msgstr "Distancia Máxima de la Ruta" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Avoidance" -msgstr "Avanzado" +msgstr "Evasión" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Avoidance Enabled" -msgstr "Activar" +msgstr "Evasión Activada" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Neighbor Dist" -msgstr "" +msgstr "Dist. de Vecinos" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Max Neighbors" -msgstr "" +msgstr "Máximo de Vecinos" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp -#, fuzzy msgid "Time Horizon" -msgstr "Voltear Horizontalmente" +msgstr "Horizonte del Tiempo" #: scene/2d/navigation_agent_2d.cpp scene/3d/navigation_agent.cpp msgid "Max Speed" msgstr "Velocidad Máxima" #: scene/2d/navigation_agent_2d.cpp -#, fuzzy msgid "" "The NavigationAgent2D can be used only under a Node2D inheriting parent node." -msgstr "El NavigationAgent2D sólo puede utilizarse bajo un nodo Node2D." +msgstr "" +"El NavigationAgent2D sólo puede utilizarse bajo un nodo padre hijo de Node2D." #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_obstacle.cpp -#, fuzzy msgid "Estimate Radius" -msgstr "Cambiar Radio Externo de Torus" +msgstr "Estimación del Radio" #: scene/2d/navigation_obstacle_2d.cpp msgid "" @@ -21632,22 +21141,20 @@ msgid "" "A NavigationPolygon resource must be set or created for this node to work. " "Please set a property or draw a polygon." msgstr "" -"Se debe crear o asignar un recurso NavigationPolygon a este nodo para que " -"funcione. Por favor, establece la propiedad o dibuja un polÃgono." +"Un recurso NavigationPolygon debe ser establecido o creado para que este " +"nodo funcione. Por favor, establece una propiedad o dibuja un polÃgono." #: scene/2d/navigation_polygon.cpp msgid "Navpoly" -msgstr "" +msgstr "Navpoly" #: scene/2d/navigation_polygon.cpp scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Enter Cost" -msgstr "Centro Inferior" +msgstr "Introduce Costo" #: scene/2d/navigation_polygon.cpp scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Travel Cost" -msgstr "Viaje" +msgstr "Costo del Viaje" #: scene/2d/node_2d.cpp scene/2d/polygon_2d.cpp scene/3d/spatial.cpp #: scene/main/canvas_layer.cpp @@ -21655,9 +21162,8 @@ msgid "Rotation Degrees" msgstr "Grados de Rotación" #: scene/2d/node_2d.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Global Rotation" -msgstr "Constante Global" +msgstr "Rotación Global" #: scene/2d/node_2d.cpp msgid "Global Rotation Degrees" @@ -21668,41 +21174,37 @@ msgid "Global Scale" msgstr "Escala Global" #: scene/2d/node_2d.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Global Transform" -msgstr "Mantener transformación global" +msgstr "Transformación Global" #: scene/2d/node_2d.cpp -#, fuzzy msgid "Z As Relative" -msgstr "Ajuste Relativo" +msgstr "Z Como Relativo" #: scene/2d/parallax_background.cpp scene/gui/scroll_container.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Scroll" -msgstr "" +msgstr "Scroll" #: scene/2d/parallax_background.cpp msgid "Base Offset" msgstr "Desplazamiento Base" #: scene/2d/parallax_background.cpp -#, fuzzy msgid "Base Scale" -msgstr "Usar Ajuste de Escalado" +msgstr "Escala Base" #: scene/2d/parallax_background.cpp msgid "Limit Begin" -msgstr "" +msgstr "Inicio del LÃmite" #: scene/2d/parallax_background.cpp -#, fuzzy msgid "Limit End" -msgstr "Al Final" +msgstr "Fin del LÃmite" #: scene/2d/parallax_background.cpp msgid "Ignore Camera Zoom" -msgstr "" +msgstr "Ignorar Zoom de la Cámara" #: scene/2d/parallax_layer.cpp msgid "" @@ -21714,12 +21216,10 @@ msgstr "" #: scene/2d/parallax_layer.cpp scene/2d/physics_body_2d.cpp #: scene/3d/physics_body.cpp scene/3d/vehicle_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Motion" -msgstr "Acción" +msgstr "Movimiento" #: scene/2d/parallax_layer.cpp -#, fuzzy msgid "Mirroring" msgstr "Reflejar" @@ -21766,9 +21266,8 @@ msgstr "" "\"Particles Animation\" activado." #: scene/2d/particles_2d.cpp -#, fuzzy msgid "Visibility Rect" -msgstr "Modo de Prioridad" +msgstr "Visibilidad Rect" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp msgid "Process Material" @@ -21776,9 +21275,8 @@ msgstr "" #: scene/2d/path_2d.cpp scene/3d/path.cpp scene/resources/sky.cpp #: scene/resources/texture.cpp -#, fuzzy msgid "Curve" -msgstr "Partir Curva" +msgstr "Curva" #: scene/2d/path_2d.cpp msgid "PathFollow2D only works when set as a child of a Path2D node." @@ -21806,25 +21304,21 @@ msgid "Lookahead" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/visual_instance.cpp -#, fuzzy msgid "Layers" -msgstr "Capa" +msgstr "Capas" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Constant Linear Velocity" -msgstr "Inicializar" +msgstr "Velocidad Lineal Constante" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Constant Angular Velocity" -msgstr "Inicializar" +msgstr "Velocidad Angular Constante" #: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp #: scene/resources/physics_material.cpp -#, fuzzy msgid "Friction" -msgstr "Función" +msgstr "Fricción" #: scene/2d/physics_body_2d.cpp scene/2d/tile_map.cpp scene/3d/physics_body.cpp #: scene/resources/physics_material.cpp @@ -21837,9 +21331,8 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: scene/resources/world.cpp scene/resources/world_2d.cpp -#, fuzzy msgid "Default Gravity" -msgstr "Vista Previa Por Defecto" +msgstr "Gravedad por Defecto" #: scene/2d/physics_body_2d.cpp msgid "" @@ -21860,38 +21353,33 @@ msgid "Inertia" msgstr "Inercia" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Weight" -msgstr "Luz" +msgstr "Peso" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Gravity Scale" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Custom Integrator" -msgstr "CustomNode" +msgstr "Integrador Personalizado" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Continuous CD" -msgstr "Continuo" +msgstr "CD Continuo" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Contacts Reported" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Contact Monitor" -msgstr "Seleccionar Color" +msgstr "Monitor de Contacto" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Sleeping" -msgstr "Ajuste Inteligente" +msgstr "Resposo" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Can Sleep" @@ -21914,18 +21402,16 @@ msgid "Torque" msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Safe Margin" -msgstr "Asignar Margen" +msgstr "Margen de Seguridad" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Sync To Physics" msgstr "Sincronización Con La FÃsica" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Moving Platform" -msgstr "Moviendo salida" +msgstr "Plataforma Móvil" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Apply Velocity On Leave" @@ -21935,24 +21421,21 @@ msgstr "" #: scene/3d/physics_body.cpp scene/gui/texture_button.cpp #: scene/resources/default_theme/default_theme.cpp #: scene/resources/line_shape_2d.cpp scene/resources/material.cpp -#, fuzzy msgid "Normal" -msgstr "Formato" +msgstr "Normal" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Remainder" msgstr "Recordatorio" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Local Shape" -msgstr "Idioma" +msgstr "Forma Local" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider" -msgstr "Modo de Colisión" +msgstr "Colisionador" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp @@ -21961,26 +21444,22 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider RID" -msgstr "RID inválido" +msgstr "Colisionador RID" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider Shape" -msgstr "Modo de Colisión" +msgstr "Forma de Colisión" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp -#, fuzzy msgid "Collider Shape Index" -msgstr "Modo de Colisión" +msgstr "Ãndice de Formas de Colisión" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #: servers/physics_2d_server.cpp servers/physics_server.cpp -#, fuzzy msgid "Collider Velocity" -msgstr "Vista de Órbita Derecha" +msgstr "Velocidad del Colisionador" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Collider Metadata" @@ -21991,28 +21470,24 @@ msgid "Invert" msgstr "" #: scene/2d/polygon_2d.cpp -#, fuzzy msgid "Vertex Colors" -msgstr "Vértice" +msgstr "Color de los Vértices" #: scene/2d/polygon_2d.cpp -#, fuzzy msgid "Internal Vertex Count" -msgstr "Crear Vértice Interno" +msgstr "Conteo de Vértices Internos" #: scene/2d/position_2d.cpp -#, fuzzy msgid "Gizmo Extents" -msgstr "Gizmos" +msgstr "Extensión de Gizmos" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp msgid "Exclude Parent" msgstr "" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp -#, fuzzy msgid "Cast To" -msgstr "Crear Nodo Shader" +msgstr "Lanzar A" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp msgid "Collide With" @@ -22031,24 +21506,20 @@ msgid "Path property must point to a valid Node2D node to work." msgstr "La propiedad Path debe apuntar a un nodo Node2D válido para funcionar." #: scene/2d/remote_transform_2d.cpp scene/3d/remote_transform.cpp -#, fuzzy msgid "Remote Path" -msgstr "Eliminar Punto" +msgstr "Ruta Remota" #: scene/2d/remote_transform_2d.cpp scene/3d/remote_transform.cpp -#, fuzzy msgid "Use Global Coordinates" -msgstr "Siguiente Coordenada" +msgstr "Utilizar Coordenadas Globales" #: scene/2d/skeleton_2d.cpp scene/3d/skeleton.cpp -#, fuzzy msgid "Rest" -msgstr "Reiniciar" +msgstr "Reposo" #: scene/2d/skeleton_2d.cpp -#, fuzzy msgid "Default Length" -msgstr "Theme Predeterminado" +msgstr "Longitud por Defecto" #: scene/2d/skeleton_2d.cpp msgid "This Bone2D chain should end at a Skeleton2D node." @@ -22075,14 +21546,12 @@ msgid "Vframes" msgstr "" #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Frame Coords" -msgstr "Fotograma %" +msgstr "Coordenadas del Marco" #: scene/2d/sprite.cpp scene/resources/texture.cpp -#, fuzzy msgid "Filter Clip" -msgstr "Filtrar scripts" +msgstr "Filtrar Clips" #: scene/2d/tile_map.cpp msgid "" @@ -22095,44 +21564,36 @@ msgstr "" "RigidBody2D, KinematicBody2D, etc. para que puedan tener forma." #: scene/2d/tile_map.cpp -#, fuzzy msgid "Tile Set" -msgstr "TileSet" +msgstr "Tile Set" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Quadrant Size" -msgstr "Cambiar Tamaño de Cámara" +msgstr "Tamaño del Cuadrante" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Custom Transform" -msgstr "Transformar" +msgstr "Transformación Personalizada" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Half Offset" -msgstr "Inicializar" +msgstr "Medio Desplazamiento" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Tile Origin" -msgstr "Ver Origen" +msgstr "Origen de los Tiles" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Y Sort" -msgstr "Ordenar" +msgstr "Ordenar Y" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Show Collision" -msgstr "Colisión" +msgstr "Mostrar Colisión" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Compatibility Mode" -msgstr "Modo de Prioridad" +msgstr "Modo de Compatibilidad" #: scene/2d/tile_map.cpp msgid "Centered Textures" @@ -22143,32 +21604,28 @@ msgid "Cell Clip UV" msgstr "" #: scene/2d/tile_map.cpp -#, fuzzy msgid "Use Parent" -msgstr "Modo de Colisión" +msgstr "Usar Padres" #: scene/2d/tile_map.cpp msgid "Use Kinematic" msgstr "" #: scene/2d/touch_screen_button.cpp -#, fuzzy msgid "Shape Centered" -msgstr "Ajustar al Centro del Nodo" +msgstr "Forma Centrada" #: scene/2d/touch_screen_button.cpp -#, fuzzy msgid "Shape Visible" -msgstr "Act./Desact. Visible" +msgstr "Forma Visible" #: scene/2d/touch_screen_button.cpp msgid "Passby Press" msgstr "" #: scene/2d/touch_screen_button.cpp -#, fuzzy msgid "Visibility Mode" -msgstr "Modo de Prioridad" +msgstr "Modo de Visibilidad" #: scene/2d/visibility_notifier_2d.cpp msgid "" @@ -22179,28 +21636,24 @@ msgstr "" "editada directamente como padre." #: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp -#, fuzzy msgid "Pause Animations" -msgstr "Pegar Animación" +msgstr "Pausar Animaciones" #: scene/2d/visibility_notifier_2d.cpp scene/3d/visibility_notifier.cpp msgid "Freeze Bodies" msgstr "" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Pause Particles" -msgstr "PartÃculas" +msgstr "Pausar PartÃculas" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Pause Animated Sprites" -msgstr "Pegar Animación" +msgstr "Pausar Sprites Animados" #: scene/2d/visibility_notifier_2d.cpp -#, fuzzy msgid "Process Parent" -msgstr "Activar Prioridad" +msgstr "Procesamiento de los Padres" #: scene/2d/visibility_notifier_2d.cpp msgid "Physics Process Parent" @@ -22211,9 +21664,8 @@ msgid "Reverb Bus" msgstr "" #: scene/3d/area.cpp -#, fuzzy msgid "Uniformity" -msgstr "Establecer Nombre de Uniform" +msgstr "Uniformidad" #: scene/3d/arvr_nodes.cpp msgid "ARVRCamera must have an ARVROrigin node as its parent." @@ -22240,9 +21692,8 @@ msgstr "" "un controlador real." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "Anchor ID" -msgstr "Sólo anclado" +msgstr "ID de Ancla" #: scene/3d/arvr_nodes.cpp msgid "ARVRAnchor must have an ARVROrigin node as its parent." @@ -22265,9 +21716,8 @@ msgid "World Scale" msgstr "Escala del Mundo" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Attenuation Model" -msgstr "Nodo de Animación" +msgstr "Modelo de Atenuación" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit dB" @@ -22286,18 +21736,16 @@ msgid "Out Of Range Mode" msgstr "" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Emission Angle" -msgstr "Colores de Emisión" +msgstr "Ãngulo de Emisión" #: scene/3d/audio_stream_player_3d.cpp msgid "Degrees" msgstr "Grados" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Filter Attenuation dB" -msgstr "Animación" +msgstr "Filtro de Atenuación dB" #: scene/3d/audio_stream_player_3d.cpp msgid "Attenuation Filter" @@ -22311,19 +21759,16 @@ msgstr "" #: scene/3d/audio_stream_player_3d.cpp #: servers/audio/effects/audio_effect_filter.cpp -#, fuzzy msgid "dB" -msgstr "B" +msgstr "dB" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Doppler" -msgstr "Activar Doppler" +msgstr "Doppler" #: scene/3d/audio_stream_player_3d.cpp -#, fuzzy msgid "Tracking" -msgstr "Empaquetando" +msgstr "Seguimiento" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/reflection_probe.cpp @@ -22357,9 +21802,8 @@ msgstr "Hecho" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/reflection_probe.cpp scene/resources/box_shape.cpp #: scene/resources/rectangle_shape_2d.cpp -#, fuzzy msgid "Extents" -msgstr "Gizmos" +msgstr "Extensiones" #: scene/3d/baked_lightmap.cpp msgid "Tweaks" @@ -22382,66 +21826,56 @@ msgid "Use HDR" msgstr "" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Use Color" -msgstr "Colores" +msgstr "Usar Color" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Default Texels Per Unit" -msgstr "Theme Predeterminado" +msgstr "Texeles Por Unidad Predeterminados" #: scene/3d/baked_lightmap.cpp scene/resources/texture.cpp -#, fuzzy msgid "Atlas" -msgstr "Nuevo Atlas" +msgstr "Atlas" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Generate" -msgstr "General" +msgstr "Generar" #: scene/3d/baked_lightmap.cpp msgid "Max Size" msgstr "Tamaño Máximo" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Custom Sky" -msgstr "CustomNode" +msgstr "Cielo Personalizado" #: scene/3d/baked_lightmap.cpp msgid "Custom Sky Rotation Degrees" msgstr "Grados de Rotación del Cielo Personalizados" #: scene/3d/baked_lightmap.cpp scene/3d/ray_cast.cpp -#, fuzzy msgid "Custom Color" -msgstr "CustomNode" +msgstr "Color Personalizado" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Custom Energy" -msgstr "Mover Efecto de Bus" +msgstr "EnergÃa Personalizada" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Min Light" -msgstr "Indentar a la Derecha" +msgstr "Luz MÃnima" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp -#, fuzzy msgid "Propagation" -msgstr "Navegación" +msgstr "Propagación" #: scene/3d/baked_lightmap.cpp msgid "Image Path" msgstr "" #: scene/3d/baked_lightmap.cpp -#, fuzzy msgid "Light Data" -msgstr "Con Datos" +msgstr "Datos de Iluminación" #: scene/3d/bone_attachment.cpp scene/3d/physics_body.cpp msgid "Bone Name" @@ -22456,14 +21890,12 @@ msgid "Cull Mask" msgstr "" #: scene/3d/camera.cpp -#, fuzzy msgid "Doppler Tracking" -msgstr "Pista de Propiedades" +msgstr "Seguimiento de Doppler" #: scene/3d/camera.cpp -#, fuzzy msgid "Projection" -msgstr "Proyecto" +msgstr "Proyección" #: scene/3d/camera.cpp msgid "FOV" @@ -22474,9 +21906,8 @@ msgid "Frustum Offset" msgstr "Offset de Frustum" #: scene/3d/camera.cpp -#, fuzzy msgid "Near" -msgstr "Más Cercano" +msgstr "Cercano" #: scene/3d/camera.cpp msgid "Far" @@ -22487,23 +21918,20 @@ msgstr "" #: scene/resources/shape.cpp scene/resources/style_box.cpp #: scene/resources/texture.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp -#, fuzzy msgid "Margin" -msgstr "Asignar Margen" +msgstr "Margen" #: scene/3d/camera.cpp -#, fuzzy msgid "Clip To" -msgstr "Clip Arriba" +msgstr "Recortar A" #: scene/3d/collision_object.cpp scene/3d/soft_body.cpp msgid "Ray Pickable" msgstr "" #: scene/3d/collision_object.cpp -#, fuzzy msgid "Capture On Drag" -msgstr "Captura" +msgstr "Captura Al Arrastrar" #: scene/3d/collision_object.cpp msgid "" @@ -22575,53 +22003,44 @@ msgstr "" "Billboard esté ajustado a \"Particle Billboard\"." #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Box Extents" -msgstr "Gizmos" +msgstr "Extensión de Cajas" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Radius" -msgstr "Máscara de Emisión" +msgstr "Radio del Anillo" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Inner Radius" -msgstr "Cambiar Radio Interno de Torus" +msgstr "Radio Interior del Anillo" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Height" -msgstr "Rotar a la Derecha" +msgstr "Altura del Anillo" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Ring Axis" -msgstr "Advertencias" +msgstr "Eje del Anillo" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Rotate Y" -msgstr "Rotar" +msgstr "Rotar Y" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp -#, fuzzy msgid "Disable Z" -msgstr "Desactivar Elemento" +msgstr "Desactivar Z" #: scene/3d/cpu_particles.cpp scene/resources/particles_material.cpp msgid "Flatness" msgstr "" #: scene/3d/cull_instance.cpp servers/visual_server.cpp -#, fuzzy msgid "Portals" -msgstr "Voltear Portales" +msgstr "Portales" #: scene/3d/cull_instance.cpp -#, fuzzy msgid "Portal Mode" -msgstr "Modo de Prioridad" +msgstr "Modo Portal" #: scene/3d/cull_instance.cpp msgid "Include In Bound" @@ -22632,9 +22051,8 @@ msgid "Allow Merging" msgstr "" #: scene/3d/cull_instance.cpp -#, fuzzy msgid "Autoplace Priority" -msgstr "Activar Prioridad" +msgstr "Prioridad de Autoemplazamiento" #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" @@ -22667,9 +22085,8 @@ msgid "Subdiv" msgstr "" #: scene/3d/gi_probe.cpp -#, fuzzy msgid "Dynamic Range" -msgstr "LibrerÃa Dinámica" +msgstr "Rango Dinámico" #: scene/3d/gi_probe.cpp scene/3d/light.cpp msgid "Normal Bias" @@ -22677,18 +22094,16 @@ msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Pixel Size" -msgstr "Ajuste de PÃxeles" +msgstr "Tamaño de PÃxeles" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Billboard" msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp -#, fuzzy msgid "Shaded" -msgstr "Shader" +msgstr "Sombreado" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Double Sided" @@ -22699,9 +22114,8 @@ msgid "No Depth Test" msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/material.cpp -#, fuzzy msgid "Fixed Size" -msgstr "Vista Frontal" +msgstr "Tamaño Fijo" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp msgid "Alpha Cut" @@ -22712,119 +22126,98 @@ msgid "Alpha Scissor Threshold" msgstr "" #: scene/3d/label_3d.cpp scene/3d/sprite_3d.cpp scene/resources/material.cpp -#, fuzzy msgid "Render Priority" -msgstr "Activar Prioridad" +msgstr "Prioridad de Renderización" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Outline Render Priority" -msgstr "Activar Prioridad" +msgstr "Prioridad de Renderización del Contorno" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Outline Modulate" -msgstr "Forzar Modulación en Blanco" +msgstr "Modular Contorno" #: scene/3d/label_3d.cpp scene/resources/default_theme/default_theme.cpp #: scene/resources/dynamic_font.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Font" -msgstr "Fuentes" +msgstr "Fuente" #: scene/3d/label_3d.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Horizontal Alignment" -msgstr "Horizontal Activado" +msgstr "Alineación Horizontal" #: scene/3d/label_3d.cpp -#, fuzzy msgid "Vertical Alignment" -msgstr "Filtrar señales" +msgstr "Alineación Vertical" #: scene/3d/label_3d.cpp scene/gui/dialogs.cpp scene/gui/label.cpp -#, fuzzy msgid "Autowrap" -msgstr "AutoLoad" +msgstr "Envoltura Automática" #: scene/3d/light.cpp -#, fuzzy msgid "Indirect Energy" -msgstr "Colores de Emisión" +msgstr "EnergÃa Indirecta" #: scene/3d/light.cpp -#, fuzzy msgid "Negative" -msgstr "GDNative" +msgstr "Negativo" #: scene/3d/light.cpp scene/resources/material.cpp #: scene/resources/visual_shader.cpp -#, fuzzy msgid "Specular" -msgstr "Modo de Regla" +msgstr "Especular" #: scene/3d/light.cpp -#, fuzzy msgid "Bake Mode" -msgstr "Modo de Bitmask" +msgstr "Modo de Bakeo" #: scene/3d/light.cpp -#, fuzzy msgid "Contact" -msgstr "Seleccionar Color" +msgstr "Contacto" #: scene/3d/light.cpp -#, fuzzy msgid "Reverse Cull Face" -msgstr "Restablecer Volumen de Bus" +msgstr "Eliminar Caras Invertidas" #: scene/3d/light.cpp servers/visual_server.cpp -#, fuzzy msgid "Directional Shadow" -msgstr "Direcciones" +msgstr "Sombra Direccional" #: scene/3d/light.cpp -#, fuzzy msgid "Split 1" -msgstr "Dividir" +msgstr "Dividir 1" #: scene/3d/light.cpp -#, fuzzy msgid "Split 2" -msgstr "Dividir" +msgstr "Dividir 2" #: scene/3d/light.cpp -#, fuzzy msgid "Split 3" -msgstr "Dividir" +msgstr "Dividir 3" #: scene/3d/light.cpp msgid "Blend Splits" msgstr "Mezclar Divisiones" #: scene/3d/light.cpp -#, fuzzy msgid "Bias Split Scale" -msgstr "Usar Ajuste de Escalado" +msgstr "Escala de División del Sesgo" #: scene/3d/light.cpp -#, fuzzy msgid "Depth Range" -msgstr "Profundidad" +msgstr "Rango de Profundidad" #: scene/3d/light.cpp msgid "Omni" msgstr "" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Mode" -msgstr "Shader" +msgstr "Modo de Sombreado" #: scene/3d/light.cpp -#, fuzzy msgid "Shadow Detail" -msgstr "Mostrar Por Defecto" +msgstr "Detalle de la Sombra" #: scene/3d/light.cpp msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows." @@ -22836,9 +22229,8 @@ msgid "Spot" msgstr "" #: scene/3d/light.cpp -#, fuzzy msgid "Angle Attenuation" -msgstr "Animación" +msgstr "Atenuación del Ãngulo" #: scene/3d/mesh_instance.cpp msgid "Software Skinning" @@ -22856,43 +22248,38 @@ msgid "" msgstr "" #: scene/3d/navigation.cpp scene/resources/curve.cpp -#, fuzzy msgid "Up Vector" -msgstr "Vector" +msgstr "Vector Superior" #: scene/3d/navigation.cpp -#, fuzzy msgid "Cell Height" -msgstr "Prueba" +msgstr "Altura de la Celda" #: scene/3d/navigation_agent.cpp msgid "Agent Height Offset" msgstr "" #: scene/3d/navigation_agent.cpp -#, fuzzy msgid "Ignore Y" -msgstr "[Ignorar]" +msgstr "Ignorar Y" #: scene/3d/navigation_agent.cpp -#, fuzzy msgid "" "The NavigationAgent can be used only under a Spatial inheriting parent node." -msgstr "El NavigationAgent sólo puede utilizarse bajo un nodo spatial." +msgstr "" +"El NavigationAgent solo puede utilizarse en un nodo padre de tipo Spatial." #: scene/3d/navigation_mesh_instance.cpp scene/resources/mesh_library.cpp -#, fuzzy msgid "NavMesh" -msgstr "Calcular NavMesh" +msgstr "NavMesh" #: scene/3d/navigation_obstacle.cpp -#, fuzzy msgid "" "The NavigationObstacle only serves to provide collision avoidance to a " "Spatial inheriting parent object." msgstr "" -"El NavigationObstacle sólo sirve para evitar la colisión de un objeto " -"spatial." +"El NavigationObstacle solo sirve para evitar colisiones en un objeto padre " +"de tipo Spatial." #: scene/3d/occluder.cpp msgid "No shape is set." @@ -22943,9 +22330,8 @@ msgstr "" "Billboard esté ajustado a \"Particle Billboard\"." #: scene/3d/particles.cpp -#, fuzzy msgid "Visibility AABB" -msgstr "Cambiar Visibilidad" +msgstr "Visibilidad AABB" #: scene/3d/particles.cpp msgid "Draw Passes" @@ -22969,7 +22355,6 @@ msgstr "" "el recurso Curve de su Path padre." #: scene/3d/path.cpp -#, fuzzy msgid "Rotation Mode" msgstr "Modo de Rotación" @@ -22984,65 +22369,56 @@ msgstr "" "En su lugar, cambia el tamaño en las formas de colisión de los hijos." #: scene/3d/physics_body.cpp -#, fuzzy msgid "Axis Lock" -msgstr "Eje" +msgstr "Bloquear Ejes" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear X" -msgstr "Lineal" +msgstr "Lineal X" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Y" -msgstr "Lineal" +msgstr "Lineal Y" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Z" -msgstr "Lineal" +msgstr "Lineal Z" #: scene/3d/physics_body.cpp msgid "Angular X" -msgstr "" +msgstr "Angular X" #: scene/3d/physics_body.cpp msgid "Angular Y" -msgstr "" +msgstr "Angular Y" #: scene/3d/physics_body.cpp msgid "Angular Z" -msgstr "" +msgstr "Angular Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion X" -msgstr "Acción" +msgstr "Movimiento X" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion Y" -msgstr "Acción" +msgstr "Movimiento Y" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Motion Z" -msgstr "Acción" +msgstr "Movimiento Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Joint Constraints" -msgstr "Constantes" +msgstr "Restringir Articulaciones" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Impulse Clamp" msgstr "" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp -#, fuzzy msgid "Swing Span" -msgstr "Guardar Escena" +msgstr "Expansión de Swing" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "Twist Span" @@ -23054,147 +22430,124 @@ msgid "Relaxation" msgstr "Relajación" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Enabled" -msgstr "Filtrar señales" +msgstr "LÃmite Angular Activado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Upper" -msgstr "Lineal" +msgstr "LÃmite Angular Superior" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Lower" -msgstr "Ortogonal Angular" +msgstr "LÃmite Angular Inferior" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Bias" -msgstr "Lineal" +msgstr "Sesgo de LÃmite Angular" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Softness" -msgstr "Animación" +msgstr "LÃmite Angular de Suavizado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Relaxation" -msgstr "Animación" +msgstr "Relajación del LÃmite Angular" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Upper" -msgstr "Lineal" +msgstr "LÃmite Lineal Superior" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Lower" -msgstr "Lineal" +msgstr "LÃmite Lineal Inferior" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Softness" -msgstr "Lineal" +msgstr "LÃmite Lineal de Suavizado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Restitution" -msgstr "Lineal" +msgstr "Restitución del LÃmite Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Damping" -msgstr "Lineal" +msgstr "Amortiguación de LÃmite Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Restitution" -msgstr "Animación" +msgstr "Restitución del LÃmite Angular" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Limit Damping" -msgstr "Animación" +msgstr "Amortiguación de LÃmite Angular" #: scene/3d/physics_body.cpp msgid "X" -msgstr "" +msgstr "X" #: scene/3d/physics_body.cpp msgid "Y" -msgstr "" +msgstr "Y" #: scene/3d/physics_body.cpp msgid "Z" -msgstr "" +msgstr "Z" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Limit Enabled" -msgstr "Lineal" +msgstr "LÃmite Lineal Activado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Enabled" -msgstr "Lineal" +msgstr "Amortiguador Lineal Activado" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Stiffness" -msgstr "Lineal" +msgstr "Rigidez Lineal del Amortiguador" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Spring Damping" -msgstr "Lineal" +msgstr "Atenuación Lineal del Amortiguador" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Equilibrium Point" -msgstr "Lineal" +msgstr "Punto de Equilibrio Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Restitution" -msgstr "Descripción" +msgstr "Restitución Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Linear Damping" -msgstr "Lineal" +msgstr "Amortiguación Lineal" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Restitution" -msgstr "Descripción" +msgstr "Restitución Angular" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Damping" -msgstr "Animación" +msgstr "Amortiguación Angular" #: scene/3d/physics_body.cpp scene/3d/physics_joint.cpp msgid "ERP" -msgstr "" +msgstr "ERP" #: scene/3d/physics_body.cpp -#, fuzzy msgid "Angular Spring Enabled" -msgstr "Filtrar señales" +msgstr "Amortiguación Angular Activada" #: scene/3d/physics_body.cpp msgid "Angular Spring Stiffness" -msgstr "" +msgstr "Rigidez del Amortiguador Angular" #: scene/3d/physics_body.cpp msgid "Angular Spring Damping" -msgstr "" +msgstr "Amortiguación Angular del Muelle" #: scene/3d/physics_body.cpp msgid "Angular Equilibrium Point" -msgstr "" +msgstr "Punto de Equilibrio Angular" #: scene/3d/physics_body.cpp msgid "Body Offset" @@ -23225,9 +22578,8 @@ msgid "Solver" msgstr "" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Exclude Nodes" -msgstr "Eliminar Nodos" +msgstr "Excluir Nodos" #: scene/3d/physics_joint.cpp msgid "Params" @@ -23238,32 +22590,28 @@ msgid "Angular Limit" msgstr "" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper" -msgstr "Mayúsculas" +msgstr "Superior" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower" -msgstr "Minúsculas" +msgstr "Inferior" #: scene/3d/physics_joint.cpp msgid "Motor" -msgstr "" +msgstr "Motor" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Target Velocity" -msgstr "Vista de Órbita Derecha" +msgstr "Velocidad del Objetivo" #: scene/3d/physics_joint.cpp msgid "Max Impulse" msgstr "Impulso Máximo" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit" -msgstr "Lineal" +msgstr "LÃmite Lineal" #: scene/3d/physics_joint.cpp msgid "Upper Distance" @@ -23274,57 +22622,48 @@ msgid "Lower Distance" msgstr "Distancia Inferior" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Restitution" -msgstr "Descripción" +msgstr "Restitución" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motion" -msgstr "Inicializar" +msgstr "Movimiento Lineal" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Ortho" -msgstr "Ortogonal Trasera" +msgstr "Ortogonal Lineal" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Upper Angle" -msgstr "Mayúsculas" +msgstr "Ãngulo Superior" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Lower Angle" -msgstr "Minúsculas" +msgstr "Ãngulo Inferior" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Angular Motion" -msgstr "Animación" +msgstr "Movimiento Angular" #: scene/3d/physics_joint.cpp msgid "Angular Ortho" msgstr "Ortogonal Angular" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit X" -msgstr "Lineal" +msgstr "LÃmite Lineal X" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor X" -msgstr "Inicializar" +msgstr "Motor Lineal X" #: scene/3d/physics_joint.cpp msgid "Force Limit" msgstr "Forzar LÃmite" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring X" -msgstr "Lineal" +msgstr "Amortiguación Lineal X" #: scene/3d/physics_joint.cpp msgid "Equilibrium Point" @@ -23340,22 +22679,19 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Angular Spring X" -msgstr "" +msgstr "Amortiguación Angular X" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit Y" -msgstr "Lineal" +msgstr "LÃmite Lineal Y" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor Y" -msgstr "Inicializar" +msgstr "Motor Lineal Y" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring Y" -msgstr "Lineal" +msgstr "Amortiguación Lineal Y" #: scene/3d/physics_joint.cpp msgid "Angular Limit Y" @@ -23367,22 +22703,19 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Angular Spring Y" -msgstr "" +msgstr "Amortiguación Angular Y" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Limit Z" -msgstr "Lineal" +msgstr "LÃmite Lineal Z" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Motor Z" -msgstr "Inicializar" +msgstr "Motor Lineal Z" #: scene/3d/physics_joint.cpp -#, fuzzy msgid "Linear Spring Z" -msgstr "Lineal" +msgstr "Amortiguación Lineal Z" #: scene/3d/physics_joint.cpp msgid "Angular Limit Z" @@ -23394,7 +22727,7 @@ msgstr "" #: scene/3d/physics_joint.cpp msgid "Angular Spring Z" -msgstr "" +msgstr "Amortiguación Angular Z" #: scene/3d/portal.cpp msgid "The RoomManager should not be a child or grandchild of a Portal." @@ -23421,14 +22754,12 @@ msgid "Linked Room" msgstr "Sala Vinculada" #: scene/3d/portal.cpp -#, fuzzy msgid "Use Default Margin" -msgstr "Por defecto" +msgstr "Usar Margen por Defecto" #: scene/3d/proximity_group.cpp -#, fuzzy msgid "Group Name" -msgstr "Agrupado" +msgstr "Nombre del Grupo" #: scene/3d/proximity_group.cpp msgid "Dispatch Mode" @@ -23439,47 +22770,40 @@ msgid "Grid Radius" msgstr "Radio de CuadrÃcula" #: scene/3d/ray_cast.cpp -#, fuzzy msgid "Debug Shape" -msgstr "Depurador" +msgstr "Depurar Shape" #: scene/3d/ray_cast.cpp scene/resources/style_box.cpp msgid "Thickness" msgstr "" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp -#, fuzzy msgid "Update Mode" -msgstr "Modo de Rotación" +msgstr "Modo de Actualización" #: scene/3d/reflection_probe.cpp msgid "Origin Offset" msgstr "Desplazamiento de Origen" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Box Projection" -msgstr "Proyecto" +msgstr "Proyección de Cajas" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Enable Shadows" -msgstr "Activar Ajuste" +msgstr "Activar Sombras" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Color" -msgstr "Seleccionar Color" +msgstr "Color de Ambiente" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Energy" -msgstr "Colores de Emisión" +msgstr "EnergÃa Ambiental" #: scene/3d/reflection_probe.cpp -#, fuzzy msgid "Ambient Contrib" -msgstr "Indentar a la Derecha" +msgstr "Contribución Ambiental" #: scene/3d/remote_transform.cpp msgid "" @@ -23523,9 +22847,8 @@ msgid "Bound" msgstr "" #: scene/3d/room_group.cpp -#, fuzzy msgid "Roomgroup Priority" -msgstr "Prioridad" +msgstr "Prioridad del Roomgroup" #: scene/3d/room_group.cpp msgid "The RoomManager should not be placed inside a RoomGroup." @@ -23559,66 +22882,57 @@ msgstr "" #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp #: scene/animation/animation_tree_player.cpp #: servers/audio/effects/audio_effect_delay.cpp -#, fuzzy msgid "Active" -msgstr "Acción" +msgstr "Activo" #: scene/3d/room_manager.cpp msgid "Roomlist" msgstr "" #: scene/3d/room_manager.cpp servers/visual_server.cpp -#, fuzzy msgid "PVS" -msgstr "FPS" +msgstr "PVS" #: scene/3d/room_manager.cpp -#, fuzzy msgid "PVS Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo PVS" #: scene/3d/room_manager.cpp -#, fuzzy msgid "PVS Filename" -msgstr "Archivo ZIP" +msgstr "Nombre del Archivo PVS" #: scene/3d/room_manager.cpp servers/visual_server.cpp msgid "Gameplay" msgstr "" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Gameplay Monitor" -msgstr "Monitor" +msgstr "Monitor de Juego" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Use Secondary PVS" -msgstr "Usar Ajuste de Escalado" +msgstr "Usar PVS Secundario" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Merge Meshes" -msgstr "Malla" +msgstr "Fusionar Mallas" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Show Margins" -msgstr "Mostrar Origen" +msgstr "Mostrar Márgenes" #: scene/3d/room_manager.cpp #, fuzzy msgid "Debug Sprawl" -msgstr "Depurar" +msgstr "Depurar Desorden" #: scene/3d/room_manager.cpp msgid "Overlap Warning Threshold" msgstr "" #: scene/3d/room_manager.cpp -#, fuzzy msgid "Preview Camera" -msgstr "Vista Previa" +msgstr "Vista previa de la Cámara" #: scene/3d/room_manager.cpp msgid "Portal Depth Limit" @@ -23774,18 +23088,16 @@ msgstr "" "En su lugar, cambia el tamaño en las formas de colisión de los hijos." #: scene/3d/spatial.cpp -#, fuzzy msgid "Global Translation" -msgstr "Mantener transformación global" +msgstr "Transformación Global" #: scene/3d/spatial.cpp msgid "Matrix" -msgstr "" +msgstr "Matriz" #: scene/3d/spatial.cpp -#, fuzzy msgid "Gizmo" -msgstr "Gizmos" +msgstr "Gizmo" #: scene/3d/spatial_velocity_tracker.cpp #, fuzzy @@ -23794,7 +23106,7 @@ msgstr "Fotogramas de FÃsica %" #: scene/3d/spring_arm.cpp msgid "Spring Length" -msgstr "" +msgstr "Cantidad de Amortiguación" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp msgid "Opacity" @@ -24999,19 +24311,16 @@ msgid "Fold Gutter" msgstr "Plegar Gutter" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Drag And Drop Selection Enabled" -msgstr "Sólo selección" +msgstr "Selección de Arrastrar y Soltar Activada" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Hiding Enabled" -msgstr "Activar" +msgstr "Ocultación Activada" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Wrap Enabled" -msgstr "Activar" +msgstr "Ajuste Activado" #: scene/gui/text_edit.cpp msgid "Scroll Vertical" @@ -25420,60 +24729,60 @@ msgid "" "Effects.\n" "HDR will be disabled for this Viewport." msgstr "" +"Este Viewport tiene HDR habilitado, pero su uso está establecido en 2D o 2D " +"sin muestreo.\n" +"El HDR solo está soportado en los Viewports que tienen su uso establecido en " +"3D o 3D Sin Efectos.\n" +"El HDR estará desactivado para esta ventana." #: scene/main/viewport.cpp msgid "ARVR" -msgstr "" +msgstr "ARVR" #: scene/main/viewport.cpp -#, fuzzy msgid "Size Override Stretch" -msgstr "Elemento de Anulación" +msgstr "Anulación del Tamaño de Estiramiento" #: scene/main/viewport.cpp msgid "Own World" -msgstr "" +msgstr "Mundo Propio" #: scene/main/viewport.cpp scene/resources/world_2d.cpp msgid "World" -msgstr "" +msgstr "Mundo" #: scene/main/viewport.cpp msgid "World 2D" -msgstr "" +msgstr "Mundo 2D" #: scene/main/viewport.cpp -#, fuzzy msgid "Transparent BG" -msgstr "Transponer" +msgstr "Fondo Transparente" #: scene/main/viewport.cpp -#, fuzzy msgid "Handle Input Locally" -msgstr "Cambiar Valor de Entrada" +msgstr "Manejar Entradas Localmente" #: scene/main/viewport.cpp msgid "FXAA" -msgstr "" +msgstr "FXAA" #: scene/main/viewport.cpp #, fuzzy msgid "Debanding" -msgstr "Vinculación" +msgstr "Debanding" #: scene/main/viewport.cpp -#, fuzzy msgid "Disable 3D" -msgstr "Desactivar Elemento" +msgstr "Desactivar 3D" #: scene/main/viewport.cpp -#, fuzzy msgid "Keep 3D Linear" -msgstr "Izquierda Lineal" +msgstr "Mantener 3D Lineal" #: scene/main/viewport.cpp msgid "Render Direct To Screen" -msgstr "" +msgstr "Renderización Directa en Pantalla" #: scene/main/viewport.cpp #, fuzzy @@ -25880,9 +25189,8 @@ msgid "Decrement Pressed" msgstr "" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Slider" -msgstr "Modo de Colisión" +msgstr "Deslizador" #: scene/resources/default_theme/default_theme.cpp msgid "Grabber Area" @@ -26321,13 +25629,12 @@ msgid "Mono Font" msgstr "Fuente Principal" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Table H Separation" -msgstr "Separación de Tabla H" +msgstr "Separación H de Tabla" #: scene/resources/default_theme/default_theme.cpp msgid "Table V Separation" -msgstr "Separación de Tabla V" +msgstr "Separación V de Tabla" #: scene/resources/default_theme/default_theme.cpp msgid "Margin Left" diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index de1187f08f..b37d9dcfd8 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -20,13 +20,14 @@ # M3CG <cgmario1999@gmail.com>, 2021, 2022. # Manuel González <mgoopazo@gmail.com>, 2021. # emnrx <emanuelermancia@gmail.com>, 2022. +# Mau_Restor <restor@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-06-21 15:56+0000\n" -"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Mau_Restor <restor@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" "Language: es_AR\n" @@ -34,7 +35,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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -268,9 +269,8 @@ msgid "Network Peer" msgstr "Profiler de Red" #: core/io/multiplayer_api.cpp scene/animation/animation_player.cpp -#, fuzzy msgid "Root Node" -msgstr "Nombre del nodo raÃz" +msgstr "Nodo raÃz" #: core/io/networked_multiplayer_peer.cpp msgid "Refuse New Connections" @@ -302,7 +302,7 @@ msgstr "" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Array de datos" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" @@ -331,9 +331,8 @@ msgstr "" "No hay suficientes bytes para decodificar bytes, o el formato es inválido." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" -msgstr "Entrada inválida %i (no se transmitió) en la expresión" +msgstr "Entrada inválida %d (no se transmitió) en la expresión" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -362,7 +361,7 @@ msgstr "En la llamada a '%s':" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp msgid "Seed" -msgstr "" +msgstr "Semilla" #: core/math/random_number_generator.cpp #, fuzzy @@ -371,16 +370,15 @@ msgstr "Estado" #: core/message_queue.cpp msgid "Message Queue" -msgstr "" +msgstr "Cola de mesajes" #: core/message_queue.cpp msgid "Max Size (KB)" -msgstr "" +msgstr "Tamaño máximo (KB)" #: core/os/input.cpp -#, fuzzy msgid "Mouse Mode" -msgstr "Modo Mover" +msgstr "Modo Mouse" #: core/os/input.cpp #, fuzzy @@ -409,9 +407,8 @@ msgid "Meta" msgstr "Meta" #: core/os/input_event.cpp -#, fuzzy msgid "Command" -msgstr "Comunidad" +msgstr "Comando" #: core/os/input_event.cpp #, fuzzy @@ -440,7 +437,7 @@ msgstr "Unicode" #: core/os/input_event.cpp msgid "Echo" -msgstr "" +msgstr "Echo" #: core/os/input_event.cpp scene/gui/base_button.cpp msgid "Button Mask" @@ -464,7 +461,7 @@ msgstr "Dobleclick" #: core/os/input_event.cpp msgid "Tilt" -msgstr "" +msgstr "Inclinación" #: core/os/input_event.cpp #, fuzzy @@ -477,9 +474,8 @@ msgid "Pen Inverted" msgstr "Invertir" #: core/os/input_event.cpp -#, fuzzy msgid "Relative" -msgstr "Ajuste Relativo" +msgstr "Relativo" #: core/os/input_event.cpp scene/2d/camera_2d.cpp scene/2d/cpu_particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/interpolated_camera.cpp @@ -537,7 +533,7 @@ msgstr "Velocidad" #: core/os/input_event.cpp msgid "Instrument" -msgstr "" +msgstr "Instrumento" #: core/os/input_event.cpp msgid "Controller Number" @@ -545,7 +541,7 @@ msgstr "Número de Controlador" #: core/os/input_event.cpp msgid "Controller Value" -msgstr "" +msgstr "Valor del controlador" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp @@ -617,9 +613,8 @@ msgstr "Nombre de Directorio de Usuario Personalizado" #: core/project_settings.cpp main/main.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #: platform/uwp/os_uwp.cpp -#, fuzzy msgid "Display" -msgstr "Mostrar Todo" +msgstr "Mostrar" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp @@ -638,17 +633,15 @@ msgstr "Altura" #: core/project_settings.cpp msgid "Always On Top" -msgstr "" +msgstr "Siempre encima" #: core/project_settings.cpp -#, fuzzy msgid "Test Width" -msgstr "Izquierda Ancha" +msgstr "probar ancho" #: core/project_settings.cpp -#, fuzzy msgid "Test Height" -msgstr "Prueba" +msgstr "probar altura" #: core/project_settings.cpp editor/animation_track_editor.cpp #: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp @@ -686,14 +679,12 @@ msgid "Script Templates Search Path" msgstr "Ruta de Búsqueda de Plantillas de Scripts" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Autoload On Startup" -msgstr "Sistema de Control de Versiones" +msgstr "Al iniciar el Sistema de Control de Versiones" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Plugin Name" -msgstr "Control de Versiones" +msgstr "Nombre del sistema de control de versiones" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -702,17 +693,15 @@ msgstr "Entrada" #: core/project_settings.cpp msgid "UI Accept" -msgstr "" +msgstr "Aceptar Interfaz del usuario" #: core/project_settings.cpp -#, fuzzy msgid "UI Select" -msgstr "Seleccionar" +msgstr "Seleccionar Interfaz de Usuario" #: core/project_settings.cpp -#, fuzzy msgid "UI Cancel" -msgstr "Cancelar" +msgstr "Cancelar la interfaz de usuario" #: core/project_settings.cpp #, fuzzy @@ -754,12 +743,11 @@ msgstr "" #: core/project_settings.cpp msgid "UI Home" -msgstr "" +msgstr "Inicio de la interfaz de usuario" #: core/project_settings.cpp -#, fuzzy msgid "UI End" -msgstr "Al Final" +msgstr "Al Final de la interfaz de usuario" #: core/project_settings.cpp main/main.cpp modules/bullet/register_types.cpp #: modules/bullet/space_bullet.cpp scene/2d/physics_body_2d.cpp @@ -817,7 +805,7 @@ msgstr "Filtros" #: core/project_settings.cpp scene/main/viewport.cpp msgid "Sharpen Intensity" -msgstr "" +msgstr "Intensidad de la nitidez" #: core/project_settings.cpp editor/editor_export.cpp editor/editor_node.cpp #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp @@ -867,7 +855,7 @@ msgstr "Nivel de Compresión" #: core/project_settings.cpp msgid "Window Log Size" -msgstr "" +msgstr "medida del registro de la ventana" #: core/project_settings.cpp msgid "Zlib" @@ -890,9 +878,8 @@ msgid "TCP" msgstr "TCP" #: core/register_core_types.cpp -#, fuzzy msgid "Connect Timeout Seconds" -msgstr "Conexiones al método:" +msgstr "Tiempo de espera en segundos de la conexion" #: core/register_core_types.cpp msgid "Packet Peer Stream" @@ -917,9 +904,8 @@ msgid "Resource" msgstr "Recursos" #: core/resource.cpp -#, fuzzy msgid "Local To Scene" -msgstr "Cerrar Escena" +msgstr "Local a la escena" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp @@ -1200,9 +1186,8 @@ msgid "Type" msgstr "Tipo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Setear Handle" +msgstr "En manejo" #: editor/animation_track_editor.cpp #, fuzzy @@ -1353,9 +1338,8 @@ msgid "Time (s):" msgstr "Tiempo (s): " #: editor/animation_track_editor.cpp -#, fuzzy msgid "Position:" -msgstr "Posición del Panel" +msgstr "Posición:" #: editor/animation_track_editor.cpp #, fuzzy @@ -2168,14 +2152,15 @@ msgstr "Favoritos:" msgid "Recent:" msgstr "Recientes:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.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 +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Coincidencias:" @@ -2235,8 +2220,8 @@ msgstr "Buscar Reemplazo de Recurso:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5645,6 +5630,10 @@ msgid "Drag And Drop Selection" msgstr "Selección de GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11932,6 +11921,11 @@ msgid "New Animation" msgstr "Nueva Animación" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrar métodos" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidad:" diff --git a/editor/translations/et.po b/editor/translations/et.po index b355c9c343..1f3fe075df 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -2154,14 +2154,15 @@ msgstr "Lemmikud:" msgid "Recent:" msgstr "Hiljutised:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Otsi:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Vasted:" @@ -2217,8 +2218,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5487,6 +5488,10 @@ msgid "Drag And Drop Selection" msgstr "Kopeeri valik" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11589,6 +11594,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Kustuta animatsioon?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/eu.po b/editor/translations/eu.po index fc753e6cb9..2555dfa8d3 100644 --- a/editor/translations/eu.po +++ b/editor/translations/eu.po @@ -2116,14 +2116,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2179,8 +2180,8 @@ msgstr "Bilatu ordezko baliabidea:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5393,6 +5394,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11467,6 +11472,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Ezabatu animazioa?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/fa.po b/editor/translations/fa.po index f43848b065..a0202d3254 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -2198,14 +2198,15 @@ msgstr "برگزیده‌ها:" msgid "Recent:" msgstr "اخیر:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "جستجو:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "تطبیق‌ها:" @@ -2265,8 +2266,8 @@ msgstr "منبع جایگزینی را جستجو Ú©Ù†:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5549,6 +5550,10 @@ msgid "Drag And Drop Selection" msgstr "انتخاب شده را ØØ°Ù Ú©Ù†" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11962,6 +11967,11 @@ msgid "New Animation" msgstr "تغییر نام انیمیشن" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ØØ§Ù„ت صاÙÛŒ:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index b83c7d11fa..28b4581d60 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -2216,14 +2216,15 @@ msgstr "Suosikit:" msgid "Recent:" msgstr "Viimeaikaiset:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Hae:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Osumat:" @@ -2283,8 +2284,8 @@ msgstr "Etsi korvaava resurssi:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5676,6 +5677,10 @@ msgid "Drag And Drop Selection" msgstr "Ruudukon valinta" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11950,6 +11955,11 @@ msgid "New Animation" msgstr "Uusi animaatio" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Suodata metodeja" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Nopeus:" diff --git a/editor/translations/fil.po b/editor/translations/fil.po index c4e02900d7..4671a2aeaf 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -2088,14 +2088,15 @@ msgstr "Mga Paborito:" msgid "Recent:" msgstr "Kamakailan:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Paghahanap:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2151,8 +2152,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5310,6 +5311,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11321,6 +11326,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Pagulit ng Animation" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index e4f5a2feff..85a3e54c1d 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -2218,14 +2218,15 @@ msgstr "Favoris :" msgid "Recent:" msgstr "Récents :" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Rechercher :" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Correspondances :" @@ -2285,8 +2286,8 @@ msgstr "Recherche ressource de remplacement :" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5675,6 +5676,10 @@ msgid "Drag And Drop Selection" msgstr "Sélection de la GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Apparence" @@ -11916,6 +11921,11 @@ msgid "New Animation" msgstr "Nouvelle animation" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrer les méthodes" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Vitesse :" diff --git a/editor/translations/ga.po b/editor/translations/ga.po index db42dda6ed..17fc0b03fa 100644 --- a/editor/translations/ga.po +++ b/editor/translations/ga.po @@ -2095,14 +2095,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cuardach:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2158,8 +2159,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5304,6 +5305,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11293,6 +11298,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "CrannBeochan" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/gl.po b/editor/translations/gl.po index b42b50e5a7..191093a45d 100644 --- a/editor/translations/gl.po +++ b/editor/translations/gl.po @@ -2196,14 +2196,15 @@ msgstr "Favoritos:" 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 +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.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 +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Coincidencias:" @@ -2263,8 +2264,8 @@ 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5656,6 +5657,10 @@ msgid "Drag And Drop Selection" msgstr "Encadrar Selección" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11904,6 +11909,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrar métodos" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidade:" diff --git a/editor/translations/he.po b/editor/translations/he.po index a89d117ead..2003351f93 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -2167,14 +2167,15 @@ msgstr "מועדפי×:" msgid "Recent:" msgstr "××—×¨×•× ×™×:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "חיפוש:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "הת×מות:" @@ -2234,8 +2235,8 @@ msgstr "חיפוש מש×ב חלופי:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5571,6 +5572,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap מילוי הבחירה" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11959,6 +11964,11 @@ msgstr "×©× ×”× ×¤×©×” חדשה:" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "מ××¤×™×™× ×™ פריט." + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "מהירות (FPS):" diff --git a/editor/translations/hi.po b/editor/translations/hi.po index a598e43071..7faa61ab12 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -2155,14 +2155,15 @@ msgstr "पसंदीदा:" msgid "Recent:" msgstr "हाल ही में किया:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "खोज:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "à¤à¤• जैसा:" @@ -2222,8 +2223,8 @@ msgstr "खोज रिपà¥à¤²à¥‡à¤¸à¤®à¥‡à¤‚ट संसाधन:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5576,6 +5577,10 @@ msgid "Drag And Drop Selection" msgstr "सà¤à¥€ खंड" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11760,6 +11765,11 @@ msgid "New Animation" msgstr "à¤à¤¨à¤¿à¤®à¥‡à¤¶à¤¨ लूप" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "à¤à¤¨à¤¿à¤®à¥‡à¤¶à¤¨" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index 61aeaeeb10..6d2b3b07da 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -6,12 +6,13 @@ # Patik <patrikfs5@gmail.com>, 2019. # Nikola Bunjevac <nikola.bunjevac@gmail.com>, 2019, 2020. # LeoClose <leoclose575@gmail.com>, 2020, 2021. +# Filip <fhomolka@protonmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2021-08-13 19:05+0000\n" -"Last-Translator: LeoClose <leoclose575@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Filip <fhomolka@protonmail.com>\n" "Language-Team: Croatian <https://hosted.weblate.org/projects/godot-engine/" "godot/hr/>\n" "Language: hr\n" @@ -19,11 +20,11 @@ msgstr "" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.8-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" -msgstr "" +msgstr "UpravljaÄki program za Tablet" #: core/bind/core_bind.cpp msgid "Clipboard" @@ -39,73 +40,77 @@ msgid "Exit Code" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "V-Sync Enabled" -msgstr "Omogući" +msgstr "V-Sync Omogućen" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" -msgstr "" +msgstr "V-Sync preko Kompozitora" #: core/bind/core_bind.cpp main/main.cpp msgid "Delta Smoothing" -msgstr "" +msgstr "Delta Ublažavanje" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode" -msgstr "" +msgstr "NaÄin niske upotrebe procesora" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" -msgstr "" +msgstr "Stanje mirovanja u naÄinu koriÅ¡tenja niskog procesora (μsec)" #: core/bind/core_bind.cpp main/main.cpp platform/uwp/os_uwp.cpp msgid "Keep Screen On" -msgstr "" +msgstr "Zadrži zaslon ukljuÄenim" #: core/bind/core_bind.cpp -#, fuzzy msgid "Min Window Size" -msgstr "Glavna skripta:" +msgstr "Min. veliÄina prozora" #: core/bind/core_bind.cpp -#, fuzzy msgid "Max Window Size" -msgstr "Glavna skripta:" +msgstr "Maks. veliÄina prozora" #: core/bind/core_bind.cpp msgid "Screen Orientation" -msgstr "" +msgstr "Orijentacija zaslona" #: core/bind/core_bind.cpp core/project_settings.cpp main/main.cpp #: platform/uwp/os_uwp.cpp +#, fuzzy msgid "Window" -msgstr "" +msgstr "Prozor" #: core/bind/core_bind.cpp core/project_settings.cpp +#, fuzzy msgid "Borderless" -msgstr "" +msgstr "Bez obruba" #: core/bind/core_bind.cpp +#, fuzzy msgid "Per Pixel Transparency Enabled" -msgstr "" +msgstr "Omogućena prozirnost po pikselu" #: core/bind/core_bind.cpp core/project_settings.cpp +#, fuzzy msgid "Fullscreen" -msgstr "" +msgstr "Cijeli zaslon" #: core/bind/core_bind.cpp +#, fuzzy msgid "Maximized" -msgstr "" +msgstr "Maksimiziran" #: core/bind/core_bind.cpp +#, fuzzy msgid "Minimized" -msgstr "" +msgstr "Minimiziran" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp +#, fuzzy msgid "Resizable" -msgstr "" +msgstr "Mogućnost promjene veliÄine" #: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp #: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp @@ -114,7 +119,7 @@ msgstr "" #: scene/resources/default_theme/default_theme.cpp #, fuzzy msgid "Position" -msgstr "Stvori" +msgstr "Pozicija" #: core/bind/core_bind.cpp core/project_settings.cpp editor/editor_settings.cpp #: main/main.cpp modules/gridmap/grid_map.cpp @@ -125,8 +130,9 @@ msgstr "Stvori" #: scene/resources/primitive_meshes.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp #: scene/resources/visual_shader.cpp servers/visual_server.cpp +#, fuzzy msgid "Size" -msgstr "" +msgstr "VeliÄina" #: core/bind/core_bind.cpp msgid "Endian Swap" @@ -135,25 +141,27 @@ msgstr "" #: core/bind/core_bind.cpp #, fuzzy msgid "Editor Hint" -msgstr "(Editor Onemogućen)" +msgstr "Savjet Urednika" #: core/bind/core_bind.cpp +#, fuzzy msgid "Print Error Messages" -msgstr "" +msgstr "Ispis poruka o pogreÅ¡kama" #: core/bind/core_bind.cpp #, fuzzy msgid "Iterations Per Second" -msgstr "NaÄin Interpolacije" +msgstr "Iteracije u sekundi" #: core/bind/core_bind.cpp +#, fuzzy msgid "Target FPS" -msgstr "" +msgstr "Ciljani FPS" #: core/bind/core_bind.cpp #, fuzzy msgid "Time Scale" -msgstr "Dubina" +msgstr "Vremenska skala" #: core/bind/core_bind.cpp main/main.cpp msgid "Physics Jitter Fix" @@ -2125,14 +2133,15 @@ msgstr "Favoriti:" msgid "Recent:" msgstr "Nedavno:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Pretraga:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Podudaranja:" @@ -2192,8 +2201,8 @@ msgstr "Traži zamjenu resursa:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5395,6 +5404,10 @@ msgid "Drag And Drop Selection" msgstr "IzbriÅ¡i Odabir" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11479,6 +11492,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Obrisati Animaciju?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index 9f0d894b2a..cc7024a260 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -2226,14 +2226,15 @@ msgstr "Kedvencek:" msgid "Recent:" msgstr "Legutóbbi:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Keresés:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Egyezések:" @@ -2293,8 +2294,8 @@ msgstr "Csere Forrás Keresése:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5684,6 +5685,10 @@ msgid "Drag And Drop Selection" msgstr "Kijelölés Keretezése" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11933,6 +11938,11 @@ msgid "New Animation" msgstr "Új animáció" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Metódusok szűrése" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/id.po b/editor/translations/id.po index 24547a7464..8c447326e3 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -39,13 +39,14 @@ # ProgrammerIndonesia 44 <elo.jhy@gmail.com>, 2022. # Rizky Ramadhan <rizkyterm@gmail.com>, 2022. # Primananda Kurnia <primakurnia71@gmail.com>, 2022. +# FellowMustard <rachmawanng33@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-09 21:12+0000\n" -"Last-Translator: yusuf afandi <afandi.yusuf.04@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: FellowMustard <rachmawanng33@gmail.com>\n" "Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/" "godot/id/>\n" "Language: id\n" @@ -53,7 +54,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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -1206,7 +1207,7 @@ msgstr "Atur Pegangan" #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp msgid "Stream" -msgstr "" +msgstr "Arus" #: editor/animation_track_editor.cpp #, fuzzy @@ -2158,14 +2159,15 @@ msgstr "Favorit:" msgid "Recent:" msgstr "Saat ini:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cari:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Kecocokan:" @@ -2225,8 +2227,8 @@ msgstr "Cari Resource Pengganti:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5616,6 +5618,10 @@ msgid "Drag And Drop Selection" msgstr "Isi Seleksi GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Penampilan" @@ -11849,6 +11855,11 @@ msgid "New Animation" msgstr "Animasi Baru" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filter method" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Kecepatan:" diff --git a/editor/translations/is.po b/editor/translations/is.po index b7eb0e4b88..7a990ebd6b 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -2140,14 +2140,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2203,8 +2204,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5381,6 +5382,10 @@ msgid "Drag And Drop Selection" msgstr "Allt úrvalið" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11444,6 +11449,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Stillið breyting á:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/it.po b/editor/translations/it.po index 36757b891d..1d89d28a99 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -69,13 +69,15 @@ # Federico Caprini <caprinifede@gmail.com>, 2022. # Alessandro Casalino <alessandro.casalino93@gmail.com>, 2022. # conecat <ilgrandemax190@gmail.com>, 2022. +# Gico2006 <gradaellig@protonmail.com>, 2022. +# ale piccia <picciatialessio2@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-04 05:16+0000\n" -"Last-Translator: conecat <ilgrandemax190@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: ale piccia <picciatialessio2@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -83,7 +85,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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -374,7 +376,6 @@ msgid "Not enough bytes for decoding bytes, or invalid format." msgstr "Byte insufficienti per decodificarli o formato non valido." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" msgstr "Input %d non valido (assente) nell'espressione" @@ -425,7 +426,7 @@ msgstr "Modalità Mouse" #: core/os/input.cpp msgid "Use Accumulated Input" -msgstr "Usa Input Accumulato" +msgstr "Usa Input Accumulati" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -671,14 +672,12 @@ msgid "Always On Top" msgstr "Sempre In Primo Piano" #: core/project_settings.cpp -#, fuzzy msgid "Test Width" -msgstr "Larghezza Test" +msgstr "Test Larghezza" #: core/project_settings.cpp -#, fuzzy msgid "Test Height" -msgstr "Altezza Test" +msgstr "Test Altezza" #: core/project_settings.cpp editor/animation_track_editor.cpp #: editor/editor_audio_buses.cpp main/main.cpp servers/audio_server.cpp @@ -713,14 +712,12 @@ msgid "Script Templates Search Path" msgstr "Percorso di Ricerca dei Template di Script" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Autoload On Startup" -msgstr "Autocaricamento all'Avvio" +msgstr "Caricamento automatico del controllo di versione all'avvio" #: core/project_settings.cpp -#, fuzzy msgid "Version Control Plugin Name" -msgstr "Controllo della versione" +msgstr "Nome del plugin di controllo della versione" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -1210,14 +1207,12 @@ msgid "Type" msgstr "Tipo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Imposta Maniglia" +msgstr "In gestione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" -msgstr "Imposta Maniglia" +msgstr "Non gestire" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1406,19 +1401,16 @@ msgid "Stream:" msgstr "Stream" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Start (s):" -msgstr "Riavvia (s):" +msgstr "inizia:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "End (s):" -msgstr "Fade In (s):" +msgstr "finisci:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation Clip:" -msgstr "Animazioni:" +msgstr "clip delle animazioni:" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -2173,14 +2165,15 @@ msgstr "Preferiti:" msgid "Recent:" msgstr "Recenti:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cerca:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Corrispondenze:" @@ -2240,8 +2233,8 @@ msgstr "Cerca risorsa di rimpiazzo:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2250,7 +2243,7 @@ msgstr "Apri" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "proprietario di: %s (Totale: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2607,9 +2600,8 @@ msgid "There is no '%s' file." msgstr "File \"%s\" assente." #: editor/editor_audio_buses.cpp -#, fuzzy msgid "Layout:" -msgstr "Disposizione" +msgstr "" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -2850,9 +2842,8 @@ msgid "Save PCK" msgstr "Salva PCK" #: editor/editor_export.cpp -#, fuzzy msgid "Cannot create file \"%s\"." -msgstr "Impossibile creare la cartella." +msgstr "impossibile creare il file \"%s\"." #: editor/editor_export.cpp #, fuzzy @@ -2860,9 +2851,8 @@ msgid "Failed to export project files." msgstr "Impossibile esportare i file del progetto" #: editor/editor_export.cpp -#, fuzzy msgid "Can't open file to read from path \"%s\"." -msgstr "Impossibile aprire il file in scrittura:" +msgstr "impossibile aprire file da leggere dalla path \"%s\"." #: editor/editor_export.cpp #, fuzzy @@ -5582,6 +5572,10 @@ msgid "Drag And Drop Selection" msgstr "Selezione GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Aspetto" @@ -11739,6 +11733,11 @@ msgid "New Animation" msgstr "Nuova Animazione" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Modalità di filtraggio" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocità :" diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 5c6358a4c4..a40939f777 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -2180,14 +2180,15 @@ msgstr "ãŠæ°—ã«å…¥ã‚Š:" msgid "Recent:" msgstr "最近:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "検索:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "一致:" @@ -2247,8 +2248,8 @@ msgstr "ç½®æ›ã™ã‚‹ãƒªã‚½ãƒ¼ã‚¹ã‚’検索:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5582,6 +5583,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap ã®é¸æŠž" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "外観" @@ -11777,6 +11782,11 @@ msgid "New Animation" msgstr "æ–°è¦ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "メソッドを絞り込む" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "速度:" diff --git a/editor/translations/ka.po b/editor/translations/ka.po index f67e7c0bdd..ae98d76c31 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -2195,14 +2195,15 @@ msgstr "სáƒáƒ§áƒ•áƒáƒ ლები:" msgid "Recent:" msgstr "ბáƒáƒšáƒ:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "ძებნáƒ:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "დáƒáƒ›áƒ—ხვევები:" @@ -2264,8 +2265,8 @@ msgstr "ჩáƒáƒ›áƒœáƒáƒªáƒ•ლებელი რესურსის ძიá #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5510,6 +5511,10 @@ msgid "Drag And Drop Selection" msgstr "ყველრმáƒáƒœáƒ˜áƒ¨áƒœáƒ•áƒ" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11727,6 +11732,11 @@ msgid "New Animation" msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ áƒáƒžáƒ¢áƒ˜áƒ›áƒ˜áƒ–áƒáƒªáƒ˜áƒ" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ფუნქციები:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/km.po b/editor/translations/km.po index 2da1ccac99..4141c021e2 100644 --- a/editor/translations/km.po +++ b/editor/translations/km.po @@ -2071,14 +2071,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2134,8 +2135,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5269,6 +5270,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11240,6 +11245,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Key(s) ដែលបានជ្រើសស្ទួន" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/ko.po b/editor/translations/ko.po index ff2f4ecb80..af0b7e99a5 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -2123,14 +2123,15 @@ msgstr "ì¦ê²¨ì°¾ê¸°:" msgid "Recent:" msgstr "최근 기ë¡:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "검색:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "ì¼ì¹˜í•¨:" @@ -2190,8 +2191,8 @@ msgstr "대체 리소스 검색:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5482,6 +5483,10 @@ msgid "Drag And Drop Selection" msgstr "그리드맵 ì„ íƒ" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "모습" @@ -11681,6 +11686,11 @@ msgid "New Animation" msgstr "새 ì• ë‹ˆë©”ì´ì…˜" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "메서드 í•„í„°" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "ì†ë„:" diff --git a/editor/translations/lt.po b/editor/translations/lt.po index 8daa544db9..3b1140192a 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -2178,14 +2178,15 @@ msgstr "MÄ—gstamiausi:" msgid "Recent:" msgstr "Naujausi:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "IeÅ¡koti:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2241,8 +2242,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5487,6 +5488,10 @@ msgid "Drag And Drop Selection" msgstr "Visas Pasirinkimas" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11716,6 +11721,11 @@ msgid "New Animation" msgstr "Animacija" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrai..." + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 2dabcb40bf..f134fd5b48 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -2173,14 +2173,15 @@ msgstr "FavorÄ«ti:" msgid "Recent:" msgstr "Nesenie:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "MeklÄ“t:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "SakritÄ«bas:" @@ -2240,8 +2241,8 @@ msgstr "MeklÄ“t aizstÄjÄ“ja resursu:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5558,6 +5559,10 @@ msgid "Drag And Drop Selection" msgstr "Režģkartes izvÄ“le" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11644,6 +11649,11 @@ msgid "New Animation" msgstr "Jauna animÄcija" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "animÄcija" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/mk.po b/editor/translations/mk.po index ef9a504af6..a3390bd895 100644 --- a/editor/translations/mk.po +++ b/editor/translations/mk.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2022-06-29 10:04+0000\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" "Last-Translator: Kristijan Fremen Velkovski <me@krisfremen.com>\n" "Language-Team: Macedonian <https://hosted.weblate.org/projects/godot-engine/" "godot/mk/>\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n==1 || n%10==1 ? 0 : 1;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -1255,7 +1255,7 @@ msgstr "" #: editor/animation_track_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Functions:" -msgstr "" +msgstr "Фукнции:" #: editor/animation_track_editor.cpp msgid "Audio Clips:" @@ -1358,33 +1358,33 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Continuous" -msgstr "" +msgstr "Континуирана" #: editor/animation_track_editor.cpp msgid "Discrete" -msgstr "" +msgstr "ДиÑкретна" #: editor/animation_track_editor.cpp msgid "Trigger" -msgstr "" +msgstr "Чкрапало" #: editor/animation_track_editor.cpp scene/3d/baked_lightmap.cpp msgid "Capture" -msgstr "" +msgstr "Снимање" #: editor/animation_track_editor.cpp msgid "Nearest" -msgstr "" +msgstr "ÐајблиÑку" #: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp #: editor/property_editor.cpp scene/2d/physics_body_2d.cpp #: scene/3d/physics_body.cpp msgid "Linear" -msgstr "" +msgstr "Линеарна" #: editor/animation_track_editor.cpp msgid "Cubic" -msgstr "" +msgstr "Кубни" #: editor/animation_track_editor.cpp msgid "Clamp Loop Interp" @@ -1462,7 +1462,7 @@ msgstr "" #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Create" -msgstr "" +msgstr "Создади" #: editor/animation_track_editor.cpp msgid "Anim Insert" @@ -1763,7 +1763,7 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Clean-Up" -msgstr "" +msgstr "ОчиÑти" #: editor/animation_track_editor.cpp msgid "Scale Ratio:" @@ -1840,7 +1840,7 @@ msgstr "" #: editor/code_editor.cpp msgid "Replace" -msgstr "" +msgstr "Замени" #: editor/code_editor.cpp msgid "Replace All" @@ -1853,7 +1853,7 @@ msgstr "" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Стандардно" #: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" @@ -1879,7 +1879,7 @@ msgstr "" #: editor/code_editor.cpp modules/gdscript/gdscript.cpp msgid "Warnings" -msgstr "" +msgstr "Предупредувања" #: editor/code_editor.cpp msgid "Line and column numbers." @@ -1921,7 +1921,7 @@ msgstr "" #: editor/plugins/item_list_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp msgid "Add" -msgstr "" +msgstr "Додади" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp @@ -1931,7 +1931,7 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" -msgstr "" +msgstr "Избриши" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" @@ -1948,11 +1948,11 @@ msgstr "" #: editor/connections_dialog.cpp scene/3d/room_manager.cpp #: servers/visual_server.cpp msgid "Advanced" -msgstr "" +msgstr "Ðапредно" #: editor/connections_dialog.cpp msgid "Deferred" -msgstr "" +msgstr "Одложено" #: editor/connections_dialog.cpp msgid "" @@ -2080,14 +2080,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2143,8 +2144,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5286,6 +5287,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11268,6 +11273,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "СвојÑтва на анимацијата." + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/ml.po b/editor/translations/ml.po index 1b5bc9e68f..4cb867c040 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -2090,14 +2090,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2153,8 +2154,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5302,6 +5303,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11290,6 +11295,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ചലനം à´šàµà´±àµà´±àµ½" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/mr.po b/editor/translations/mr.po index 8dffed5d4e..47b8bd3f86 100644 --- a/editor/translations/mr.po +++ b/editor/translations/mr.po @@ -2091,14 +2091,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2154,8 +2155,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5292,6 +5293,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11278,6 +11283,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "अâ€à¥…निमेशन टà¥à¤°à¥€" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/ms.po b/editor/translations/ms.po index caef354c6c..055e18e0bc 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -2101,14 +2101,15 @@ msgstr "Kegemaran:" msgid "Recent:" msgstr "Terkini:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Cari:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Padanan:" @@ -2168,8 +2169,8 @@ msgstr "Cari Penggantian Sumber:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5551,6 +5552,10 @@ msgid "Drag And Drop Selection" msgstr "Semua Pilihan" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11733,6 +11738,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Padam Animasi?" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index 68de0259c2..dac373fdc7 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -2205,14 +2205,15 @@ msgstr "Favoritter:" msgid "Recent:" msgstr "Nylige:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Søk:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Treff:" @@ -2274,8 +2275,8 @@ msgstr "Søk Erstatningsressurs:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5735,6 +5736,10 @@ msgid "Drag And Drop Selection" msgstr "Slett Valgte" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12215,6 +12220,11 @@ msgstr "Animasjon" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "Lim inn Noder" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "Hastighet (FPS):" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 756bf78add..40e0ddfb78 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -2270,14 +2270,15 @@ msgstr "Favorieten:" msgid "Recent:" msgstr "Onlangs:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Zoeken:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Overeenkomsten:" @@ -2337,8 +2338,8 @@ msgstr "Bronvervanging zoeken:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5728,6 +5729,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap-selectie vullen" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12068,6 +12073,11 @@ msgid "New Animation" msgstr "Nieuwe animatie" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filter methoden" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Snelheid:" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 264d623676..180abba988 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -2176,14 +2176,15 @@ msgstr "Ulubione:" msgid "Recent:" msgstr "Ostatnie:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Szukaj:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "PasujÄ…ce:" @@ -2243,8 +2244,8 @@ msgstr "Szukaj zastÄ™pczego zasobu:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5629,6 +5630,10 @@ msgid "Drag And Drop Selection" msgstr "Wybór GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "WyglÄ…d" @@ -11902,6 +11907,11 @@ msgid "New Animation" msgstr "Nowa animacja" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtruj metody" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Szybkość:" diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 5c33524652..337e5af5c0 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -2165,14 +2165,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2228,8 +2229,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5474,6 +5475,10 @@ msgid "Drag And Drop Selection" msgstr "Yar, Blow th' Selected Down!" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11705,6 +11710,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Paste yer Node" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/pt.po b/editor/translations/pt.po index 0b2fa35ae5..db7171b3c6 100644 --- a/editor/translations/pt.po +++ b/editor/translations/pt.po @@ -25,13 +25,14 @@ # El_ExpertPlayer <xpertnathan37@gmail.com>, 2022. # Esdras Caleb Oliveira Silva <acheicaleb@gmail.com>, 2022. # Ednaldo Pereira Confia <filat51823@storypo.com>, 2022. +# Zé Beato Página Oficial <zebeato@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-11 21:32+0000\n" -"Last-Translator: Ednaldo Pereira Confia <filat51823@storypo.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Zé Beato Página Oficial <zebeato@gmail.com>\n" "Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/" "godot/pt/>\n" "Language: pt\n" @@ -2109,14 +2110,15 @@ msgstr "Favoritos:" 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 +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Procurar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Correspondências:" @@ -2176,8 +2178,8 @@ msgstr "Procurar Recurso de substituição:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2931,9 +2933,8 @@ msgid "The given export path doesn't exist." msgstr "O caminho de exportação não existe:" #: editor/editor_export.cpp platform/javascript/export/export.cpp -#, fuzzy msgid "Template file not found: \"%s\"." -msgstr "Ficheiro Modelo não encontrado:" +msgstr "Ficheiro Modelo não encontrado" #: editor/editor_export.cpp #, fuzzy @@ -5538,6 +5539,10 @@ msgid "Drag And Drop Selection" msgstr "Seleção de GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Aparência" @@ -11721,6 +11726,11 @@ msgid "New Animation" msgstr "Nova Animação" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Métodos de filtro" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidade:" diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index a812335e4b..5d2b642352 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -142,13 +142,15 @@ # lucas rossy brasil coelho <lucasrossy270@gmail.com>, 2022. # Kaycke <kaycke@ymail.com>, 2022. # Ednaldo Pereira Confia <filat51823@storypo.com>, 2022. +# Mauricio <mauricio.fidalgo1@gmail.com>, 2022. +# Felipe Kinoshita <kinofhek@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2022-07-16 06:20+0000\n" -"Last-Translator: Cearaj <pmoraisleal@gmail.com>\n" +"PO-Revision-Date: 2022-07-27 13:26+0000\n" +"Last-Translator: Felipe Kinoshita <kinofhek@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -361,7 +363,7 @@ msgstr "Página lida adiante" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" -msgstr "Modo de bloqueio ativado" +msgstr "Modo de Bloqueio Ativado" #: core/io/http_client.cpp msgid "Connection" @@ -579,9 +581,8 @@ msgid "Pressure" msgstr "Pressão" #: core/os/input_event.cpp -#, fuzzy msgid "Pen Inverted" -msgstr "Inverter" +msgstr "Caneta Invertida (\"Borracha\")" #: core/os/input_event.cpp msgid "Relative" @@ -1120,7 +1121,7 @@ msgstr "Máximo de luzes renderizáveis" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Reflections" -msgstr "Reflexões máximas renderizáveis" +msgstr "Máximo de Reflexões Renderizáveis" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Lights Per Object" @@ -1278,14 +1279,12 @@ msgid "Type" msgstr "Tipo" #: editor/animation_track_editor.cpp -#, fuzzy msgid "In Handle" -msgstr "Definir Manipulador" +msgstr "Manipulador de Entrada" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out Handle" -msgstr "Definir Manipulador" +msgstr "Manipulador de SaÃda" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1296,11 +1295,11 @@ msgstr "Fluxo" #: editor/animation_track_editor.cpp msgid "Start Offset" -msgstr "Iniciar deslocamento" +msgstr "Deslocamento Inicial" #: editor/animation_track_editor.cpp msgid "End Offset" -msgstr "Terminar deslocamento" +msgstr "Deslocamento Final" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #: editor/import/resource_importer_scene.cpp @@ -1314,7 +1313,7 @@ msgstr "Animação" #: editor/animation_track_editor.cpp msgid "Easing" -msgstr "Facilitar Entrada-SaÃda" +msgstr "Suavização" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1453,18 +1452,16 @@ msgid "(Invalid, expected type: %s)" msgstr "(Inválido, tipo esperado: %s)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing:" -msgstr "Facilitar Entrada-SaÃda:" +msgstr "Suavizar:" #: editor/animation_track_editor.cpp msgid "In-Handle:" -msgstr "Definir Manipulador:" +msgstr "Manipulador de Entrada:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Out-Handle:" -msgstr "Definir Manipulador:" +msgstr "Manipulador de SaÃda:" #: editor/animation_track_editor.cpp msgid "Stream:" @@ -2110,7 +2107,7 @@ msgstr "" #: editor/connections_dialog.cpp scene/resources/texture.cpp msgid "Oneshot" -msgstr "Oneshot" +msgstr "Só Uma Vez" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." @@ -2229,14 +2226,15 @@ msgstr "Favoritos:" 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 +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Pesquisar:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Correspondências:" @@ -2296,8 +2294,8 @@ msgstr "Buscar Recurso para Substituição:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2420,7 +2418,7 @@ msgstr "Desenvolvedor-chefe" #: editor/editor_about.cpp msgctxt "Job Title" msgid "Project Manager" -msgstr "Gerenciador de Projeto" +msgstr "Gestor de Projeto" #: editor/editor_about.cpp msgid "Developers" @@ -2993,7 +2991,7 @@ msgstr "64 Bits" #: editor/editor_export.cpp msgid "Embed PCK" -msgstr "Incorporar PCK" +msgstr "PCK Incorporado" #: editor/editor_export.cpp platform/osx/export/export.cpp msgid "Texture Format" @@ -3016,9 +3014,8 @@ msgid "ETC2" msgstr "ETC2" #: editor/editor_export.cpp -#, fuzzy msgid "No BPTC Fallbacks" -msgstr "Sem Fallbacks do BPTC" +msgstr "Sem Fallbacks para imagens BPTC" #: editor/editor_export.cpp platform/android/export/export_plugin.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -3673,9 +3670,8 @@ msgid "Property:" msgstr "Propriedade:" #: editor/editor_inspector.cpp editor/editor_spin_slider.cpp -#, fuzzy msgid "Label" -msgstr "Etiqueta" +msgstr "Rótulo" #: editor/editor_inspector.cpp editor/editor_spin_slider.cpp #: scene/resources/default_theme/default_theme.cpp @@ -4391,11 +4387,11 @@ msgstr "Abas de Cena" #: editor/editor_node.cpp msgid "Always Show Close Button" -msgstr "Sempre mostrar o botão de fechar." +msgstr "Sempre Exibir o Botão de Fechar" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Resize If Many Tabs" -msgstr "Redimensionar se houver muitas guias" +msgstr "Redimensionar se Houver Muitas Guias" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Minimum Width" @@ -5102,7 +5098,7 @@ msgstr "Tempo Médio (ms)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "Frame %" +msgstr "Quadro %" #: editor/editor_profiler.cpp msgid "Physics Frame %" @@ -5147,12 +5143,11 @@ msgstr "Depurador" #: editor/editor_profiler.cpp msgid "Profiler Frame History Size" -msgstr "" +msgstr "Tamanho de histórico disponÃvel no \"Profiler\"" #: editor/editor_profiler.cpp -#, fuzzy msgid "Profiler Frame Max Functions" -msgstr "Renomear Função" +msgstr "Máximo de funções por quadro no \"Profiler\"" #: editor/editor_properties.cpp msgid "Edit Text:" @@ -5285,20 +5280,17 @@ msgstr "Novo %s" #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: modules/visual_script/visual_script_yield_nodes.cpp -#, fuzzy msgid "Base Type" -msgstr "Mudar Tipo Base" +msgstr "Tipo Base" #: editor/editor_resource_picker.cpp -#, fuzzy msgid "Edited Resource" -msgstr "Adicionar Recurso" +msgstr "Recurso Editado" #: editor/editor_resource_picker.cpp scene/gui/line_edit.cpp #: scene/gui/slider.cpp scene/gui/spin_box.cpp -#, fuzzy msgid "Editable" -msgstr "Item Editável" +msgstr "Editável" #: editor/editor_resource_picker.cpp editor/property_editor.cpp msgid "New Script" @@ -5324,9 +5316,8 @@ msgstr "" "predefinição existente como executável." #: editor/editor_run_native.cpp -#, fuzzy msgid "Project Run" -msgstr "Projeto" +msgstr "Executar Projeto" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." @@ -5353,73 +5344,68 @@ msgid "Did you forget the '_run' method?" msgstr "Você esqueceu o método '_run'?" #: editor/editor_settings.cpp -#, fuzzy msgid "Editor Language" -msgstr "Layout do Editor" +msgstr "Linguagem do Editor" #: editor/editor_settings.cpp -#, fuzzy msgid "Display Scale" -msgstr "Exibir Tudo" +msgstr "Escala de Exibição" #: editor/editor_settings.cpp msgid "Custom Display Scale" -msgstr "" +msgstr "Escala de Exibição Customizada" #: editor/editor_settings.cpp msgid "Main Font Size" -msgstr "" +msgstr "Tamanho de Fonte Principal" #: editor/editor_settings.cpp msgid "Code Font Size" -msgstr "" +msgstr "Tamanho de Fonte (Tipo) no Código" #: editor/editor_settings.cpp msgid "Font Antialiased" -msgstr "" +msgstr "Fonte Com Serrilhado Suavizado" #: editor/editor_settings.cpp msgid "Font Hinting" -msgstr "" +msgstr "Suavização de Fonte" #: editor/editor_settings.cpp -#, fuzzy msgid "Main Font" -msgstr "Cena Principal" +msgstr "Fonte Principal" #: editor/editor_settings.cpp msgid "Main Font Bold" -msgstr "" +msgstr "Fonte Principal (Negrito)" #: editor/editor_settings.cpp -#, fuzzy msgid "Code Font" -msgstr "Adicionar Ponto de Nó" +msgstr "Fonte para Código" #: editor/editor_settings.cpp msgid "Dim Editor On Dialog Popup" -msgstr "" +msgstr "Escurecer o Editor ao Abir Janela Popup" #: editor/editor_settings.cpp main/main.cpp msgid "Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Tempo de Espera em Modo de Hibernação (µseg)" #: editor/editor_settings.cpp msgid "Unfocused Low Processor Mode Sleep (µsec)" -msgstr "" +msgstr "Tempo de Espera em Modo de Hibernação Quando Fora de Foco (µseg)" #: editor/editor_settings.cpp -#, fuzzy msgid "Separate Distraction Mode" -msgstr "Modo Sem Distrações" +msgstr "Modo \"Sem Distrações\" Desacoplado" #: editor/editor_settings.cpp msgid "Automatically Open Screenshots" -msgstr "" +msgstr "Abrir Capturas de Tela Automaticamente" #: editor/editor_settings.cpp msgid "Max Array Dictionary Items Per Page" -msgstr "" +msgstr "Máximo de Itens em Arrays Dicionários Por Página" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp scene/gui/control.cpp @@ -5433,59 +5419,51 @@ msgstr "Predefinição" #: editor/editor_settings.cpp msgid "Icon And Font Color" -msgstr "" +msgstr "Cor da Fonte e do Ãcone" #: editor/editor_settings.cpp -#, fuzzy msgid "Base Color" -msgstr "Cores" +msgstr "Cor Base" #: editor/editor_settings.cpp -#, fuzzy msgid "Accent Color" -msgstr "Escolher Cor" +msgstr "Cor de Destaque" #: editor/editor_settings.cpp scene/resources/environment.cpp msgid "Contrast" -msgstr "" +msgstr "Contraste" #: editor/editor_settings.cpp msgid "Relationship Line Opacity" -msgstr "" +msgstr "Opacidade da Linha de Relacionamento" #: editor/editor_settings.cpp -#, fuzzy msgid "Highlight Tabs" -msgstr "Salvando mapas de luz" +msgstr "Abas de Destaque" #: editor/editor_settings.cpp -#, fuzzy msgid "Border Size" -msgstr "Pixels de Borda" +msgstr "Tamanho da Borda" #: editor/editor_settings.cpp msgid "Use Graph Node Headers" -msgstr "" +msgstr "Utilizar Cabeçalhos de Nós para Gráficos" #: editor/editor_settings.cpp -#, fuzzy msgid "Additional Spacing" -msgstr "Loop da Animação" +msgstr "Espaçamento Adicional" #: editor/editor_settings.cpp -#, fuzzy msgid "Custom Theme" -msgstr "Tema do Editor" +msgstr "Tema Personalizado" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Script Button" -msgstr "Botão direito da roda" +msgstr "Botão de Exibir Script" #: editor/editor_settings.cpp -#, fuzzy msgid "Directories" -msgstr "Direções" +msgstr "Diretórios" #: editor/editor_settings.cpp msgid "Autoscan Project Path" @@ -5496,23 +5474,20 @@ msgid "Default Project Path" msgstr "Caminho Padrão do Projeto" #: editor/editor_settings.cpp -#, fuzzy msgid "On Save" -msgstr "Salvar" +msgstr "Ao Salvar" #: editor/editor_settings.cpp -#, fuzzy msgid "Compress Binary Resources" -msgstr "Copiar Recurso" +msgstr "Comprimir Recursos Binários" #: editor/editor_settings.cpp msgid "Safe Save On Backup Then Rename" -msgstr "" +msgstr "Salvar de Forma Segura Como Backup e Então Renomear" #: editor/editor_settings.cpp -#, fuzzy msgid "File Dialog" -msgstr "Diálogo XForm" +msgstr "Janela de Arquivo" #: editor/editor_settings.cpp msgid "Thumbnail Size" @@ -5520,82 +5495,73 @@ msgstr "Tamanho da Miniatura" #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "Docas" #: editor/editor_settings.cpp -#, fuzzy msgid "Scene Tree" -msgstr "Edição da Ãrvore de Cena" +msgstr "Ãrvore de Cena" #: editor/editor_settings.cpp msgid "Start Create Dialog Fully Expanded" -msgstr "" +msgstr "Iniciar Dialogo de Criação Expandido por Completo" #: editor/editor_settings.cpp -#, fuzzy msgid "Always Show Folders" -msgstr "Sempre Mostrar Grade" +msgstr "Sempre Exibir Pastas" #: editor/editor_settings.cpp -#, fuzzy msgid "Property Editor" -msgstr "Editor de Grupos" +msgstr "Editor de Propriedades" #: editor/editor_settings.cpp msgid "Auto Refresh Interval" -msgstr "" +msgstr "Intervalo de Atualização Automática" #: editor/editor_settings.cpp -#, fuzzy msgid "Subresource Hue Tint" -msgstr "Sub-Recursos" +msgstr "Tom de Coloração para Sub-Recursos" #: editor/editor_settings.cpp -#, fuzzy msgid "Color Theme" -msgstr "Tema do Editor" +msgstr "Tema de Cores" #: editor/editor_settings.cpp scene/3d/label_3d.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Line Spacing" -msgstr "" +msgstr "Espaçamento de Linha" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp #: modules/gdscript/editor/gdscript_highlighter.cpp -#, fuzzy msgid "Highlighting" -msgstr "Iluminação direta" +msgstr "Destacando" #: editor/editor_settings.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Syntax Highlighting" -msgstr "Realce de sintaxe" +msgstr "Destaque de Sintaxe" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Highlight All Occurrences" -msgstr "" +msgstr "Destaque de Todas as Ocorrências" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Highlight Current Line" -msgstr "" +msgstr "Destaque da Linha Atual" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp msgid "Highlight Type Safe Lines" -msgstr "" +msgstr "Destaque de Linhas de Tipo Seguro" #: editor/editor_settings.cpp -#, fuzzy msgid "Indent" -msgstr "Recuar Esquerda" +msgstr "Indentar" #: editor/editor_settings.cpp editor/plugins/script_text_editor.cpp msgid "Auto Indent" msgstr "Auto Recuar" #: editor/editor_settings.cpp -#, fuzzy msgid "Convert Indent On Save" -msgstr "Converter recuo para espaços" +msgstr "Converter Indentação Ao Salvar" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Draw Tabs" @@ -5614,144 +5580,139 @@ msgstr "Navegação" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Smooth Scrolling" -msgstr "" +msgstr "Rolagem Suave" #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "V Scroll Speed" -msgstr "" +msgstr "Velocidade de Rolagem Vertical" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Minimap" -msgstr "Mostrar Origem" +msgstr "Exibir Mini-Mapa" #: editor/editor_settings.cpp msgid "Minimap Width" -msgstr "" +msgstr "Largura do Mini-Mapa" #: editor/editor_settings.cpp msgid "Mouse Extra Buttons Navigate History" -msgstr "" +msgstr "Botões Extra do Mouse Navegam o Histórico" #: editor/editor_settings.cpp -#, fuzzy msgid "Drag And Drop Selection" -msgstr "Seleção Do GridMap" +msgstr "Seleção Arrasta e Solta" #: editor/editor_settings.cpp -msgid "Appearance" +msgid "Stay In Script Editor On Node Selected" msgstr "" +#: editor/editor_settings.cpp +msgid "Appearance" +msgstr "Aparência" + #: editor/editor_settings.cpp scene/gui/text_edit.cpp msgid "Show Line Numbers" msgstr "Mostrar Números de Linha" #: editor/editor_settings.cpp -#, fuzzy msgid "Line Numbers Zero Padded" -msgstr "Número da Linha:" +msgstr "Número das Linha Tem Espaçamento Com Zeros" #: editor/editor_settings.cpp msgid "Show Bookmark Gutter" -msgstr "" +msgstr "Exibir Espaçamento de Bookmark" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Breakpoint Gutter" -msgstr "Pular Breakpoints" +msgstr "Exibir Espaçamento de Pontos de Quebra" #: editor/editor_settings.cpp msgid "Show Info Gutter" -msgstr "" +msgstr "Exibir Espaçamento de Informações" #: editor/editor_settings.cpp msgid "Code Folding" -msgstr "" +msgstr "Dobramento de Código (Folding)" #: editor/editor_settings.cpp msgid "Word Wrap" -msgstr "" +msgstr "Quebra de Linhas" #: editor/editor_settings.cpp msgid "Show Line Length Guidelines" -msgstr "" +msgstr "Exibir Guia de Tamanho de Linhas" #: editor/editor_settings.cpp msgid "Line Length Guideline Soft Column" -msgstr "" +msgstr "Tamanho de Linha Guia em Coluna Suave" #: editor/editor_settings.cpp msgid "Line Length Guideline Hard Column" -msgstr "" +msgstr "Tamanho de Linha Guia em Coluna RÃgida" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Script List" -msgstr "Editor de Script" +msgstr "Lista de Scripts" #: editor/editor_settings.cpp msgid "Show Members Overview" -msgstr "" +msgstr "Exibir Visão Geral de Membros" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Files" -msgstr "Arquivo" +msgstr "Arquivos" #: editor/editor_settings.cpp -#, fuzzy msgid "Trim Trailing Whitespace On Save" -msgstr "Apagar Espaços em Branco" +msgstr "Aparar Espaços em Branco de Fim de Linha ao Salvar" #: editor/editor_settings.cpp msgid "Autosave Interval Secs" -msgstr "" +msgstr "Intervalo de Salvamento Automático em Segundos" #: editor/editor_settings.cpp editor/plugins/script_editor_plugin.cpp msgid "Restore Scripts On Load" -msgstr "" +msgstr "Restaurar Scripts ao Carregar" #: editor/editor_settings.cpp msgid "Auto Reload And Parse Scripts On Save" -msgstr "" +msgstr "Ao Salvar Recarregar e Reinterpretar Scripts Automaticamente" #: editor/editor_settings.cpp msgid "Auto Reload Scripts On External Change" -msgstr "" +msgstr "Recarregar Scripts Automaticamente em Alterações Externas" #: editor/editor_settings.cpp -#, fuzzy msgid "Create Signal Callbacks" -msgstr "Forçar Fallbacks do Shader" +msgstr "Criar Sinal de Callback" #: editor/editor_settings.cpp msgid "Sort Members Outline Alphabetically" -msgstr "" +msgstr "Ordenar Prévia de Membros Automaticamente" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Cursor" -msgstr "" +msgstr "Cursor" #: editor/editor_settings.cpp msgid "Scroll Past End Of File" -msgstr "" +msgstr "Rolar Além do Fim do Arquivo" #: editor/editor_settings.cpp msgid "Block Caret" -msgstr "" +msgstr "Bloco Cursor" #: editor/editor_settings.cpp msgid "Caret Blink" -msgstr "" +msgstr "Piscar Cursor" #: editor/editor_settings.cpp msgid "Caret Blink Speed" -msgstr "" +msgstr "Velocidade de Piscar do Cursor" #: editor/editor_settings.cpp -#, fuzzy msgid "Right Click Moves Caret" -msgstr "Clique com o botão direito para adicionar o ponto" +msgstr "Botão Direito Move o Cursor" #: editor/editor_settings.cpp modules/gdscript/gdscript.cpp #: modules/gdscript/gdscript_editor.cpp @@ -5761,54 +5722,51 @@ msgstr "Conclusão" #: editor/editor_settings.cpp msgid "Idle Parse Delay" -msgstr "" +msgstr "Atraso Ocioso Para Interpretação" #: editor/editor_settings.cpp msgid "Auto Brace Complete" -msgstr "" +msgstr "Fechar Chaves Automaticamente" #: editor/editor_settings.cpp msgid "Code Complete Delay" -msgstr "" +msgstr "Atraso de Sugestão de Código" #: editor/editor_settings.cpp msgid "Put Callhint Tooltip Below Current Line" -msgstr "" +msgstr "Pôr Dica de Sugestão de Chamada na Linha Abaixo da Atual" #: editor/editor_settings.cpp msgid "Callhint Tooltip Offset" -msgstr "" +msgstr "Espaçamento de Dica de Sugestão de Chamada" #: editor/editor_settings.cpp -#, fuzzy msgid "Complete File Paths" -msgstr "Copiar Caminho do Nó" +msgstr "Concluir Caminhos de Arquivo" #: editor/editor_settings.cpp modules/gdscript/gdscript_editor.cpp -#, fuzzy msgid "Add Type Hints" -msgstr "Adicionar Modelo" +msgstr "Adicionar Dicas de Tipo" #: editor/editor_settings.cpp msgid "Use Single Quotes" msgstr "Usar Aspas Simples" #: editor/editor_settings.cpp -#, fuzzy msgid "Show Help Index" -msgstr "Mostrar auxiliadores" +msgstr "Exibir Ãndice de Ajuda" #: editor/editor_settings.cpp msgid "Help Font Size" -msgstr "" +msgstr "Tamanho da Fonte de Ajuda" #: editor/editor_settings.cpp msgid "Help Source Font Size" -msgstr "" +msgstr "Tamanho da Fonte de Ajuda Principal" #: editor/editor_settings.cpp msgid "Help Title Font Size" -msgstr "" +msgstr "Tamanho da Fonte de Ajuda para TÃtulos" #: editor/editor_settings.cpp modules/gridmap/grid_map_editor_plugin.cpp msgid "Grid Map" @@ -5819,45 +5777,39 @@ msgid "Pick Distance" msgstr "Escolha a Distância" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Preview Size" -msgstr "Visualização" +msgstr "Tamanho da Prévia" #: editor/editor_settings.cpp msgid "Primary Grid Color" -msgstr "" +msgstr "Cor Primária da Grade" #: editor/editor_settings.cpp msgid "Secondary Grid Color" -msgstr "" +msgstr "Cor Secundária da Grade" #: editor/editor_settings.cpp -#, fuzzy msgid "Selection Box Color" -msgstr "Selecionar Apenas" +msgstr "Cor da Caixa de Seleção" #: editor/editor_settings.cpp editor/plugins/path_editor_plugin.cpp #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp -#, fuzzy msgid "3D Gizmos" -msgstr "Gizmos" +msgstr "Gizmos 3D" #: editor/editor_settings.cpp editor/plugins/path_editor_plugin.cpp #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp -#, fuzzy msgid "Gizmo Colors" -msgstr "Cores de Emissão" +msgstr "Cores do Gismo" #: editor/editor_settings.cpp -#, fuzzy msgid "Instanced" -msgstr "Instância" +msgstr "Instanciado" #: editor/editor_settings.cpp modules/gltf/gltf_node.cpp #: scene/3d/physics_body.cpp -#, fuzzy msgid "Joint" -msgstr "Ponto" +msgstr "Junção" #: editor/editor_settings.cpp scene/2d/collision_shape_2d.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/touch_screen_button.cpp @@ -5866,12 +5818,11 @@ msgstr "Ponto" #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Shape" -msgstr "" +msgstr "Form" #: editor/editor_settings.cpp -#, fuzzy msgid "Primary Grid Steps" -msgstr "Passo de grade:" +msgstr "Passadas para Grade Primária" #: editor/editor_settings.cpp msgid "Grid Size" @@ -5879,183 +5830,155 @@ msgstr "Tamanho da Grade" #: editor/editor_settings.cpp msgid "Grid Division Level Max" -msgstr "" +msgstr "NÃvel Máximo de Divisão de Grade" #: editor/editor_settings.cpp msgid "Grid Division Level Min" -msgstr "" +msgstr "NÃvel MÃnimo de Divisão da Grade" #: editor/editor_settings.cpp msgid "Grid Division Level Bias" -msgstr "" +msgstr "Tendência do NÃvel de Divisão da Grade" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid XZ Plane" -msgstr "Pintura GridMap" +msgstr "Grade do Plano XZ" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid XY Plane" -msgstr "Pintura GridMap" +msgstr "Grade do Plano XY" #: editor/editor_settings.cpp -#, fuzzy msgid "Grid YZ Plane" -msgstr "Pintura GridMap" +msgstr "Grade do Plano YZ" #: editor/editor_settings.cpp -#, fuzzy msgid "Default FOV" -msgstr "Padrão" +msgstr "Campo de Visão (FOV) Padrão" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Z Near" -msgstr "Tema Padrão" +msgstr "Z Padrão Próximo" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Z Far" -msgstr "Padrão" +msgstr "Z Padrão Longe" #: editor/editor_settings.cpp msgid "Lightmap Baking Number Of CPU Threads" -msgstr "" +msgstr "Número de Threads de CPU para o Bake do Mapa de Luz" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Scheme" -msgstr "Modo Navegação" +msgstr "Esquema de Navegação" #: editor/editor_settings.cpp -#, fuzzy msgid "Invert Y Axis" -msgstr "Eduitar Eixo Y" +msgstr "Inverter Eixo Y" #: editor/editor_settings.cpp -#, fuzzy msgid "Invert X Axis" -msgstr "Editar Eixo X" +msgstr "Inverter Eixo X" #: editor/editor_settings.cpp -#, fuzzy msgid "Zoom Style" -msgstr "Reduzir" +msgstr "Estilo de Zoom" #: editor/editor_settings.cpp msgid "Emulate Numpad" -msgstr "" +msgstr "Simular o Numpad" #: editor/editor_settings.cpp msgid "Emulate 3 Button Mouse" -msgstr "" +msgstr "Simular o Botão 3 Do Mouse" #: editor/editor_settings.cpp -#, fuzzy msgid "Orbit Modifier" -msgstr "Ordenar por Primeiro Modificado" +msgstr "Modificador de Órbita" #: editor/editor_settings.cpp -#, fuzzy msgid "Pan Modifier" -msgstr "Modo Panorâmico" +msgstr "Modificador de Panorâmica" #: editor/editor_settings.cpp -#, fuzzy msgid "Zoom Modifier" -msgstr "Modificado" +msgstr "Modificador de Zoom" #: editor/editor_settings.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Warped Mouse Panning" -msgstr "" +msgstr "Panorização Distorcida pelo Mouse" #: editor/editor_settings.cpp -#, fuzzy msgid "Navigation Feel" -msgstr "Modo Navegação" +msgstr "Sensação de Navegação" #: editor/editor_settings.cpp msgid "Orbit Sensitivity" -msgstr "" +msgstr "Sensitividade de Órbita" #: editor/editor_settings.cpp msgid "Orbit Inertia" -msgstr "" +msgstr "Inercia de Órbita" #: editor/editor_settings.cpp -#, fuzzy msgid "Translation Inertia" -msgstr "Traduções" +msgstr "Inércia de Translação" #: editor/editor_settings.cpp -#, fuzzy msgid "Zoom Inertia" -msgstr "Ampliar" +msgstr "Inércia de Zoom" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook" -msgstr "Visão Livre em Cima" +msgstr "Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Navigation Scheme" -msgstr "Criar Malha de Navegação" +msgstr "Esquema de Navegação de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Sensitivity" -msgstr "Visão Livre na Esquerda" +msgstr "Sensibilidade de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Inertia" -msgstr "Visão Livre na Esquerda" +msgstr "Inercia de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Base Speed" -msgstr "Modificador de velocidade da Visão Livre" +msgstr "Velocidade Base de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Activation Modifier" -msgstr "Modificador de velocidade lenta da Visão Livre" +msgstr "Modificador de Ativação de Visão Livre" #: editor/editor_settings.cpp -#, fuzzy msgid "Freelook Speed Zoom Link" -msgstr "Modificador de velocidade da Visão Livre" +msgstr "Velocidade de Ligação do Visão Livre" #: editor/editor_settings.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Grid Color" -msgstr "Escolher Cor" +msgstr "Cor da Grade" #: editor/editor_settings.cpp -#, fuzzy msgid "Guides Color" -msgstr "Escolher Cor" +msgstr "Cor Guia" #: editor/editor_settings.cpp -#, fuzzy msgid "Smart Snapping Line Color" -msgstr "Encaixe inteligente" +msgstr "Cor da Linha de Encaixe Inteligente" #: editor/editor_settings.cpp msgid "Bone Width" -msgstr "" +msgstr "Largura do Osso" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Color 1" -msgstr "Renomear Item de Cor" +msgstr "Cor de Osso 1" #: editor/editor_settings.cpp -#, fuzzy msgid "Bone Color 2" -msgstr "Renomear Item de Cor" +msgstr "Cor de Osso 2" #: editor/editor_settings.cpp msgid "Bone Selected Color" @@ -6063,11 +5986,11 @@ msgstr "Cor Selecionada do Osso" #: editor/editor_settings.cpp msgid "Bone IK Color" -msgstr "" +msgstr "Cor de Osso IK (cinemática inversa)" #: editor/editor_settings.cpp msgid "Bone Outline Color" -msgstr "" +msgstr "Cor de Contorno do Osso" #: editor/editor_settings.cpp msgid "Bone Outline Size" @@ -6075,103 +5998,93 @@ msgstr "Tamanho do Contorno do Osso" #: editor/editor_settings.cpp msgid "Viewport Border Color" -msgstr "" +msgstr "Cor da Borda de Viewport" #: editor/editor_settings.cpp msgid "Constrain Editor View" -msgstr "" +msgstr "Restringir Visão do Editor" #: editor/editor_settings.cpp msgid "Simple Panning" -msgstr "" +msgstr "Panoramização Simples" #: editor/editor_settings.cpp msgid "Scroll To Pan" -msgstr "" +msgstr "Rolar para Panoramizar" #: editor/editor_settings.cpp -#, fuzzy msgid "Pan Speed" -msgstr "Velocidade:" +msgstr "Velocidade da Panoramização" #: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Poly Editor" -msgstr "Editor UV de PolÃgonos 2D" +msgstr "Editor de PolÃgonos" #: editor/editor_settings.cpp msgid "Point Grab Radius" -msgstr "" +msgstr "Raio de Agarro ao Ponto" #: editor/editor_settings.cpp editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Show Previous Outline" -msgstr "Plano Anterior" +msgstr "Exibir Prévia Anterior" #: editor/editor_settings.cpp editor/scene_tree_dock.cpp -#, fuzzy msgid "Autorename Animation Tracks" -msgstr "Renomear Animação" +msgstr "Renomear Automaticamente Faixa de Animação" #: editor/editor_settings.cpp msgid "Default Create Bezier Tracks" -msgstr "" +msgstr "Criar Faixa de Bezier por Padrão" #: editor/editor_settings.cpp -#, fuzzy msgid "Default Create Reset Tracks" -msgstr "Criar RESET Track(s)" +msgstr "Criar Faixa RESET Por Padrão" #: editor/editor_settings.cpp msgid "Onion Layers Past Color" -msgstr "" +msgstr "Cor da Camada de Cebola Anterior" #: editor/editor_settings.cpp msgid "Onion Layers Future Color" -msgstr "" +msgstr "Cor da Camada de Cebola Posterior" #: editor/editor_settings.cpp -#, fuzzy msgid "Visual Editors" -msgstr "Editor de Grupos" +msgstr "Editores Visuais" #: editor/editor_settings.cpp msgid "Minimap Opacity" -msgstr "" +msgstr "Opacidade do Mini-Mapa" #: editor/editor_settings.cpp msgid "Window Placement" -msgstr "" +msgstr "Colocação da Janela" #: editor/editor_settings.cpp scene/2d/back_buffer_copy.cpp scene/2d/sprite.cpp #: scene/2d/visibility_notifier_2d.cpp scene/3d/sprite_3d.cpp #: scene/gui/control.cpp -#, fuzzy msgid "Rect" -msgstr "Rect Completo" +msgstr "Retângulo" #: editor/editor_settings.cpp -#, fuzzy msgid "Rect Custom Position" -msgstr "Definir Posição de SaÃda da Curva" +msgstr "Posição Personalizada Do Retângulo" #: editor/editor_settings.cpp platform/android/export/export_plugin.cpp msgid "Screen" -msgstr "" +msgstr "Tela" #: editor/editor_settings.cpp -#, fuzzy msgid "Auto Save" -msgstr "Auto Fatiar" +msgstr "Salvar Automaticamente" #: editor/editor_settings.cpp msgid "Save Before Running" msgstr "Salvar Antes de Executar" #: editor/editor_settings.cpp -#, fuzzy msgid "Font Size" -msgstr "Visão Frontal" +msgstr "Tamanho da Fonte" #: editor/editor_settings.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp @@ -6180,28 +6093,26 @@ msgstr "Hospedeiro Remoto" #: editor/editor_settings.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp -#, fuzzy msgid "Remote Port" -msgstr "Remover Ponto" +msgstr "Porta Remota" #: editor/editor_settings.cpp -#, fuzzy msgid "Editor SSL Certificates" -msgstr "Configurações do Editor" +msgstr "Certificados SSL do Editor" #: editor/editor_settings.cpp msgid "HTTP Proxy" -msgstr "" +msgstr "Proxy HTTP" #: editor/editor_settings.cpp msgid "Host" -msgstr "" +msgstr "Hospedeiro" #: editor/editor_settings.cpp editor/fileserver/editor_file_server.cpp #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Port" -msgstr "" +msgstr "Porta" #. TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects. #: editor/editor_settings.cpp @@ -6215,32 +6126,31 @@ msgstr "Ordem de Classificação" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Symbol Color" -msgstr "" +msgstr "Cor do Simbolo" #: editor/editor_settings.cpp msgid "Keyword Color" -msgstr "" +msgstr "Cor de Palavra Chave" #: editor/editor_settings.cpp msgid "Control Flow Keyword Color" -msgstr "" +msgstr "Core de Palavra Chave de Controle de Fluxo" #: editor/editor_settings.cpp -#, fuzzy msgid "Base Type Color" -msgstr "Mudar Tipo Base" +msgstr "Cor de Tipo Base" #: editor/editor_settings.cpp msgid "Engine Type Color" -msgstr "" +msgstr "Cor de Tipo da Engine" #: editor/editor_settings.cpp msgid "User Type Color" -msgstr "" +msgstr "Cor de Tipo Do Usuário" #: editor/editor_settings.cpp msgid "Comment Color" -msgstr "" +msgstr "Cor de Comentário" #: editor/editor_settings.cpp msgid "String Color" @@ -6257,26 +6167,24 @@ msgid "Completion Background Color" msgstr "Cor de Fundo de Acabamento" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Completion Selected Color" -msgstr "Importar Selecionado" +msgstr "Cor de Sugestão Selecionada" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Existing Color" -msgstr "" +msgstr "Cor de Sugestão Existente" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Scroll Color" -msgstr "" +msgstr "Cor da Barra de Rolagem de Sugestão" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Completion Font Color" -msgstr "" +msgstr "Cor da Fonte de Sugestão" #: editor/editor_settings.cpp -#, fuzzy msgid "Text Color" -msgstr "Próximo Chão" +msgstr "Cor do Texto" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Line Number Color" @@ -6288,86 +6196,75 @@ msgstr "Cor do Número da Linha Segura" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Caret Color" -msgstr "" +msgstr "Cor do Cursor" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Caret Background Color" msgstr "Cor de Fundo de Acentuação" #: editor/editor_settings.cpp -#, fuzzy msgid "Text Selected Color" -msgstr "Excluir Selecionados" +msgstr "Cor do Texto Selecionado" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Selection Color" -msgstr "Selecionar Apenas" +msgstr "Cor da Seleção" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Brace Mismatch Color" -msgstr "" +msgstr "Cor de Chave IncompatÃvel" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Current Line Color" -msgstr "Cena Atual" +msgstr "Cor da Linha Atual" #: editor/editor_settings.cpp msgid "Line Length Guideline Color" -msgstr "" +msgstr "Cor do Tamanho de Linha Guia" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Word Highlighted Color" -msgstr "Realce de sintaxe" +msgstr "Cor da Palavra em Destaque" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Number Color" -msgstr "" +msgstr "Cor de Número" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Function Color" -msgstr "Funções" +msgstr "Cor de Função" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Member Variable Color" -msgstr "Renomear Variável" +msgstr "Cor de Variável Membro" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Mark Color" -msgstr "Escolher Cor" +msgstr "Cor de Marcação" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Bookmark Color" -msgstr "Marcadores" +msgstr "Cor de Bookmark" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Breakpoint Color" -msgstr "Breakpoints" +msgstr "Cor de Ponto de Quebra" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Executing Line Color" -msgstr "" +msgstr "Cor da Linha em Execução" #: editor/editor_settings.cpp scene/resources/default_theme/default_theme.cpp msgid "Code Folding Color" -msgstr "" +msgstr "Cor da Dobradiça de Código" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Color" -msgstr "Pesquisar resultados" +msgstr "Cor do Resultado de Pesquisa" #: editor/editor_settings.cpp -#, fuzzy msgid "Search Result Border Color" -msgstr "Pesquisar resultados" +msgstr "Cor da Borda do Resultado de Pesquisa" #: editor/editor_spin_slider.cpp msgid "Hold %s to round to integers. Hold Shift for more precise changes." @@ -6376,14 +6273,12 @@ msgstr "" "mais precisas." #: editor/editor_spin_slider.cpp scene/gui/button.cpp -#, fuzzy msgid "Flat" -msgstr "Plano 0" +msgstr "Raso" #: editor/editor_spin_slider.cpp -#, fuzzy msgid "Hide Slider" -msgstr "Modo Colisão" +msgstr "Esconder Rolagem" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" @@ -6683,7 +6578,7 @@ msgstr "" #: editor/fileserver/editor_file_server.cpp msgid "File Server" -msgstr "" +msgstr "Servidor de Arquivos" #: editor/fileserver/editor_file_server.cpp #: editor/plugins/version_control_editor_plugin.cpp @@ -6751,6 +6646,11 @@ msgid "" "After renaming to an unknown extension, the file won't be shown in the " "editor anymore." msgstr "" +"Esta extensão de arquivo não é reconhecida pelo editor.\n" +"Se ainda assim você deseja renomear, utilize o explorador de arquivos do seu " +"sistema operacional.\n" +"Após renomear para uma extensão desconhecida, este arquivo não será mais " +"exibida pelo editor." #: editor/filesystem_dock.cpp msgid "" @@ -7051,43 +6951,40 @@ msgstr "Gerenciar Grupos" #: editor/import/editor_import_collada.cpp msgid "Collada" -msgstr "" +msgstr "Collada" #: editor/import/editor_import_collada.cpp msgid "Use Ambient" -msgstr "" +msgstr "Utilizar Ambient" #: editor/import/resource_importer_bitmask.cpp -#, fuzzy msgid "Create From" -msgstr "Criar Pasta" +msgstr "Criar à Partir de" #: editor/import/resource_importer_bitmask.cpp #: servers/audio/effects/audio_effect_compressor.cpp msgid "Threshold" -msgstr "" +msgstr "Limite" #: editor/import/resource_importer_csv_translation.cpp #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_scene.cpp #: editor/import/resource_importer_texture.cpp #: editor/import/resource_importer_wav.cpp scene/3d/gi_probe.cpp -#, fuzzy msgid "Compress" -msgstr "Componentes" +msgstr "Comprimir" #: editor/import/resource_importer_csv_translation.cpp msgid "Delimiter" -msgstr "" +msgstr "Delimitador" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "ColorCorrect" -msgstr "Correção de Cor" +msgstr "Corrigir as Cores" #: editor/import/resource_importer_layered_texture.cpp msgid "No BPTC If RGB" -msgstr "" +msgstr "Não utilizar BPTC se for RGB" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/2d/cpu_particles_2d.cpp @@ -7095,13 +6992,13 @@ msgstr "" #: scene/resources/material.cpp scene/resources/particles_material.cpp #: scene/resources/texture.cpp scene/resources/visual_shader.cpp msgid "Flags" -msgstr "" +msgstr "Sinalizadores" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/animation/tween.cpp #: scene/resources/texture.cpp msgid "Repeat" -msgstr "" +msgstr "Repetir" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp scene/2d/light_2d.cpp @@ -7111,24 +7008,22 @@ msgstr "Filtro" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Mipmaps" -msgstr "Sinais" +msgstr "Mipmaps" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp msgid "Anisotropic" -msgstr "" +msgstr "Anisotrópico" #: editor/import/resource_importer_layered_texture.cpp #: editor/import/resource_importer_texture.cpp msgid "sRGB" -msgstr "" +msgstr "sRGB" #: editor/import/resource_importer_layered_texture.cpp -#, fuzzy msgid "Slices" -msgstr "Auto Fatiar" +msgstr "Fatias" #: editor/import/resource_importer_layered_texture.cpp #: scene/gui/aspect_ratio_container.cpp scene/gui/control.cpp @@ -7145,14 +7040,12 @@ msgid "Vertical" msgstr "Vertical" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Generate Tangents" -msgstr "Gerar Pontos" +msgstr "Gerar Tangentes" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Scale Mesh" -msgstr "Modo de Escalonamento" +msgstr "Redimensionar Malha" #: editor/import/resource_importer_obj.cpp msgid "Offset Mesh" @@ -7160,14 +7053,12 @@ msgstr "Malha de Deslocamento" #: editor/import/resource_importer_obj.cpp #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Octahedral Compression" -msgstr "Expressão" +msgstr "Compressão Octaedral" #: editor/import/resource_importer_obj.cpp -#, fuzzy msgid "Optimize Mesh Flags" -msgstr "Sinalizadores de Tamanho" +msgstr "Otimizar Sinalizadores da Malha" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" @@ -7215,24 +7106,20 @@ msgid "Nodes" msgstr "Nós" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Type" -msgstr "Retornar" +msgstr "Tipo da Raiz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Name" -msgstr "Nome Remoto" +msgstr "Nome da Raiz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Root Scale" -msgstr "Escala" +msgstr "Escala da Raiz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Custom Script" -msgstr "Recortar Nós" +msgstr "Script Personalizado" #: editor/import/resource_importer_scene.cpp scene/resources/texture.cpp msgid "Storage" @@ -7240,69 +7127,59 @@ msgstr "Armazenamento" #: editor/import/resource_importer_scene.cpp msgid "Use Legacy Names" -msgstr "" +msgstr "Utilizar Nomes Legados" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Materials" msgstr "Materiais" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep On Reimport" -msgstr "Reimportar" +msgstr "Manter ao Reimportar" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp -#, fuzzy msgid "Meshes" -msgstr "Malha" +msgstr "Malhas" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Ensure Tangents" -msgstr "Modificar Tangente da Curva" +msgstr "Garantir Tangentes" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Light Baking" -msgstr "Faça mapas de luz" +msgstr "Bake de Mapa de Luz" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Lightmap Texel Size" -msgstr "Faça mapas de luz" +msgstr "Tamanho do Texel no Mapa de Luz" #: editor/import/resource_importer_scene.cpp modules/gltf/gltf_state.cpp msgid "Skins" -msgstr "" +msgstr "Peles" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Use Named Skins" -msgstr "Usar Encaixe Escalar" +msgstr "Utilizar Peles com Nome" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "External Files" -msgstr "Abrir um Arquivo" +msgstr "Arquivos Externos" #: editor/import/resource_importer_scene.cpp msgid "Store In Subdir" -msgstr "" +msgstr "Salvar em Sub Diretório" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Filter Script" -msgstr "Filtrar scripts" +msgstr "Filtrar Script" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Keep Custom Tracks" -msgstr "Transformação" +msgstr "Manter Faixas Personalizadas" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Optimizer" -msgstr "Otimizar" +msgstr "Otimizador" #: editor/import/resource_importer_scene.cpp #: editor/plugins/item_list_editor_plugin.cpp main/main.cpp @@ -7316,9 +7193,8 @@ msgstr "Otimizar" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp #: scene/gui/rich_text_label.cpp scene/resources/curve.cpp #: scene/resources/environment.cpp scene/resources/material.cpp -#, fuzzy msgid "Enabled" -msgstr "Habilitar" +msgstr "Habilitado" #: editor/import/resource_importer_scene.cpp msgid "Max Linear Error" @@ -7329,19 +7205,16 @@ msgid "Max Angular Error" msgstr "Erro Angular Máximo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Max Angle" -msgstr "Valor" +msgstr "Ângulo Máximo" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Remove Unused Tracks" -msgstr "Remover Trilha da Anim" +msgstr "Remover Faixas não Utilizadas" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Clips" -msgstr "Clipes de Animação" +msgstr "Clipes" #: editor/import/resource_importer_scene.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/particles_2d.cpp scene/3d/area.cpp scene/3d/cpu_particles.cpp @@ -7395,30 +7268,33 @@ msgid "" "%s: Texture detected as used as a normal map in 3D. Enabling red-green " "texture compression to reduce memory usage (blue channel is discarded)." msgstr "" +"%s: Foi detectado que a textura está sendo utilizada como mapa normal em 3D. " +"Habilitando a compressão vermelho/verde para reduzir o uso de memória (o " +"canal azul é descartado)." #: editor/import/resource_importer_texture.cpp msgid "" "%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap " "generation and VRAM texture compression." msgstr "" +"%s: Foi detectado que a textura está sendo utilizada em 3D. Habilitando a " +"filtro, repetir, geração de mipmap e compressão de textura VRAM." #: editor/import/resource_importer_texture.cpp msgid "2D, Detect 3D" -msgstr "" +msgstr "2D, Detecte 3D" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "2D Pixel" -msgstr "Pixels Sólidos" +msgstr "Pixel 2D" #: editor/import/resource_importer_texture.cpp scene/resources/texture.cpp msgid "Lossy Quality" -msgstr "" +msgstr "Com Perda de Qualidade" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "HDR Mode" -msgstr "Modo de Seleção" +msgstr "Modo HDR" #: editor/import/resource_importer_texture.cpp msgid "BPTC LDR" @@ -7429,54 +7305,52 @@ msgstr "" #: scene/2d/mesh_instance_2d.cpp scene/2d/multimesh_instance_2d.cpp #: scene/2d/particles_2d.cpp scene/2d/sprite.cpp scene/resources/style_box.cpp msgid "Normal Map" -msgstr "" +msgstr "Mapa Normal" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Process" -msgstr "Pós-processamento" +msgstr "Processar" #: editor/import/resource_importer_texture.cpp msgid "Fix Alpha Border" -msgstr "" +msgstr "Corrigir Alpha da Borda" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Premult Alpha" -msgstr "Editar PolÃgono" +msgstr "" #: editor/import/resource_importer_texture.cpp msgid "Hdr As Srgb" -msgstr "" +msgstr "HDR como SRGB" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Invert Color" -msgstr "Vértice" +msgstr "Inverter Cor" #: editor/import/resource_importer_texture.cpp msgid "Normal Map Invert Y" msgstr "Inverter Y do Mapa Normal" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "Size Limit" -msgstr "Limites" +msgstr "Limite de Tamanho" #: editor/import/resource_importer_texture.cpp msgid "Detect 3D" -msgstr "" +msgstr "Detectar 3D" #: editor/import/resource_importer_texture.cpp -#, fuzzy msgid "SVG" -msgstr "HSV" +msgstr "SVG" #: editor/import/resource_importer_texture.cpp msgid "" "Warning, no suitable PC VRAM compression enabled in Project Settings. This " "texture will not display correctly on PC." msgstr "" +"Atenção, nenhuma forma adequada de Compressão VRAM para PC foi habilitada " +"nas Configurações do Projeto. Esta textura não será exibida corretamente em " +"PCs." #: editor/import/resource_importer_texture_atlas.cpp msgid "Atlas File" @@ -7487,64 +7361,56 @@ msgid "Import Mode" msgstr "Modo de Importação" #: editor/import/resource_importer_texture_atlas.cpp -#, fuzzy msgid "Crop To Region" -msgstr "Definir a região do Mosaico" +msgstr "Recortar para Região" #: editor/import/resource_importer_texture_atlas.cpp msgid "Trim Alpha Border From Region" -msgstr "" +msgstr "Aparar Borda Alfa da Região" #: editor/import/resource_importer_wav.cpp scene/2d/physics_body_2d.cpp -#, fuzzy msgid "Force" -msgstr "Forçar Push" +msgstr "Forçar" #: editor/import/resource_importer_wav.cpp msgid "8 Bit" -msgstr "" +msgstr "8 Bits" #: editor/import/resource_importer_wav.cpp main/main.cpp #: modules/mono/editor/csharp_project.cpp modules/mono/mono_gd/gd_mono.cpp msgid "Mono" -msgstr "" +msgstr "Mono" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Max Rate" -msgstr "Nó Mix" +msgstr "Frequência Máxima" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Max Rate Hz" -msgstr "Nó Mix" +msgstr "Frequência Máxima Hz" #: editor/import/resource_importer_wav.cpp msgid "Trim" -msgstr "" +msgstr "Aparar" #: editor/import/resource_importer_wav.cpp -#, fuzzy msgid "Normalize" -msgstr "Formato" +msgstr "Normalizar" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Mode" -msgstr "Modo de Movimentação" +msgstr "Modo de Loop" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop Begin" -msgstr "Modo de Movimentação" +msgstr "Inicio do Loop" #: editor/import/resource_importer_wav.cpp #: scene/resources/audio_stream_sample.cpp -#, fuzzy msgid "Loop End" -msgstr "Modo de Movimentação" +msgstr "Fim do Loop" #: editor/import_defaults_editor.cpp msgid "Select Importer" @@ -7632,18 +7498,16 @@ msgid "Raw" msgstr "Bruto" #: editor/inspector_dock.cpp -#, fuzzy msgid "Capitalized" -msgstr "Capitalizar" +msgstr "Capitalizado" #: editor/inspector_dock.cpp -#, fuzzy msgid "Localized" -msgstr "Localizar" +msgstr "Localizado" #: editor/inspector_dock.cpp msgid "Localization not available for current language." -msgstr "" +msgstr "Localização não disponÃvel para linguagem atual." #: editor/inspector_dock.cpp msgid "Copy Properties" @@ -8192,9 +8056,8 @@ msgid "New" msgstr "Novo" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Paste As Reference" -msgstr "%s Referência de Classes" +msgstr "Colar como Referência" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -8523,7 +8386,7 @@ msgstr "Filtros..." #: editor/plugins/asset_library_editor_plugin.cpp scene/main/http_request.cpp msgid "Use Threads" -msgstr "" +msgstr "Usar Threads" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Contents:" @@ -8686,25 +8549,21 @@ msgid "Loading..." msgstr "Carregando..." #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "First" msgstr "Primeiro" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Previous" msgstr "Anterior" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Next" msgstr "Próximo" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgctxt "Pagination" msgid "Last" msgstr "Último" @@ -8755,7 +8614,7 @@ msgstr "Testando" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed to get repository configuration." -msgstr "" +msgstr "Falhou em obter o repositório de configuração." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" @@ -8815,7 +8674,7 @@ msgstr "Faça mapas de luz" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "LightMap Bake" -msgstr "" +msgstr "Bake de Mapa de Luz" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Select lightmap bake file:" @@ -9322,23 +9181,20 @@ msgid "View" msgstr "Visualizar" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show" -msgstr "Mostrar Grade" +msgstr "Exibir" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Show When Snapping" -msgstr "Encaixe inteligente" +msgstr "Exibir ao Encaixar" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Hide" -msgstr "" +msgstr "Esconder" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Toggle Grid" -msgstr "Alternar Modo" +msgstr "Alternar Grade" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -9622,11 +9478,11 @@ msgstr "Plano 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" -msgstr "Ease In" +msgstr "Esmaecer de Entrada" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease Out" -msgstr "Ease Out" +msgstr "Esmaecer de SaÃda" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" @@ -9690,16 +9546,15 @@ msgstr "Gradiente Editado" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp msgid "Swap GradientTexture2D Fill Points" -msgstr "" +msgstr "Trocar Pontos de Preenchimento do GradientTexture2D" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp msgid "Swap Gradient Fill Points" -msgstr "" +msgstr "Trocar Pontos de Preenchimento do Degradê" #: editor/plugins/gradient_texture_2d_editor_plugin.cpp -#, fuzzy msgid "Toggle Grid Snap" -msgstr "Alternar Modo" +msgstr "Alternar Encaixe da Grade" #: editor/plugins/item_list_editor_plugin.cpp editor/project_export.cpp #: scene/3d/label_3d.cpp scene/gui/button.cpp scene/gui/dialogs.cpp @@ -9718,13 +9573,12 @@ msgstr "Ãcone" #: editor/plugins/item_list_editor_plugin.cpp msgid "ID" -msgstr "" +msgstr "ID" #: editor/plugins/item_list_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Separator" -msgstr "Separação:" +msgstr "Separador" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" @@ -9958,7 +9812,6 @@ msgstr "" "%s" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "MeshLibrary" msgstr "Biblioteca de Malhas" @@ -9983,14 +9836,12 @@ msgid "Update from Scene" msgstr "Atualizar a partir de Cena" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply without Transforms" -msgstr "Aplicar transformações da MeshInstance" +msgstr "Aplicar sem Transformações" #: editor/plugins/mesh_library_editor_plugin.cpp -#, fuzzy msgid "Apply with Transforms" -msgstr "Aplicar transformações da MeshInstance" +msgstr "Aplicar com Transformações" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." @@ -10482,7 +10333,7 @@ msgstr "Configurações da grade" #: editor/plugins/polygon_2d_editor_plugin.cpp modules/csg/csg_shape.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Snap" -msgstr "Snap" +msgstr "Encaixe" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" @@ -10518,7 +10369,7 @@ msgstr "Sincronizar Ossos ao PolÃgono" #: editor/plugins/ray_cast_2d_editor_plugin.cpp msgid "Set cast_to" -msgstr "" +msgstr "Definir cast_to" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ERROR: Couldn't load resource!" @@ -10849,48 +10700,43 @@ msgstr "Resultados de Pesquisa" #: editor/plugins/script_editor_plugin.cpp msgid "Open Dominant Script On Scene Change" -msgstr "" +msgstr "Abrir Script Dominante ao Mudar de Cena" #: editor/plugins/script_editor_plugin.cpp msgid "External" -msgstr "" +msgstr "Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Use External Editor" -msgstr "Depurar com o Editor Externo" +msgstr "Utilizar Editor Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Exec Path" -msgstr "Caminho de Exportação" +msgstr "Caminho de Execução" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Script Temperature Enabled" -msgstr "Selecionar o Arquivo de Modelo" +msgstr "Temperatura de Script Habilitado" #: editor/plugins/script_editor_plugin.cpp msgid "Highlight Current Script" -msgstr "" +msgstr "Destacar Script Atual" #: editor/plugins/script_editor_plugin.cpp msgid "Script Temperature History Size" -msgstr "" +msgstr "Tamanho de Histórico de Temperatura de Script" #: editor/plugins/script_editor_plugin.cpp msgid "Current Script Background Color" msgstr "Cor de Fundo do Script Atual" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Group Help Pages" -msgstr "Agrupar Selecionados" +msgstr "Agrupar Páginas de Ajuda" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Sort Scripts By" -msgstr "Criar Script" +msgstr "Ordenar Scripts Por" #: editor/plugins/script_editor_plugin.cpp msgid "List Script Names As" @@ -10898,7 +10744,7 @@ msgstr "Listar Nomes de Script Como" #: editor/plugins/script_editor_plugin.cpp msgid "Exec Flags" -msgstr "" +msgstr "Sinalizadores de Execução" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Scripts" @@ -10982,7 +10828,7 @@ msgstr "Marcadores" #: editor/plugins/script_text_editor.cpp msgid "Breakpoints" -msgstr "Breakpoints" +msgstr "Pontos de Quebra" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp @@ -11411,13 +11257,14 @@ msgstr "Pré-visualização Cinemática" #: editor/plugins/spatial_editor_plugin.cpp msgid "(Not in GLES2)" -msgstr "" +msgstr "(Não disponÃvel em GLES2)" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "" "Debug draw modes are only available when using the GLES3 renderer, not GLES2." -msgstr "Não disponÃvel ao usar o renderizador GLES2." +msgstr "" +"Modos de Debug draw só estão disponÃveis para uso com o renderizador GLES3. " +"GLES2 não suporta esta funcionalidade." #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Left" @@ -11712,16 +11559,15 @@ msgstr "Pós" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Size" -msgstr "" +msgstr "Tamanho do Gizmo Manipulador" #: editor/plugins/spatial_editor_plugin.cpp msgid "Manipulator Gizmo Opacity" -msgstr "" +msgstr "Opacidade do Gizmo Manipulador" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Show Viewport Rotation Gizmo" -msgstr "Bloquear Rotação da Visão" +msgstr "Exibir Gizmo de Rotação do Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "Unnamed Gizmo" @@ -11773,9 +11619,8 @@ msgid "Invalid geometry, can't replace by mesh." msgstr "Geometria inválida, não é possÃvel substituir por malha." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to MeshInstance2D" -msgstr "Converter para Malha2D" +msgstr "Converter para MeshInstance2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." @@ -11878,6 +11723,11 @@ msgid "New Animation" msgstr "Nova animação" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrar métodos" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Velocidade:" @@ -12175,9 +12025,8 @@ msgstr "" "Fechar mesmo assim?" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Type" -msgstr "Remover Telha" +msgstr "Remover Tipo" #: editor/plugins/theme_editor_plugin.cpp msgid "" @@ -12221,14 +12070,12 @@ msgstr "" "Adicione mais itens manualmente ou importe de outro tema." #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Add Theme Type" -msgstr "Adicionar Tipo de Item" +msgstr "Adicionar Tipo de Tema" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Remove Theme Type" -msgstr "Remover remoto" +msgstr "Remover Tipo de Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Add Color Item" @@ -12343,9 +12190,8 @@ msgid "Select Another Theme Resource:" msgstr "Selecionar Outro Recurso de Tema:" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Theme Resource" -msgstr "Renomear Recurso" +msgstr "Recurso de Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Another Theme" @@ -12400,14 +12246,12 @@ msgid "Add Item Type" msgstr "Adicionar Tipo de Item" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Set Variation Base Type" -msgstr "Definir o Tipo da Variável" +msgstr "Definir Tipo de Variação Base" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Set Base Type" -msgstr "Mudar Tipo Base" +msgstr "Definir Tipo Base" #: editor/plugins/theme_editor_plugin.cpp msgid "Show Default" @@ -12429,12 +12273,15 @@ msgstr "Substituir todos os itens do modelo padrão." #: editor/plugins/theme_editor_plugin.cpp msgid "Select the variation base type from a list of available types." msgstr "" +"Selecione a variação do tipo base à partir da lista de tipos disponÃveis." #: editor/plugins/theme_editor_plugin.cpp msgid "" "A type associated with a built-in class cannot be marked as a variation of " "another type." msgstr "" +"Um tipo associado à uma classe padrão não pode ser marcada como variação de " +"outro tipo." #: editor/plugins/theme_editor_plugin.cpp msgid "Theme:" @@ -12672,14 +12519,13 @@ msgid "Clear Transform" msgstr "Limpar Transformação" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Tile Map" -msgstr "Pintar TileMap" +msgstr "Tile Map" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Palette Min Width" -msgstr "" +msgstr "Largura MÃnima de Paleta" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -12687,24 +12533,20 @@ msgid "Palette Item H Separation" msgstr "Separador Nomeado" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Names" -msgstr "Mostrar todos os Locales" +msgstr "Mostrar Nomes dos Tiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Show Tile Ids" -msgstr "Mostrar Réguas" +msgstr "Mostrar Ids dos Tiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Sort Tiles By Name" -msgstr "Ordenar arquivos" +msgstr "Ordenar Tiles por Nome" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Bucket Fill Preview" -msgstr "Preenchimento de Balde" +msgstr "Pré-visualização do Preenchimento de Balde" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp @@ -12713,9 +12555,8 @@ msgid "Editor Side" msgstr "Editor" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Display Grid" -msgstr "Exibição Overdraw" +msgstr "Mostrar Grid" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -13081,14 +12922,12 @@ msgstr "Passo" #: editor/plugins/tile_set_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Separation" -msgstr "Separação:" +msgstr "Separação" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Tile" -msgstr "Selecionar" +msgstr "Selecionar Tile" #: editor/plugins/tile_set_editor_plugin.cpp scene/2d/cpu_particles_2d.cpp #: scene/2d/light_2d.cpp scene/2d/line_2d.cpp scene/2d/mesh_instance_2d.cpp @@ -13097,9 +12936,8 @@ msgstr "Selecionar" #: scene/gui/nine_patch_rect.cpp scene/gui/texture_rect.cpp #: scene/resources/material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Texture" -msgstr "Texto" +msgstr "Textura" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13119,9 +12957,8 @@ msgid "Modulate" msgstr "Popular" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tile Mode" -msgstr "Alternar Modo" +msgstr "Modo de Tiles" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13129,14 +12966,12 @@ msgid "Autotile Bitmask Mode" msgstr "Modo Bitmask" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho do Sub TÃtulo" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Subtile Spacing" -msgstr "Loop da Animação" +msgstr "Espaçamento dos Subtiles" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13144,24 +12979,20 @@ msgid "Occluder Offset" msgstr "Criar PolÃgono de Oclusão" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Offset" -msgstr "Modo Navegação" +msgstr "Deslocamento da Navegação" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Offset" -msgstr "Deslocamento Base" +msgstr "Deslocamento da Forma" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Shape Transform" -msgstr "Transformação" +msgstr "Transformação da Forma" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Collision" -msgstr "Colisão" +msgstr "Colisão Selecionada" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -13174,19 +13005,16 @@ msgid "Selected Collision One Way Margin" msgstr "Modo Colisão" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Navigation" -msgstr "Navegação VisÃvel" +msgstr "Navegação Selecionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Selected Occlusion" -msgstr "Selecionar" +msgstr "Oclusão Selecionada" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Tileset Script" -msgstr "Filtrar scripts" +msgstr "Scripts do Tileset" #: editor/plugins/tile_set_editor_plugin.cpp msgid "TileSet" @@ -13265,7 +13093,7 @@ msgstr "Selecione o caminho da chave privada SSH" #: editor/plugins/version_control_editor_plugin.cpp msgid "SSH Passphrase" -msgstr "SSH Passphrase" +msgstr "Senha SSH" #: editor/plugins/version_control_editor_plugin.cpp msgid "Detect new changes" @@ -14274,11 +14102,13 @@ msgstr "Executável" #: editor/project_export.cpp msgid "Export the project for all the presets defined." -msgstr "" +msgstr "Exportar o projeto para todos os presets definidos." #: editor/project_export.cpp msgid "All presets must have an export path defined for Export All to work." msgstr "" +"Todos os presets devem ter um caminho de exportação para que a " +"funcionalidade de Exportar Todos funcione." #: editor/project_export.cpp msgid "Delete preset '%s'?" @@ -14391,11 +14221,12 @@ msgid "" "Note: Encryption key needs to be stored in the binary,\n" "you need to build the export templates from source." msgstr "" +"Nota: Chaves de encriptação têm que ser salvas com o binário,\n" +"você precisa compilar os modelos de exportação à partir do código fonte." #: editor/project_export.cpp -#, fuzzy msgid "More Info..." -msgstr "Mover Para..." +msgstr "Mais Informações..." #: editor/project_export.cpp msgid "Export PCK/Zip..." @@ -14422,18 +14253,16 @@ msgid "ZIP File" msgstr "Arquivo ZIP" #: editor/project_export.cpp -#, fuzzy msgid "Godot Project Pack" -msgstr "Pacote de Jogos Godot" +msgstr "Pacote do Projeto Godot" #: editor/project_export.cpp msgid "Export templates for this platform are missing:" msgstr "Modelos de exportação para esta plataforma não foram encontrados:" #: editor/project_export.cpp -#, fuzzy msgid "Project Export" -msgstr "Fundadores do Projeto" +msgstr "Exportar Projeto" #: editor/project_export.cpp msgid "Manage Export Templates" @@ -14746,7 +14575,6 @@ msgstr "" #. TRANSLATORS: This refers to the application where users manage their Godot projects. #: editor/project_manager.cpp -#, fuzzy msgctxt "Application" msgid "Project Manager" msgstr "Gerenciador de Projetos" @@ -15546,7 +15374,7 @@ msgstr "Tornar Local" #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Another node already uses this unique name in the scene." -msgstr "" +msgstr "Outro nó já está usando este nome único na cena atual." #: editor/scene_tree_dock.cpp #, fuzzy @@ -15632,7 +15460,7 @@ msgstr "Sub-Recursos" #: editor/scene_tree_dock.cpp msgid "Access as Scene Unique Name" -msgstr "" +msgstr "Acessar como Nome Único de Cena" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance" @@ -15737,7 +15565,7 @@ msgstr "Seleção Central" #: editor/scene_tree_dock.cpp msgid "Derive Script Globals By Name" -msgstr "" +msgstr "Obter Globais de Script por Nome" #: editor/scene_tree_dock.cpp #, fuzzy @@ -15770,6 +15598,9 @@ msgid "" "with the '%s' prefix in a node path.\n" "Click to disable this." msgstr "" +"Este nó pode ser acessado em qualquer lugar na cena adicionando o prefixo " +"'%s' em um node path.\n" +"Clique para desabilitar esta funcionalidade." #: editor/scene_tree_editor.cpp msgid "" @@ -16062,15 +15893,15 @@ msgstr "Filtros do tile" #: editor/script_editor_debugger.cpp msgid "Auto Switch To Remote Scene Tree" -msgstr "" +msgstr "Mudar Automaticamente Para a Ãrvore de Cena Remota" #: editor/script_editor_debugger.cpp msgid "Remote Scene Tree Refresh Interval" -msgstr "" +msgstr "Intervalo de Atualização da Ãrvore Remota" #: editor/script_editor_debugger.cpp msgid "Remote Inspect Refresh Interval" -msgstr "" +msgstr "Intervalo de Atualização da Inspeção Remota" #: editor/script_editor_debugger.cpp msgid "Network Profiler" @@ -16168,7 +15999,7 @@ msgstr "Alterar Raio da Luz" #: editor/spatial_editor_gizmos.cpp msgid "Stream Player 3D" -msgstr "" +msgstr "Player de Stream 3D" #: editor/spatial_editor_gizmos.cpp msgid "Change AudioStreamPlayer3D Emission Angle" @@ -16178,7 +16009,7 @@ msgstr "Alterar o Ângulo de Emissão do AudioStreamPlayer3D" #: platform/osx/export/export.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Camera" -msgstr "" +msgstr "Câmera" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" @@ -16190,7 +16021,7 @@ msgstr "Alterar Tamanho da Câmera" #: editor/spatial_editor_gizmos.cpp msgid "Visibility Notifier" -msgstr "" +msgstr "Notificador de Visibilidade" #: editor/spatial_editor_gizmos.cpp msgid "Change Notifier AABB" @@ -16248,9 +16079,8 @@ msgid "Change Ray Shape Length" msgstr "Alterar o Comprimento da Forma do Raio" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Edge" -msgstr "Modo Navegação" +msgstr "Bordas de Navegação" #: editor/spatial_editor_gizmos.cpp #, fuzzy @@ -16258,30 +16088,28 @@ msgid "Navigation Edge Disabled" msgstr "Modo Navegação" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid" -msgstr "Modo Navegação" +msgstr "Navegação Sólida" #: editor/spatial_editor_gizmos.cpp -#, fuzzy msgid "Navigation Solid Disabled" -msgstr "Modo Navegação" +msgstr "Navegação Sólida Desabilitada" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body A" -msgstr "" +msgstr "Corpo de Encaixe A" #: editor/spatial_editor_gizmos.cpp msgid "Joint Body B" -msgstr "" +msgstr "Corpo de Encaixe B" #: editor/spatial_editor_gizmos.cpp msgid "Room Edge" -msgstr "" +msgstr "Canto da Sala" #: editor/spatial_editor_gizmos.cpp msgid "Room Overlap" -msgstr "" +msgstr "Intercessão de Quarto" #: editor/spatial_editor_gizmos.cpp msgid "Set Room Point Position" @@ -16294,11 +16122,11 @@ msgstr "Definir Margem" #: editor/spatial_editor_gizmos.cpp msgid "Portal Edge" -msgstr "" +msgstr "Canto do Portal" #: editor/spatial_editor_gizmos.cpp msgid "Portal Arrow" -msgstr "" +msgstr "Seta do Portal" #: editor/spatial_editor_gizmos.cpp msgid "Set Portal Point Position" @@ -16306,7 +16134,7 @@ msgstr "Definir Posição Do Ponto Do Portal" #: editor/spatial_editor_gizmos.cpp msgid "Portal Front" -msgstr "" +msgstr "Frente do Portal" #: editor/spatial_editor_gizmos.cpp #, fuzzy @@ -16354,12 +16182,12 @@ msgstr "Criar PolÃgono de Oclusão" #: main/main.cpp msgid "Godot Physics" -msgstr "" +msgstr "Godot Physics" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp msgid "Use BVH" -msgstr "" +msgstr "Usar BVH" #: main/main.cpp servers/physics_2d/physics_2d_server_sw.cpp #: servers/visual/visual_server_scene.cpp @@ -16382,37 +16210,36 @@ msgid "RID Pool Prealloc" msgstr "" #: main/main.cpp -#, fuzzy msgid "Debugger stdout" -msgstr "Depurador" +msgstr "Depurador stdout" #: main/main.cpp msgid "Max Chars Per Second" -msgstr "" +msgstr "Máximo de Caracteres por Segundo" #: main/main.cpp msgid "Max Messages Per Frame" -msgstr "" +msgstr "Máximo de Mensagens por Quadro" #: main/main.cpp msgid "Max Errors Per Second" -msgstr "" +msgstr "Máximo de Erros por Segundo" #: main/main.cpp msgid "Max Warnings Per Second" -msgstr "" +msgstr "Máximo de Alertas Por Segundo" #: main/main.cpp msgid "Flush stdout On Print" -msgstr "" +msgstr "Limpar stdout ao Fazer Print" #: main/main.cpp servers/visual_server.cpp msgid "Logging" -msgstr "" +msgstr "Registrando Log" #: main/main.cpp msgid "File Logging" -msgstr "" +msgstr "Registrando Log de Arquivos" #: main/main.cpp #, fuzzy @@ -16426,11 +16253,11 @@ msgstr "Copiar Caminho" #: main/main.cpp msgid "Max Log Files" -msgstr "" +msgstr "Máximo Log de Arquivos" #: main/main.cpp msgid "Driver" -msgstr "" +msgstr "Driver" #: main/main.cpp msgid "Driver Name" @@ -16438,41 +16265,39 @@ msgstr "Nome do Driver" #: main/main.cpp msgid "Fallback To GLES2" -msgstr "" +msgstr "Utilizar GLES2 Como Fallback" #: main/main.cpp msgid "Use Nvidia Rect Flicker Workaround" -msgstr "" +msgstr "Utilizar a Gambiarra \"Nvidia Rect Flicker\"" #: main/main.cpp msgid "DPI" -msgstr "" +msgstr "DPI" #: main/main.cpp msgid "Allow hiDPI" -msgstr "" +msgstr "Permitir hiDPI" #: main/main.cpp -#, fuzzy msgid "V-Sync" -msgstr "Sincronizar" +msgstr "Sincronização Vertical (V-Sync)" #: main/main.cpp -#, fuzzy msgid "Use V-Sync" -msgstr "Use Encaixar" +msgstr "Usar Sincronização Vertical (V-Sync)" #: main/main.cpp msgid "Per Pixel Transparency" -msgstr "" +msgstr "Transparência por Pixel" #: main/main.cpp msgid "Allowed" -msgstr "" +msgstr "Permitido" #: main/main.cpp msgid "Intended Usage" -msgstr "" +msgstr "Intenção de Uso" #: main/main.cpp #, fuzzy @@ -16480,13 +16305,12 @@ msgid "Framebuffer Allocation" msgstr "Seleção de Frame" #: main/main.cpp platform/uwp/os_uwp.cpp -#, fuzzy msgid "Energy Saving" -msgstr "Erro ao salvar" +msgstr "Economia de Energia" #: main/main.cpp msgid "Threads" -msgstr "" +msgstr "Threads" #: main/main.cpp servers/physics_2d/physics_2d_server_wrap_mt.h #, fuzzy @@ -16499,19 +16323,17 @@ msgstr "" #: main/main.cpp msgid "Handheld" -msgstr "" +msgstr "Portátil (Handheld)" #: main/main.cpp platform/javascript/export/export.cpp #: platform/uwp/export/export.cpp -#, fuzzy msgid "Orientation" -msgstr "Documentação Online" +msgstr "Orientação" #: main/main.cpp scene/gui/scroll_container.cpp scene/gui/text_edit.cpp #: scene/main/scene_tree.cpp scene/register_scene_types.cpp -#, fuzzy msgid "Common" -msgstr "Comunidade" +msgstr "Comum" #: main/main.cpp #, fuzzy @@ -16519,27 +16341,26 @@ msgid "Physics FPS" msgstr "Frame de FÃsica %" #: main/main.cpp -#, fuzzy msgid "Force FPS" -msgstr "Forçar Push" +msgstr "Forçar FPS" #: main/main.cpp msgid "Enable Pause Aware Picking" -msgstr "" +msgstr "Habilitar Escolha que é Ciente à Pausas" #: main/main.cpp scene/gui/item_list.cpp scene/gui/popup_menu.cpp #: scene/gui/scroll_container.cpp scene/gui/text_edit.cpp scene/gui/tree.cpp #: scene/main/viewport.cpp scene/register_scene_types.cpp msgid "GUI" -msgstr "" +msgstr "GUI (Interface Gráfica de Usuário)" #: main/main.cpp msgid "Drop Mouse On GUI Input Disabled" -msgstr "" +msgstr "Desabilitar Mouse quando GUI Input estiver Desabilitad" #: main/main.cpp msgid "stdout" -msgstr "" +msgstr "stdout" #: main/main.cpp msgid "Print FPS" @@ -16547,7 +16368,7 @@ msgstr "" #: main/main.cpp msgid "Verbose stdout" -msgstr "" +msgstr "stdout Verboso" #: main/main.cpp scene/main/scene_tree.cpp scene/resources/multimesh.cpp #, fuzzy @@ -16555,9 +16376,8 @@ msgid "Physics Interpolation" msgstr "Modo de Interpolação" #: main/main.cpp -#, fuzzy msgid "Enable Warnings" -msgstr "Habilitar Filtragem" +msgstr "Habilitar Avisos" #: main/main.cpp #, fuzzy @@ -16566,19 +16386,19 @@ msgstr "Seleção de Frame" #: main/main.cpp msgid "Low Processor Mode" -msgstr "" +msgstr "Modo Processamento Baixo" #: main/main.cpp msgid "Delta Sync After Draw" -msgstr "" +msgstr "Sincronizar Delta Após o Draw" #: main/main.cpp msgid "iOS" -msgstr "" +msgstr "iOS" #: main/main.cpp msgid "Hide Home Indicator" -msgstr "" +msgstr "Esconder Indicador de Home" #: main/main.cpp #, fuzzy @@ -16592,16 +16412,15 @@ msgstr "Ponto" #: main/main.cpp msgid "Touch Delay" -msgstr "" +msgstr "Atraso de Touch" #: main/main.cpp servers/visual_server.cpp msgid "GLES3" -msgstr "" +msgstr "GLES3" #: main/main.cpp servers/visual_server.cpp -#, fuzzy msgid "Shaders" -msgstr "Shader" +msgstr "Shaders" #: main/main.cpp #, fuzzy @@ -16611,30 +16430,28 @@ msgstr "Forçar Fallbacks do Shader" #: main/main.cpp scene/3d/baked_lightmap.cpp scene/3d/camera.cpp #: scene/3d/world_environment.cpp scene/main/scene_tree.cpp #: scene/resources/world.cpp -#, fuzzy msgid "Environment" -msgstr "Visualizar Ambiente" +msgstr "Ambiente" #: main/main.cpp msgid "Default Clear Color" -msgstr "" +msgstr "Cor de Limpeza Padrão" #: main/main.cpp msgid "Boot Splash" -msgstr "" +msgstr "Imagem de Exibição ao Iniciar" #: main/main.cpp -#, fuzzy msgid "Show Image" -msgstr "Mostrar Ossos" +msgstr "Mostrar Imagem" #: main/main.cpp msgid "Image" -msgstr "" +msgstr "Imagem" #: main/main.cpp msgid "Fullsize" -msgstr "" +msgstr "Tamanho Inteiro" #: main/main.cpp scene/resources/dynamic_font.cpp msgid "Use Filter" @@ -16646,13 +16463,12 @@ msgid "BG Color" msgstr "Cores" #: main/main.cpp -#, fuzzy msgid "macOS Native Icon" -msgstr "Definir Ãcone de telha" +msgstr "Ãcone Nativo macOS" #: main/main.cpp msgid "Windows Native Icon" -msgstr "" +msgstr "Ãcone Windows Nativo" #: main/main.cpp msgid "Buffering" @@ -16660,29 +16476,27 @@ msgstr "" #: main/main.cpp msgid "Agile Event Flushing" -msgstr "" +msgstr "Limpeza de Eventos Agil" #: main/main.cpp msgid "Emulate Touch From Mouse" -msgstr "" +msgstr "Simular Toque à Partir do Mouse" #: main/main.cpp msgid "Emulate Mouse From Touch" -msgstr "" +msgstr "Simular Mouse à Partir do Touch" #: main/main.cpp -#, fuzzy msgid "Mouse Cursor" -msgstr "Botão do Mouse" +msgstr "Cursor do Mouse" #: main/main.cpp -#, fuzzy msgid "Custom Image" -msgstr "Recortar Nós" +msgstr "Imagem Personalizada" #: main/main.cpp msgid "Custom Image Hotspot" -msgstr "" +msgstr "Imagem Personalizada de Hotspot" #: main/main.cpp msgid "Tooltip Position Offset" @@ -16694,9 +16508,8 @@ msgid "Debugger Agent" msgstr "Depurador" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp -#, fuzzy msgid "Wait For Debugger" -msgstr "Depurador" +msgstr "Esperar pelo Depurador" #: main/main.cpp modules/mono/mono_gd/gd_mono.cpp msgid "Wait Timeout" @@ -16704,11 +16517,11 @@ msgstr "Tempo Limite de Espera" #: main/main.cpp msgid "Runtime" -msgstr "" +msgstr "Tempo de Execução" #: main/main.cpp msgid "Unhandled Exception Policy" -msgstr "" +msgstr "Politica de Tratamento Exceções" #: main/main.cpp #, fuzzy @@ -16717,22 +16530,20 @@ msgstr "Localizar Tipo de Nó" #: main/main.cpp scene/gui/texture_progress.cpp #: scene/gui/viewport_container.cpp -#, fuzzy msgid "Stretch" -msgstr "Buscar" +msgstr "Esticar" #: main/main.cpp -#, fuzzy msgid "Aspect" -msgstr "Inspetor" +msgstr "Aspecto" #: main/main.cpp msgid "Shrink" -msgstr "" +msgstr "Encolher" #: main/main.cpp scene/main/scene_tree.cpp msgid "Auto Accept Quit" -msgstr "" +msgstr "Aceitar Sair Automaticamente" #: main/main.cpp scene/main/scene_tree.cpp #, fuzzy @@ -16746,15 +16557,15 @@ msgstr "Encaixar nos Lados do Nó" #: main/main.cpp msgid "Dynamic Fonts" -msgstr "" +msgstr "Fontes Dinâmicas" #: main/main.cpp msgid "Use Oversampling" -msgstr "" +msgstr "Utilizar Oversampling" #: modules/bullet/register_types.cpp modules/bullet/space_bullet.cpp msgid "Active Soft World" -msgstr "" +msgstr "Ativar Mundo Macio" #: modules/csg/csg_gizmos.cpp msgid "CSG" @@ -16777,35 +16588,30 @@ msgid "Change Torus Outer Radius" msgstr "Alterar Raio Externo do Toro" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Operation" -msgstr "Opções" +msgstr "Operação" #: modules/csg/csg_shape.cpp msgid "Calculate Tangents" -msgstr "" +msgstr "Calcular Tangentes" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Use Collision" -msgstr "Colisão" +msgstr "Usar Colisão" #: modules/csg/csg_shape.cpp servers/physics_2d_server.cpp -#, fuzzy msgid "Collision Layer" -msgstr "Modo Colisão" +msgstr "Camada de Colisão" #: modules/csg/csg_shape.cpp scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp #: scene/3d/ray_cast.cpp scene/3d/spring_arm.cpp #: scene/resources/navigation_mesh.cpp servers/physics_server.cpp -#, fuzzy msgid "Collision Mask" -msgstr "Modo Colisão" +msgstr "Máscara de Colisão" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Invert Faces" -msgstr "Converter MaÃusculas/Minúsculas" +msgstr "Inverter Faces" #: modules/csg/csg_shape.cpp scene/2d/navigation_agent_2d.cpp #: scene/2d/navigation_obstacle_2d.cpp scene/3d/navigation_agent.cpp @@ -16823,14 +16629,12 @@ msgid "Radial Segments" msgstr "Segmentos Radiais" #: modules/csg/csg_shape.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Rings" -msgstr "Avisos" +msgstr "Anéis" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Smooth Faces" -msgstr "Passo suave" +msgstr "Suavizar Faces" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16839,7 +16643,7 @@ msgstr "Mostrar Guias" #: modules/csg/csg_shape.cpp msgid "Cone" -msgstr "" +msgstr "Cone" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16853,27 +16657,25 @@ msgstr "Alterar Raio Externo do Toro" #: modules/csg/csg_shape.cpp msgid "Ring Sides" -msgstr "" +msgstr "Lados de Anel" #: modules/csg/csg_shape.cpp scene/2d/collision_polygon_2d.cpp #: scene/2d/light_occluder_2d.cpp scene/2d/polygon_2d.cpp #: scene/3d/collision_polygon.cpp -#, fuzzy msgid "Polygon" -msgstr "PolÃgonos" +msgstr "PolÃgono" #: modules/csg/csg_shape.cpp msgid "Spin Degrees" -msgstr "" +msgstr "Graus de Rotação" #: modules/csg/csg_shape.cpp msgid "Spin Sides" -msgstr "" +msgstr "Lados de Rotação" #: modules/csg/csg_shape.cpp -#, fuzzy msgid "Path Node" -msgstr "Colar Nós" +msgstr "Caminho do Nó" #: modules/csg/csg_shape.cpp #, fuzzy @@ -16882,11 +16684,11 @@ msgstr "Criar Vertex Interno" #: modules/csg/csg_shape.cpp msgid "Path Interval" -msgstr "" +msgstr "Intervalo de Caminho" #: modules/csg/csg_shape.cpp msgid "Path Simplify Angle" -msgstr "" +msgstr "Ângulo de Simplificação de Caminho" #: modules/csg/csg_shape.cpp msgid "Path Rotation" @@ -16911,58 +16713,52 @@ msgid "Path Joined" msgstr "Caminho Unido" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Compression Mode" -msgstr "Modo Colisão" +msgstr "Modo de Compressão" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Transfer Channel" -msgstr "Alteração de Transformação" +msgstr "Transferir Canal" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Channel Count" -msgstr "Instância" +msgstr "Quantidade de Canais" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Always Ordered" -msgstr "Sempre Mostrar Grade" +msgstr "Sempre Ordenado" #: modules/enet/networked_multiplayer_enet.cpp msgid "Server Relay" -msgstr "" +msgstr "Retransmissor de Servidor" #: modules/enet/networked_multiplayer_enet.cpp msgid "DTLS Verify" -msgstr "" +msgstr "Virificar DTLS" #: modules/enet/networked_multiplayer_enet.cpp msgid "DTLS Hostname" -msgstr "" +msgstr "Nome de Host DTLS" #: modules/enet/networked_multiplayer_enet.cpp -#, fuzzy msgid "Use DTLS" -msgstr "Use Encaixar" +msgstr "Usar DTLS" #: modules/fbx/editor_scene_importer_fbx.cpp msgid "FBX" -msgstr "" +msgstr "FBX" #: modules/fbx/editor_scene_importer_fbx.cpp msgid "Use FBX" -msgstr "" +msgstr "Utilizar FBX" #: modules/gdnative/gdnative.cpp msgid "Config File" msgstr "Arquivo de Configuração" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Load Once" -msgstr "Carregar Recurso" +msgstr "Carregar Apenas uma Vez" #: modules/gdnative/gdnative.cpp #: modules/visual_script/visual_script_func_nodes.cpp @@ -16975,9 +16771,8 @@ msgid "Symbol Prefix" msgstr "Prefixo do SÃmbolo" #: modules/gdnative/gdnative.cpp -#, fuzzy msgid "Reloadable" -msgstr "Recarregar" +msgstr "Recarregável" #: modules/gdnative/gdnative.cpp #: modules/gdnative/gdnative_library_singleton_editor.cpp @@ -17042,9 +16837,8 @@ msgid "Script Class" msgstr "Classe do Script" #: modules/gdnative/nativescript/nativescript.cpp -#, fuzzy msgid "Icon Path" -msgstr "Habilitar" +msgstr "Caminho para Ãcone" #: modules/gdnative/register_types.cpp msgid "GDNative" @@ -17057,7 +16851,7 @@ msgstr "GDScript" #: modules/gdscript/editor/gdscript_highlighter.cpp msgid "Function Definition Color" -msgstr "" +msgstr "Cor de Definição de Função" #: modules/gdscript/editor/gdscript_highlighter.cpp #, fuzzy @@ -17066,19 +16860,19 @@ msgstr "Copiar Caminho do Nó" #: modules/gdscript/gdscript.cpp modules/visual_script/visual_script.cpp msgid "Max Call Stack" -msgstr "" +msgstr "Tamanho Máximo da Pilha de Chamadas de Função" #: modules/gdscript/gdscript.cpp msgid "Treat Warnings As Errors" -msgstr "" +msgstr "Trate Alertas como Erros" #: modules/gdscript/gdscript.cpp msgid "Exclude Addons" -msgstr "" +msgstr "Excluir Addons" #: modules/gdscript/gdscript.cpp msgid "Autocomplete Setters And Getters" -msgstr "" +msgstr "Auto Completar Setters e Getters" #: modules/gdscript/gdscript_functions.cpp msgid "Step argument is zero!" @@ -17129,11 +16923,11 @@ msgstr "Não foi possÃvel resolver" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Show Native Symbols In Editor" -msgstr "" +msgstr "Exibir Simbolos Nativos no Editor" #: modules/gdscript/language_server/gdscript_language_server.cpp msgid "Use Thread" -msgstr "" +msgstr "Utilize Thread" #: modules/gltf/editor_scene_exporter_gltf_plugin.cpp msgid "Export Mesh GLTF2" @@ -17153,9 +16947,8 @@ msgid "Byte Offset" msgstr "Deslocamento do Byte" #: modules/gltf/gltf_accessor.cpp -#, fuzzy msgid "Component Type" -msgstr "Componentes" +msgstr "Tipo do Componente" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17167,14 +16960,12 @@ msgid "Count" msgstr "Quantidade" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Min" -msgstr "MiB" +msgstr "Min" #: modules/gltf/gltf_accessor.cpp scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Max" -msgstr "Misturar" +msgstr "Max" #: modules/gltf/gltf_accessor.cpp #, fuzzy @@ -17216,9 +17007,8 @@ msgid "Byte Stride" msgstr "" #: modules/gltf/gltf_buffer_view.cpp -#, fuzzy msgid "Indices" -msgstr "Todos os dispositivos" +msgstr "Ãndices" #: modules/gltf/gltf_camera.cpp msgid "FOV Size" @@ -17241,19 +17031,17 @@ msgstr "Linear" #: scene/resources/environment.cpp scene/resources/material.cpp #: scene/resources/particles_material.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp -#, fuzzy msgid "Color" -msgstr "Cores" +msgstr "Cor" #: modules/gltf/gltf_light.cpp scene/3d/reflection_probe.cpp #: scene/resources/environment.cpp msgid "Intensity" -msgstr "" +msgstr "Intensidade" #: modules/gltf/gltf_light.cpp scene/2d/light_2d.cpp scene/3d/light.cpp -#, fuzzy msgid "Range" -msgstr "Alterar" +msgstr "Intervalo" #: modules/gltf/gltf_light.cpp msgid "Inner Cone Angle" @@ -17284,35 +17072,31 @@ msgstr "Plataforma" #: modules/gltf/gltf_node.cpp scene/3d/mesh_instance.cpp msgid "Skin" -msgstr "" +msgstr "Skin" #: modules/gltf/gltf_node.cpp scene/3d/spatial.cpp -#, fuzzy msgid "Translation" -msgstr "Traduções" +msgstr "Tradução" #: modules/gltf/gltf_node.cpp -#, fuzzy msgid "Children" -msgstr "Filhos Editáveis" +msgstr "Filhos" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints" -msgstr "Ponto" +msgstr "Pontos" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_skin.cpp msgid "Roots" -msgstr "" +msgstr "RaÃzes" #: modules/gltf/gltf_skeleton.cpp modules/gltf/gltf_state.cpp msgid "Unique Names" -msgstr "" +msgstr "Nomes Únicos" #: modules/gltf/gltf_skeleton.cpp -#, fuzzy msgid "Godot Bone Node" -msgstr "Nó TimeSeek" +msgstr "Nó de Osso Godot" #: modules/gltf/gltf_skin.cpp #, fuzzy @@ -17320,9 +17104,8 @@ msgid "Skin Root" msgstr "Nova Raiz de Cena" #: modules/gltf/gltf_skin.cpp -#, fuzzy msgid "Joints Original" -msgstr "Origem do Foco" +msgstr "Pontos Originais" #: modules/gltf/gltf_skin.cpp msgid "Inverse Binds" @@ -17367,12 +17150,11 @@ msgstr "" #: modules/gltf/gltf_state.cpp msgid "Json" -msgstr "" +msgstr "Json" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Major Version" -msgstr "Versão" +msgstr "Versão Importante" #: modules/gltf/gltf_state.cpp #, fuzzy @@ -17402,28 +17184,25 @@ msgid "Scene Name" msgstr "Nome da Cena" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Root Nodes" -msgstr "Nome do nó raiz" +msgstr "Nós RaÃzes" #: modules/gltf/gltf_state.cpp scene/2d/particles_2d.cpp #: scene/gui/texture_button.cpp scene/gui/texture_progress.cpp -#, fuzzy msgid "Textures" -msgstr "Funcionalidades" +msgstr "Texturas" #: modules/gltf/gltf_state.cpp platform/uwp/export/export.cpp msgid "Images" -msgstr "" +msgstr "Imagens" #: modules/gltf/gltf_state.cpp msgid "Cameras" -msgstr "" +msgstr "Câmeras" #: modules/gltf/gltf_state.cpp servers/visual_server.cpp -#, fuzzy msgid "Lights" -msgstr "Luz" +msgstr "Luzes" #: modules/gltf/gltf_state.cpp msgid "Unique Animation Names" @@ -17434,9 +17213,8 @@ msgid "Skeletons" msgstr "Esqueletos" #: modules/gltf/gltf_state.cpp -#, fuzzy msgid "Skeleton To Node" -msgstr "Selecione um Nó" +msgstr "Esqueleto Para Nó" #: modules/gltf/gltf_state.cpp msgid "Animations" @@ -17463,7 +17241,7 @@ msgstr "Faça mapas de luz" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp msgid "Cell" -msgstr "" +msgstr "Célula" #: modules/gridmap/grid_map.cpp #, fuzzy @@ -17471,25 +17249,22 @@ msgid "Octant Size" msgstr "Visão Frontal" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center X" -msgstr "Centro" +msgstr "Centro X" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Y" -msgstr "Centro" +msgstr "Centro Y" #: modules/gridmap/grid_map.cpp -#, fuzzy msgid "Center Z" -msgstr "Centro" +msgstr "Centro Z" #: modules/gridmap/grid_map.cpp scene/2d/collision_object_2d.cpp #: scene/2d/tile_map.cpp scene/3d/collision_object.cpp scene/3d/soft_body.cpp #: scene/resources/material.cpp msgid "Mask" -msgstr "" +msgstr "Máscara" #: modules/gridmap/grid_map.cpp scene/2d/tile_map.cpp #, fuzzy @@ -17500,9 +17275,8 @@ msgstr "Navegação" #: scene/2d/navigation_agent_2d.cpp scene/2d/navigation_polygon.cpp #: scene/2d/tile_map.cpp scene/3d/navigation.cpp scene/3d/navigation_agent.cpp #: scene/3d/navigation_mesh_instance.cpp -#, fuzzy msgid "Navigation Layers" -msgstr "Modo Navegação" +msgstr "Camadas da Navegação" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Plane" @@ -17804,7 +17578,7 @@ msgstr "Pronto!" #: modules/opensimplex/noise_texture.cpp msgid "Seamless" -msgstr "" +msgstr "Sem Emenda" #: modules/opensimplex/noise_texture.cpp msgid "As Normal Map" @@ -17824,7 +17598,7 @@ msgstr "Deslocamento do RuÃdo" #: modules/opensimplex/open_simplex_noise.cpp msgid "Octaves" -msgstr "" +msgstr "Oitavas" #: modules/opensimplex/open_simplex_noise.cpp msgid "Period" @@ -17841,7 +17615,7 @@ msgstr "" #: modules/regex/regex.cpp msgid "Subject" -msgstr "" +msgstr "Sujeito" #: modules/regex/regex.cpp #, fuzzy @@ -18293,7 +18067,7 @@ msgstr "Iterador" #: modules/visual_script/visual_script_flow_control.cpp msgid "for (elem) in (input):" -msgstr "" +msgstr "para (elem) em (input):" #: modules/visual_script/visual_script_flow_control.cpp msgid "Input type not iterable:" @@ -18327,7 +18101,7 @@ msgstr "Switch" #: modules/visual_script/visual_script_flow_control.cpp msgid "'input' is:" -msgstr "" +msgstr "'input' é:" #: modules/visual_script/visual_script_flow_control.cpp msgid "Type Cast" @@ -18579,7 +18353,7 @@ msgstr "Chamadas" #: modules/visual_script/visual_script_nodes.cpp scene/gui/graph_node.cpp msgid "Title" -msgstr "" +msgstr "TÃtulo" #: modules/visual_script/visual_script_nodes.cpp #, fuzzy @@ -18658,7 +18432,7 @@ msgstr "Modo Prioridade" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" -msgstr "" +msgstr "WebRTC" #: modules/webrtc/webrtc_data_channel.h #, fuzzy @@ -18892,7 +18666,7 @@ msgstr "Inspecionar a Instância Anterior" #: platform/android/export/export_plugin.cpp msgid "Code" -msgstr "" +msgstr "Código" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp #, fuzzy @@ -18985,7 +18759,7 @@ msgstr "Interface de Usuário" #: platform/android/export/export_plugin.cpp msgid "Allow" -msgstr "" +msgstr "Permitir" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp #, fuzzy @@ -19003,7 +18777,7 @@ msgstr "Expressão" #: platform/android/export/export_plugin.cpp msgid "Salt" -msgstr "" +msgstr "Sal" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -19298,10 +19072,8 @@ msgstr "" "do projeto" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "" -"Não foi possÃvel exportar os arquivos do projeto ao projeto do gradle\n" +msgstr "Não foi possÃvel exportar os arquivos do projeto ao projeto do gradle" #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -19385,19 +19157,19 @@ msgstr "" #: platform/iphone/export/export.cpp msgid "iPhone 2436 X 1125" -msgstr "" +msgstr "IPhone 2436 X 1125" #: platform/iphone/export/export.cpp msgid "iPhone 2208 X 1242" -msgstr "" +msgstr "iPhone 2208 X 1242" #: platform/iphone/export/export.cpp msgid "iPad 1024 X 768" -msgstr "" +msgstr "iPad 1024 X 768" #: platform/iphone/export/export.cpp msgid "iPad 2048 X 1536" -msgstr "" +msgstr "iPad 2048 X 1536" #: platform/iphone/export/export.cpp msgid "Portrait Launch Screens" @@ -19405,31 +19177,31 @@ msgstr "" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 960" -msgstr "" +msgstr "iPhone 640 X 960" #: platform/iphone/export/export.cpp msgid "iPhone 640 X 1136" -msgstr "" +msgstr "iPhone 640 X 1136" #: platform/iphone/export/export.cpp msgid "iPhone 750 X 1334" -msgstr "" +msgstr "iPhone 750 X 1334" #: platform/iphone/export/export.cpp msgid "iPhone 1125 X 2436" -msgstr "" +msgstr "iPhone 1125 X 2436" #: platform/iphone/export/export.cpp msgid "iPad 768 X 1024" -msgstr "" +msgstr "iPad 768 X 1024" #: platform/iphone/export/export.cpp msgid "iPad 1536 X 2048" -msgstr "" +msgstr "iPad 1536 X 2048" #: platform/iphone/export/export.cpp msgid "iPhone 1242 X 2208" -msgstr "" +msgstr "iPhone 1242 X 2208" #: platform/iphone/export/export.cpp msgid "App Store Team ID" @@ -19466,7 +19238,7 @@ msgstr "" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Info" -msgstr "" +msgstr "Informação" #: platform/iphone/export/export.cpp platform/osx/export/export.cpp msgid "Identifier" @@ -19536,23 +19308,23 @@ msgstr "Descrições da Propriedade" #: platform/iphone/export/export.cpp msgid "iPhone 120 X 120" -msgstr "" +msgstr "iPhone 120 X 120" #: platform/iphone/export/export.cpp msgid "iPhone 180 X 180" -msgstr "" +msgstr "iPhone 180 X 180" #: platform/iphone/export/export.cpp msgid "iPad 76 X 76" -msgstr "" +msgstr "iPad 76 X 76" #: platform/iphone/export/export.cpp msgid "iPad 152 X 152" -msgstr "" +msgstr "iPad 152 X 152" #: platform/iphone/export/export.cpp msgid "iPad 167 X 167" -msgstr "" +msgstr "iPad 167 X 167" #: platform/iphone/export/export.cpp msgid "App Store 1024 X 1024" @@ -19636,14 +19408,12 @@ msgid "Could not open template for export: \"%s\"." msgstr "Não foi possÃvel abrir o modelo para exportação: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Invalid export template: \"%s\"." -msgstr "Template de exportação inválido:" +msgstr "Template de exportação inválido: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not write file: \"%s\"." -msgstr "Não foi possÃvel escrever o arquivo:" +msgstr "Não foi possÃvel escrever o arquivo: \"%s\"." #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #, fuzzy @@ -19656,7 +19426,7 @@ msgstr "Não foi possÃvel ler o arquivo: \"%s\"." #: platform/javascript/export/export.cpp msgid "PWA" -msgstr "" +msgstr "PWA" #: platform/javascript/export/export.cpp msgid "Variant" @@ -19674,15 +19444,15 @@ msgstr "Expressão" #: platform/javascript/export/export.cpp msgid "For Desktop" -msgstr "" +msgstr "Para Desktop" #: platform/javascript/export/export.cpp msgid "For Mobile" -msgstr "" +msgstr "Para Mobile" #: platform/javascript/export/export.cpp msgid "HTML" -msgstr "" +msgstr "HTML" #: platform/javascript/export/export.cpp #, fuzzy @@ -19703,8 +19473,9 @@ msgid "Canvas Resize Policy" msgstr "" #: platform/javascript/export/export.cpp +#, fuzzy msgid "Focus Canvas On Start" -msgstr "" +msgstr "Focar Canvas ao Iniciar" #: platform/javascript/export/export.cpp #, fuzzy @@ -19713,11 +19484,11 @@ msgstr "Filtrar sinais" #: platform/javascript/export/export.cpp msgid "Progressive Web App" -msgstr "" +msgstr "Progressive Web App" #: platform/javascript/export/export.cpp msgid "Offline Page" -msgstr "" +msgstr "Página Offline" #: platform/javascript/export/export.cpp msgid "Icon 144 X 144" @@ -19736,9 +19507,8 @@ msgid "Could not read HTML shell: \"%s\"." msgstr "Não foi possÃvel ler o shell HTML: \"%s\"." #: platform/javascript/export/export.cpp -#, fuzzy msgid "Could not create HTTP server directory: %s." -msgstr "Não foi possÃvel criar o diretório do servidor HTTP:" +msgstr "Não foi possÃvel criar o diretório do servidor HTTP: \"%s\"." #: platform/javascript/export/export.cpp msgid "Error starting HTTP server: %d." @@ -19746,7 +19516,7 @@ msgstr "Erro ao iniciar o servidor HTTP: %d." #: platform/javascript/export/export.cpp msgid "Web" -msgstr "" +msgstr "Web" #: platform/javascript/export/export.cpp msgid "HTTP Host" @@ -19763,7 +19533,7 @@ msgstr "Use Encaixar" #: platform/javascript/export/export.cpp msgid "SSL Key" -msgstr "" +msgstr "Chave SSL" #: platform/osx/export/codesign.cpp msgid "Can't get filesystem access." @@ -19803,7 +19573,7 @@ msgstr "Caminho base inválido." #: platform/osx/export/codesign.cpp msgid "Already signed!" -msgstr "" +msgstr "Já assinado!" #: platform/osx/export/codesign.cpp #, fuzzy @@ -19843,7 +19613,7 @@ msgstr "" #: platform/osx/export/codesign.cpp msgid "Unknown object type." -msgstr "" +msgstr "Tipo de objeto desconhecido." #: platform/osx/export/export.cpp msgid "App Category" @@ -19851,7 +19621,7 @@ msgstr "Categoria do Aplicativo" #: platform/osx/export/export.cpp msgid "High Res" -msgstr "" +msgstr "Alta Resolução" #: platform/osx/export/export.cpp #, fuzzy @@ -19931,7 +19701,7 @@ msgstr "Recortar Nós" #: platform/osx/export/export.cpp msgid "Allow JIT Code Execution" -msgstr "" +msgstr "Permitir Execução de Código JIT" #: platform/osx/export/export.cpp msgid "Allow Unsigned Executable Memory" @@ -19953,7 +19723,7 @@ msgstr "Adicionar Entrada" #: platform/osx/export/export.cpp msgid "Address Book" -msgstr "" +msgstr "Contatos" #: platform/osx/export/export.cpp msgid "Calendars" @@ -19995,7 +19765,7 @@ msgstr "Dispositivo" #: platform/osx/export/export.cpp msgid "Device Bluetooth" -msgstr "" +msgstr "Bluetooth do Dispositivo" #: platform/osx/export/export.cpp #, fuzzy @@ -20067,6 +19837,8 @@ msgid "" "You can check progress manually by opening a Terminal and running the " "following command:" msgstr "" +"Você pode verificar o progresso manualmente abrindo um Terminal e rodando o " +"seguinte comando:" #: platform/osx/export/export.cpp msgid "" @@ -20096,6 +19868,8 @@ msgid "" "Could not start codesign executable, make sure Xcode command line tools are " "installed." msgstr "" +"Não foi possÃvel iniciar o executável codesign, tenha certeza que as " +"utilidades de linha de comando do Xcode estão instaladas." #: platform/osx/export/export.cpp platform/windows/export/export.cpp #, fuzzy @@ -20156,7 +19930,7 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Making PKG" -msgstr "" +msgstr "Criando PKG" #: platform/osx/export/export.cpp msgid "" @@ -20170,7 +19944,7 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Making DMG" -msgstr "" +msgstr "Criando DMG" #: platform/osx/export/export.cpp msgid "Code signing DMG" @@ -20178,7 +19952,7 @@ msgstr "" #: platform/osx/export/export.cpp msgid "Making ZIP" -msgstr "" +msgstr "Criando ZIP" #: platform/osx/export/export.cpp msgid "" @@ -20341,7 +20115,7 @@ msgstr "Nome Curto" #: platform/uwp/export/export.cpp msgid "Publisher" -msgstr "" +msgstr "Publicadora" #: platform/uwp/export/export.cpp msgid "Publisher Display Name" @@ -20389,7 +20163,7 @@ msgstr "Revisão" #: platform/uwp/export/export.cpp msgid "Landscape" -msgstr "" +msgstr "Paisagem" #: platform/uwp/export/export.cpp #, fuzzy @@ -20398,11 +20172,11 @@ msgstr "Inverter Horizontalmente" #: platform/uwp/export/export.cpp msgid "Landscape Flipped" -msgstr "" +msgstr "Paisagem Invertido" #: platform/uwp/export/export.cpp msgid "Portrait Flipped" -msgstr "" +msgstr "Retrato Invertido" #: platform/uwp/export/export.cpp #, fuzzy @@ -20504,7 +20278,7 @@ msgstr "Dimensões inválidas da tela de abertura (deve ser 620x300)." #: platform/uwp/export/export.cpp msgid "UWP" -msgstr "" +msgstr "UWP" #: platform/uwp/export/export.cpp platform/windows/export/export.cpp #, fuzzy @@ -20521,13 +20295,13 @@ msgid "Debug Algorithm" msgstr "Depurador" #: platform/windows/export/export.cpp -#, fuzzy msgid "Failed to rename temporary file \"%s\"." -msgstr "Não é possÃvel remover o arquivo temporário:" +msgstr "Falha ao renomear arquivo temporário \"%s\"." #: platform/windows/export/export.cpp +#, fuzzy msgid "Identity Type" -msgstr "" +msgstr "Tipo de Identidade" #: platform/windows/export/export.cpp msgid "Timestamp Server URL" @@ -20567,7 +20341,7 @@ msgstr "Descrição" #: platform/windows/export/export.cpp msgid "Trademarks" -msgstr "" +msgstr "Marca Registrada (Trademarks)" #: platform/windows/export/export.cpp #, fuzzy @@ -20673,7 +20447,7 @@ msgstr "Nova Janela" #: platform/windows/export/export.cpp msgid "Rcedit" -msgstr "" +msgstr "Rcedit" #: platform/windows/export/export.cpp msgid "Osslsigncode" @@ -20872,7 +20646,7 @@ msgstr "Modo de Movimentação" #: scene/2d/camera_2d.cpp msgid "Limit" -msgstr "" +msgstr "Limite" #: scene/2d/camera_2d.cpp scene/gui/control.cpp scene/gui/nine_patch_rect.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp @@ -21172,7 +20946,7 @@ msgstr "" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp msgid "Drawing" -msgstr "" +msgstr "Desenhando" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp @@ -21183,7 +20957,7 @@ msgstr "Projetos Locais" #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/particles.cpp msgid "Draw Order" -msgstr "" +msgstr "Ordem de Desenho" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21240,7 +21014,7 @@ msgstr "Velocidade" #: scene/resources/particles_material.cpp servers/physics_2d_server.cpp #: servers/physics_server.cpp msgid "Angular Velocity" -msgstr "" +msgstr "Velocidade Angular" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21309,7 +21083,7 @@ msgstr "Dvidir Curva" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp scene/3d/light.cpp #: scene/resources/particles_material.cpp msgid "Angle" -msgstr "" +msgstr "Ângulo" #: scene/2d/cpu_particles_2d.cpp scene/3d/cpu_particles.cpp #: scene/resources/particles_material.cpp @@ -21435,7 +21209,7 @@ msgstr "" #: scene/2d/joints_2d.cpp scene/resources/animation.cpp #: scene/resources/ray_shape.cpp scene/resources/segment_shape_2d.cpp msgid "Length" -msgstr "" +msgstr "Comprimento" #: scene/2d/joints_2d.cpp #, fuzzy @@ -21471,7 +21245,7 @@ msgstr "Região da Textura" #: scene/3d/light.cpp scene/resources/environment.cpp #: scene/resources/material.cpp scene/resources/sky.cpp msgid "Energy" -msgstr "" +msgstr "Energia" #: scene/2d/light_2d.cpp msgid "Z Min" @@ -21549,7 +21323,7 @@ msgstr "Padrão" #: scene/2d/line_2d.cpp scene/resources/texture.cpp msgid "Fill" -msgstr "" +msgstr "Preencher" #: scene/2d/line_2d.cpp scene/resources/texture.cpp #, fuzzy @@ -21894,7 +21668,7 @@ msgstr "" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Mass" -msgstr "" +msgstr "Massa" #: scene/2d/physics_body_2d.cpp msgid "Inertia" @@ -21943,7 +21717,7 @@ msgstr "Úmido" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp msgid "Angular" -msgstr "" +msgstr "Angular" #: scene/2d/physics_body_2d.cpp msgid "Applied Forces" @@ -22056,15 +21830,15 @@ msgstr "Criar Nó Shader" #: scene/2d/ray_cast_2d.cpp scene/3d/ray_cast.cpp msgid "Collide With" -msgstr "" +msgstr "Colidir com" #: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp msgid "Areas" -msgstr "" +msgstr "Ãreas" #: scene/2d/ray_cast_2d.cpp scene/3d/camera.cpp scene/3d/ray_cast.cpp msgid "Bodies" -msgstr "" +msgstr "Corpos" #: scene/2d/remote_transform_2d.cpp msgid "Path property must point to a valid Node2D node to work." @@ -22306,15 +22080,15 @@ msgstr "Nó de Animação" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit dB" -msgstr "" +msgstr "Unidade dB" #: scene/3d/audio_stream_player_3d.cpp msgid "Unit Size" -msgstr "" +msgstr "Tamanho da Unidade" #: scene/3d/audio_stream_player_3d.cpp msgid "Max dB" -msgstr "" +msgstr "Max dB" #: scene/3d/audio_stream_player_3d.cpp msgid "Out Of Range Mode" @@ -22362,7 +22136,7 @@ msgstr "Empacotando" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp #: scene/3d/reflection_probe.cpp msgid "Interior" -msgstr "" +msgstr "Interior" #: scene/3d/baked_lightmap.cpp msgid "Finding meshes and lights" @@ -22413,7 +22187,7 @@ msgstr "Usar Redutor de RuÃdo" #: scene/3d/baked_lightmap.cpp scene/resources/texture.cpp msgid "Use HDR" -msgstr "" +msgstr "Usar HDR" #: scene/3d/baked_lightmap.cpp #, fuzzy @@ -22512,7 +22286,7 @@ msgstr "Mais próximo" #: scene/3d/camera.cpp msgid "Far" -msgstr "" +msgstr "Longe" #: scene/3d/camera.cpp scene/3d/collision_polygon.cpp scene/3d/spring_arm.cpp #: scene/gui/control.cpp scene/resources/default_theme/default_theme.cpp @@ -22764,9 +22538,8 @@ msgid "Font" msgstr "Fontes" #: scene/3d/label_3d.cpp scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Horizontal Alignment" -msgstr "Horizontal:" +msgstr "Alinhamento Horizontal" #: scene/3d/label_3d.cpp #, fuzzy @@ -22877,6 +22650,8 @@ msgid "" "be removed in a future version. Use 'NavigationServer.map_get_path()' " "instead." msgstr "" +"O nó 'Navigation' e 'Navigation.get_simple_path()' estão depreciados e serão " +"removidos em versões futuras. Use 'NavigationServer.map_get_path()' no lugar." #: scene/3d/navigation.cpp scene/resources/curve.cpp #, fuzzy @@ -23131,15 +22906,15 @@ msgstr "Animação" #: scene/3d/physics_body.cpp msgid "X" -msgstr "" +msgstr "X" #: scene/3d/physics_body.cpp msgid "Y" -msgstr "" +msgstr "Y" #: scene/3d/physics_body.cpp msgid "Z" -msgstr "" +msgstr "Z" #: scene/3d/physics_body.cpp #, fuzzy @@ -23456,7 +23231,7 @@ msgstr "Depurador" #: scene/3d/ray_cast.cpp scene/resources/style_box.cpp msgid "Thickness" -msgstr "" +msgstr "Espessura" #: scene/3d/reflection_probe.cpp scene/main/viewport.cpp #, fuzzy @@ -23563,7 +23338,7 @@ msgstr "Só Deve existir um RoomManager na SceneTree." #: scene/3d/room_manager.cpp msgid "Main" -msgstr "" +msgstr "Principal" #: scene/3d/room_manager.cpp scene/animation/animation_blend_tree.cpp #: scene/animation/animation_player.cpp scene/animation/animation_tree.cpp @@ -23789,7 +23564,7 @@ msgstr "Manter Transformação Global" #: scene/3d/spatial.cpp msgid "Matrix" -msgstr "" +msgstr "Matriz" #: scene/3d/spatial.cpp #, fuzzy @@ -23807,7 +23582,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp scene/gui/graph_edit.cpp msgid "Opacity" -msgstr "" +msgstr "Opacidade" #: scene/3d/sprite_3d.cpp scene/resources/material.cpp msgid "Transparent" @@ -23906,9 +23681,8 @@ msgid "Cast Shadow" msgstr "Criar Nó Shader" #: scene/3d/visual_instance.cpp -#, fuzzy msgid "Extra Cull Margin" -msgstr "Argumentos de Chamada Extras:" +msgstr "Margem de Descarte Extra" #: scene/3d/visual_instance.cpp #, fuzzy @@ -23930,9 +23704,8 @@ msgstr "" #: scene/3d/visual_instance.cpp scene/animation/skeleton_ik.cpp #: scene/resources/material.cpp -#, fuzzy msgid "Min Distance" -msgstr "Escolha uma Distância:" +msgstr "Distância MÃnima" #: scene/3d/visual_instance.cpp msgid "Min Hysteresis" @@ -23979,33 +23752,28 @@ msgid "Mix Mode" msgstr "Nó Mix" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Fadein Time" -msgstr "Tempo do X-Fade (s):" +msgstr "Tempo de Esmaecer de Entrada" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Fadeout Time" -msgstr "Tempo do X-Fade (s):" +msgstr "Tempo de Esmaecer de SaÃda" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Auto Restart" -msgstr "ReinÃcio Automático:" +msgstr "ReinÃcio Automático" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Autorestart" -msgstr "ReinÃcio Automático:" +msgstr "ReinÃcio Automático" #: scene/animation/animation_blend_tree.cpp msgid "Delay" -msgstr "" +msgstr "Atraso" #: scene/animation/animation_blend_tree.cpp -#, fuzzy msgid "Random Delay" -msgstr "Inclinação aleatória:" +msgstr "Atraso Aleatório" #: scene/animation/animation_blend_tree.cpp #, fuzzy @@ -24029,9 +23797,8 @@ msgstr "Adicionar porta de entrada" #: scene/animation/animation_blend_tree.cpp #: scene/animation/animation_node_state_machine.cpp -#, fuzzy msgid "Xfade Time" -msgstr "Tempo do X-Fade (s):" +msgstr "Tempo do Esmaecer Cruzado" #: scene/animation/animation_node_state_machine.cpp #, fuzzy @@ -24064,7 +23831,7 @@ msgstr "Adicionar Animação" #: scene/animation/animation_player.cpp msgid "Reset On Save" -msgstr "" +msgstr "Redefinir ao Salvar" #: scene/animation/animation_player.cpp #, fuzzy @@ -24077,9 +23844,8 @@ msgid "Current Animation Position" msgstr "Adicionar ponto de Animação" #: scene/animation/animation_player.cpp -#, fuzzy msgid "Playback Options" -msgstr "Opções da Classe:" +msgstr "Opções de Playback" #: scene/animation/animation_player.cpp #, fuzzy @@ -24122,9 +23888,8 @@ msgid "The AnimationPlayer root node is not a valid node." msgstr "O nó raiz do AnimationPlayer não é um nó válido." #: scene/animation/animation_tree.cpp -#, fuzzy msgid "Tree Root" -msgstr "Criar nó raiz:" +msgstr "Nó Raiz" #: scene/animation/animation_tree.cpp #, fuzzy @@ -24234,7 +23999,7 @@ msgstr "Modo de Seleção" #: scene/gui/aspect_ratio_container.cpp scene/gui/box_container.cpp msgid "Alignment" -msgstr "" +msgstr "Alinhamento" #: scene/gui/base_button.cpp #, fuzzy @@ -24272,11 +24037,11 @@ msgstr "Copiar Texto" #: scene/gui/button.cpp scene/gui/label.cpp scene/gui/line_edit.cpp #: scene/gui/spin_box.cpp msgid "Align" -msgstr "" +msgstr "Alinhar" #: scene/gui/button.cpp msgid "Icon Align" -msgstr "" +msgstr "Alinhamento do Ãcone" #: scene/gui/button.cpp #, fuzzy @@ -24380,14 +24145,12 @@ msgid "Grow Direction" msgstr "Direções" #: scene/gui/control.cpp scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Min Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho MÃnimo" #: scene/gui/control.cpp -#, fuzzy msgid "Pivot Offset" -msgstr "Deslocamento da Grade:" +msgstr "Deslocamento do Pivô" #: scene/gui/control.cpp #, fuzzy @@ -24435,7 +24198,7 @@ msgstr "Anterior" #: scene/gui/control.cpp msgid "Mouse" -msgstr "" +msgstr "Mouse" #: scene/gui/control.cpp msgid "Default Cursor Shape" @@ -24461,7 +24224,7 @@ msgstr "Propriedades do Tema" #: scene/gui/dialogs.cpp msgid "Window Title" -msgstr "" +msgstr "TÃtulo da Janela" #: scene/gui/dialogs.cpp #, fuzzy @@ -24495,14 +24258,12 @@ msgid "Right Disconnects" msgstr "Desconectar" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Scroll Offset" -msgstr "Deslocamento da Grade:" +msgstr "Deslocamento da Rolagem" #: scene/gui/graph_edit.cpp -#, fuzzy msgid "Snap Distance" -msgstr "Escolha uma Distância:" +msgstr "Distância de Encaixe" #: scene/gui/graph_edit.cpp #, fuzzy @@ -24527,7 +24288,7 @@ msgstr "Mostrar Ossos" #: scene/gui/graph_edit.cpp scene/gui/text_edit.cpp #: scene/resources/default_theme/default_theme.cpp msgid "Minimap" -msgstr "" +msgstr "Mini-Mapa" #: scene/gui/graph_edit.cpp msgid "Enable grid minimap." @@ -24600,9 +24361,8 @@ msgid "Fixed Column Width" msgstr "" #: scene/gui/item_list.cpp -#, fuzzy msgid "Icon Scale" -msgstr "Escala aleatória:" +msgstr "Escala de Ãcone" #: scene/gui/item_list.cpp #, fuzzy @@ -24615,9 +24375,8 @@ msgid "V Align" msgstr "Atribuir" #: scene/gui/label.cpp scene/gui/rich_text_label.cpp -#, fuzzy msgid "Visible Characters" -msgstr "Caracteres válidos:" +msgstr "Caracteres Visiveis" #: scene/gui/label.cpp scene/gui/rich_text_label.cpp #, fuzzy @@ -24641,9 +24400,8 @@ msgid "Secret" msgstr "" #: scene/gui/line_edit.cpp -#, fuzzy msgid "Secret Character" -msgstr "Caracteres válidos:" +msgstr "Caracteres Secretos" #: scene/gui/line_edit.cpp msgid "Expand To Text Length" @@ -24704,16 +24462,15 @@ msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Blink" -msgstr "" +msgstr "Piscar" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Blink Speed" -msgstr "Velocidade:" +msgstr "Velocidade de Piscar" #: scene/gui/link_button.cpp msgid "Underline" -msgstr "" +msgstr "Sublinhado" #: scene/gui/menu_button.cpp #, fuzzy @@ -24796,9 +24553,8 @@ msgid "Allow Search" msgstr "Pesquisar" #: scene/gui/progress_bar.cpp -#, fuzzy msgid "Percent" -msgstr "Recente:" +msgstr "Porcentagem" #: scene/gui/range.cpp msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." @@ -24858,9 +24614,8 @@ msgid "Absolute Index" msgstr "Auto Recuar" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Elapsed Time" -msgstr "Tempos de Mistura:" +msgstr "Tempo Decorrido" #: scene/gui/rich_text_effect.cpp #, fuzzy @@ -24868,9 +24623,8 @@ msgid "Env" msgstr "Fim" #: scene/gui/rich_text_effect.cpp -#, fuzzy msgid "Character" -msgstr "Caracteres válidos:" +msgstr "Caractere" #: scene/gui/rich_text_label.cpp msgid "BBCode" @@ -24881,9 +24635,8 @@ msgid "Meta Underlined" msgstr "" #: scene/gui/rich_text_label.cpp -#, fuzzy msgid "Tab Size" -msgstr "Tamanho:" +msgstr "Tamanho da Tabulação" #: scene/gui/rich_text_label.cpp #, fuzzy @@ -24904,9 +24657,8 @@ msgid "Selection Enabled" msgstr "Selecionar Apenas" #: scene/gui/rich_text_label.cpp scene/gui/text_edit.cpp -#, fuzzy msgid "Override Selected Font Color" -msgstr "Configurar Perfil Selecionado:" +msgstr "Sobrescrever Cor da Fonte Selecionada" #: scene/gui/rich_text_label.cpp #, fuzzy @@ -24934,9 +24686,8 @@ msgid "Follow Focus" msgstr "Popular SuperfÃcie" #: scene/gui/scroll_container.cpp -#, fuzzy msgid "Horizontal Enabled" -msgstr "Horizontal:" +msgstr "Horizontal Habilitado" #: scene/gui/scroll_container.cpp #, fuzzy @@ -24957,24 +24708,20 @@ msgid "Tick Count" msgstr "Escolher Cor" #: scene/gui/slider.cpp -#, fuzzy msgid "Ticks On Borders" -msgstr "Renomear pasta:" +msgstr "Pontos Nas Bordas" #: scene/gui/spin_box.cpp -#, fuzzy msgid "Prefix" -msgstr "Prefixo:" +msgstr "Prefixo" #: scene/gui/spin_box.cpp -#, fuzzy msgid "Suffix" -msgstr "Sufixo:" +msgstr "Sufixo" #: scene/gui/split_container.cpp -#, fuzzy msgid "Split Offset" -msgstr "Deslocamento da Grade:" +msgstr "Deslocamento de Divisão" #: scene/gui/split_container.cpp scene/gui/tree.cpp #, fuzzy @@ -24991,9 +24738,8 @@ msgid "Tab Align" msgstr "" #: scene/gui/tab_container.cpp scene/gui/tabs.cpp -#, fuzzy msgid "Current Tab" -msgstr "Atual:" +msgstr "Aba Atual" #: scene/gui/tab_container.cpp #, fuzzy @@ -25035,9 +24781,8 @@ msgid "Breakpoint Gutter" msgstr "Pular Breakpoints" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Fold Gutter" -msgstr "Pasta:" +msgstr "Espaçamento de Dobra" #: scene/gui/text_edit.cpp #, fuzzy @@ -25055,19 +24800,16 @@ msgid "Wrap Enabled" msgstr "Habilitar" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Scroll Vertical" -msgstr "Vertical:" +msgstr "Scroll Vertical" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Scroll Horizontal" -msgstr "Horizontal:" +msgstr "Scroll Horizontal" #: scene/gui/text_edit.cpp -#, fuzzy msgid "Draw" -msgstr "Chamadas de Desenho:" +msgstr "Desenhar" #: scene/gui/text_edit.cpp #, fuzzy @@ -25125,9 +24867,8 @@ msgid "Progress Offset" msgstr "" #: scene/gui/texture_progress.cpp -#, fuzzy msgid "Fill Mode" -msgstr "Modo Panorâmico:" +msgstr "Modo de Preenchimento" #: scene/gui/texture_progress.cpp scene/resources/material.cpp msgid "Tint" @@ -25195,9 +24936,8 @@ msgid "Hide Folding" msgstr "Botão Desativado" #: scene/gui/tree.cpp -#, fuzzy msgid "Hide Root" -msgstr "Criar nó raiz:" +msgstr "Esconder Raiz" #: scene/gui/tree.cpp msgid "Drop Mode Flags" @@ -25210,7 +24950,7 @@ msgstr "Adicionar Faixa" #: scene/gui/video_player.cpp scene/main/scene_tree.cpp scene/main/timer.cpp msgid "Paused" -msgstr "" +msgstr "Pausado" #: scene/gui/video_player.cpp #, fuzzy @@ -25295,19 +25035,16 @@ msgid "Filename" msgstr "Renomear" #: scene/main/node.cpp -#, fuzzy msgid "Owner" -msgstr "Donos De:" +msgstr "Dono" #: scene/main/node.cpp scene/main/scene_tree.cpp -#, fuzzy msgid "Multiplayer" -msgstr "Definir Múltiplos:" +msgstr "Multijogador" #: scene/main/node.cpp -#, fuzzy msgid "Custom Multiplayer" -msgstr "Definir Múltiplos:" +msgstr "Multijogador Personalizado" #: scene/main/node.cpp #, fuzzy @@ -25340,17 +25077,16 @@ msgstr "Nova Raiz de Cena" #: scene/main/scene_tree.cpp msgid "Root" -msgstr "" +msgstr "Raiz" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Multiplayer Poll" -msgstr "Definir Múltiplos:" +msgstr "" #: scene/main/scene_tree.cpp scene/resources/mesh_library.cpp #: scene/resources/shape_2d.cpp msgid "Shapes" -msgstr "" +msgstr "Formas" #: scene/main/scene_tree.cpp msgid "Shape Color" @@ -25384,9 +25120,8 @@ msgid "Reflections" msgstr "Reflexões" #: scene/main/scene_tree.cpp -#, fuzzy msgid "Atlas Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho do Atlas" #: scene/main/scene_tree.cpp msgid "Atlas Subdiv" @@ -25398,7 +25133,7 @@ msgstr "" #: scene/main/scene_tree.cpp msgid "Use FXAA" -msgstr "" +msgstr "Usar FXAA" #: scene/main/scene_tree.cpp msgid "Use Debanding" @@ -25406,7 +25141,7 @@ msgstr "" #: scene/main/scene_tree.cpp scene/main/viewport.cpp msgid "HDR" -msgstr "" +msgstr "HDR" #: scene/main/scene_tree.cpp scene/main/viewport.cpp msgid "Use 32 BPC Depth" @@ -25444,9 +25179,8 @@ msgstr "" "Timer para tempos de espera muito baixos." #: scene/main/timer.cpp -#, fuzzy msgid "Autostart" -msgstr "ReinÃcio Automático:" +msgstr "InÃcio Automático" #: scene/main/viewport.cpp #, fuzzy @@ -25472,7 +25206,7 @@ msgstr "" #: scene/main/viewport.cpp msgid "ARVR" -msgstr "" +msgstr "ARVR" #: scene/main/viewport.cpp #, fuzzy @@ -25485,11 +25219,11 @@ msgstr "" #: scene/main/viewport.cpp scene/resources/world_2d.cpp msgid "World" -msgstr "" +msgstr "Mundo" #: scene/main/viewport.cpp msgid "World 2D" -msgstr "" +msgstr "Mundo 2D" #: scene/main/viewport.cpp #, fuzzy @@ -25503,7 +25237,7 @@ msgstr "Alterar Valor da Entrada" #: scene/main/viewport.cpp msgid "FXAA" -msgstr "" +msgstr "FXAA" #: scene/main/viewport.cpp #, fuzzy @@ -25521,8 +25255,9 @@ msgid "Keep 3D Linear" msgstr "Linear Esquerda" #: scene/main/viewport.cpp +#, fuzzy msgid "Render Direct To Screen" -msgstr "" +msgstr "Renderizar Diretamente para a Tela" #: scene/main/viewport.cpp #, fuzzy @@ -25530,9 +25265,8 @@ msgid "Debug Draw" msgstr "Depuração" #: scene/main/viewport.cpp -#, fuzzy msgid "Render Target" -msgstr "Renderizador:" +msgstr "Alvo do Renderizador" #: scene/main/viewport.cpp msgid "V Flip" @@ -25640,7 +25374,7 @@ msgstr "Navegação" #: scene/register_scene_types.cpp msgid "Use hiDPI" -msgstr "" +msgstr "Usar hiDPI" #: scene/register_scene_types.cpp #, fuzzy @@ -25660,12 +25394,11 @@ msgstr "Nó Mix" #: scene/resources/audio_stream_sample.cpp msgid "Stereo" -msgstr "" +msgstr "Stereo" #: scene/resources/concave_polygon_shape_2d.cpp -#, fuzzy msgid "Segments" -msgstr "Argumentos da Cena Principal:" +msgstr "Segmentos" #: scene/resources/curve.cpp #, fuzzy @@ -25678,7 +25411,7 @@ msgstr "" #: scene/resources/default_theme/default_theme.cpp msgid "Panel" -msgstr "" +msgstr "Painel" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25706,9 +25439,8 @@ msgid "Font Color Disabled" msgstr "Corte Desabilitado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "H Separation" -msgstr "Separação:" +msgstr "Separação Horizontal" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25717,7 +25449,7 @@ msgstr "Loop da Animação" #: scene/resources/default_theme/default_theme.cpp msgid "Arrow" -msgstr "" +msgstr "Seta" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25796,14 +25528,12 @@ msgid "Font Outline Modulate" msgstr "Forçar Módulo Branco" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow Offset X" -msgstr "Deslocamento da Grade X:" +msgstr "Deslocamento da Sombra em X" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Shadow Offset Y" -msgstr "Deslocamento da Grade Y:" +msgstr "Deslocamento da Sombra em Y" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -25861,14 +25591,12 @@ msgid "Space" msgstr "Cena Principal" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Folded" -msgstr "Pasta:" +msgstr "Dobrado" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Fold" -msgstr "Pasta:" +msgstr "Dobrar" #: scene/resources/default_theme/default_theme.cpp msgid "Font Color Readonly" @@ -26036,9 +25764,8 @@ msgid "Font Color Separator" msgstr "Separador de Cor da Fonte" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "V Separation" -msgstr "Separação:" +msgstr "Separação Vertical" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26091,9 +25818,8 @@ msgid "Close Offset" msgstr "Deslocamento do RuÃdo" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Port Offset" -msgstr "Deslocamento da Grade:" +msgstr "Deslocamento de Porta" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26203,14 +25929,12 @@ msgid "Draw Guides" msgstr "Mostrar Guias" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Scroll Border" -msgstr "Vertical:" +msgstr "Borda da Barra de Rolagem" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Scroll Speed" -msgstr "Deslocamento da Grade:" +msgstr "Velocidade de Rolagem" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26218,9 +25942,8 @@ msgid "Icon Margin" msgstr "Definir Margem" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Line Separation" -msgstr "Separação:" +msgstr "Separação de Linha" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26239,7 +25962,7 @@ msgstr "Item Desativado" #: scene/resources/default_theme/default_theme.cpp msgid "Menu" -msgstr "" +msgstr "Menu" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26280,9 +26003,8 @@ msgid "Large" msgstr "Destino" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Folder" -msgstr "Pasta:" +msgstr "Pasta" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26374,7 +26096,7 @@ msgstr "Cena Principal" #: scene/resources/default_theme/default_theme.cpp msgid "Bold Italics Font" -msgstr "" +msgstr "Fonte Negrito Itálica" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26382,14 +26104,12 @@ msgid "Mono Font" msgstr "Cena Principal" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Table H Separation" -msgstr "Separação:" +msgstr "Separação Horizontal da Tabela" #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Table V Separation" -msgstr "Separação:" +msgstr "Separação Vertical da Tabela" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26418,11 +26138,11 @@ msgstr "Auto Fatiar" #: scene/resources/default_theme/default_theme.cpp msgid "Minus" -msgstr "" +msgstr "Menos" #: scene/resources/default_theme/default_theme.cpp msgid "More" -msgstr "" +msgstr "Mais" #: scene/resources/default_theme/default_theme.cpp #, fuzzy @@ -26482,9 +26202,8 @@ msgid "Font Path" msgstr "Habilitar" #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Outline Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho do Contorno" #: scene/resources/dynamic_font.cpp #, fuzzy @@ -26497,14 +26216,12 @@ msgid "Use Mipmaps" msgstr "Sinais" #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Extra Spacing" -msgstr "Opções Extra:" +msgstr "Espaçamento Extra" #: scene/resources/dynamic_font.cpp -#, fuzzy msgid "Char" -msgstr "Caracteres válidos:" +msgstr "Caractere" #: scene/resources/dynamic_font.cpp #, fuzzy @@ -26517,7 +26234,7 @@ msgstr "" #: scene/resources/environment.cpp scene/resources/sky.cpp msgid "Sky" -msgstr "" +msgstr "Céu" #: scene/resources/environment.cpp #, fuzzy @@ -26530,9 +26247,8 @@ msgid "Sky Orientation" msgstr "Documentação Online" #: scene/resources/environment.cpp -#, fuzzy msgid "Sky Rotation" -msgstr "Passo de Rotação:" +msgstr "Rotação do Céu" #: scene/resources/environment.cpp msgid "Sky Rotation Degrees" @@ -26561,14 +26277,12 @@ msgid "Fog" msgstr "Névoa" #: scene/resources/environment.cpp -#, fuzzy msgid "Sun Color" -msgstr "Armazenando Arquivo:" +msgstr "Cor do Sol" #: scene/resources/environment.cpp -#, fuzzy msgid "Sun Amount" -msgstr "Quantidade:" +msgstr "Quantidade do Sol" #: scene/resources/environment.cpp #, fuzzy @@ -26632,7 +26346,7 @@ msgstr "Exportação" #: scene/resources/environment.cpp msgid "White" -msgstr "" +msgstr "Branco" #: scene/resources/environment.cpp msgid "Auto Exposure" @@ -26657,14 +26371,12 @@ msgid "Max Steps" msgstr "Passo" #: scene/resources/environment.cpp -#, fuzzy msgid "Fade In" -msgstr "[i]Fade In[/i](s):" +msgstr "Esmaecer de Entrada" #: scene/resources/environment.cpp -#, fuzzy msgid "Fade Out" -msgstr "[i]Fade Out[/i](s):" +msgstr "Esmaecer de SaÃda" #: scene/resources/environment.cpp #, fuzzy @@ -26677,12 +26389,11 @@ msgstr "Rugosidade" #: scene/resources/environment.cpp msgid "SSAO" -msgstr "" +msgstr "SSAO" #: scene/resources/environment.cpp -#, fuzzy msgid "Radius 2" -msgstr "Raio:" +msgstr "Raio 2" #: scene/resources/environment.cpp msgid "Intensity 2" @@ -26700,7 +26411,7 @@ msgstr "Depuração do Canal UV" #: scene/resources/environment.cpp msgid "Blur" -msgstr "" +msgstr "Blur" #: scene/resources/environment.cpp msgid "Edge Sharpness" @@ -26711,9 +26422,8 @@ msgid "DOF Far Blur" msgstr "" #: scene/resources/environment.cpp scene/resources/material.cpp -#, fuzzy msgid "Distance" -msgstr "Escolha uma Distância:" +msgstr "Distância" #: scene/resources/environment.cpp msgid "Transition" @@ -26796,18 +26506,16 @@ msgid "Brightness" msgstr "Luz" #: scene/resources/environment.cpp -#, fuzzy msgid "Saturation" -msgstr "Separação:" +msgstr "Separação" #: scene/resources/environment.cpp msgid "Color Correction" msgstr "Correção de Cor" #: scene/resources/font.cpp -#, fuzzy msgid "Ascent" -msgstr "Recente:" +msgstr "Subida" #: scene/resources/font.cpp #, fuzzy @@ -26820,9 +26528,8 @@ msgid "Raw Data" msgstr "Profundidade" #: scene/resources/gradient.cpp -#, fuzzy msgid "Offsets" -msgstr "Deslocamento:" +msgstr "Deslocamentos" #: scene/resources/height_map_shape.cpp msgid "Map Width" @@ -26902,7 +26609,7 @@ msgstr "" #: scene/resources/material.cpp msgid "Is sRGB" -msgstr "" +msgstr "É sRGB" #: scene/resources/material.cpp servers/visual_server.cpp msgid "Parameters" @@ -26948,9 +26655,8 @@ msgid "Grow" msgstr "Crescer" #: scene/resources/material.cpp -#, fuzzy msgid "Grow Amount" -msgstr "Quantidade:" +msgstr "Quantidade de Crescimento" #: scene/resources/material.cpp msgid "Use Alpha Scissor" @@ -27105,7 +26811,7 @@ msgstr "Faça mapas de luz" #: scene/resources/mesh.cpp scene/resources/primitive_meshes.cpp msgid "Custom AABB" -msgstr "" +msgstr "AABB Personalizado" #: scene/resources/mesh_library.cpp #, fuzzy @@ -27139,9 +26845,8 @@ msgid "Visible Instance Count" msgstr "" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Sampling" -msgstr "Escala:" +msgstr "Mostragem" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -27162,12 +26867,11 @@ msgstr "Origem do Nome do Grupo" #: scene/resources/navigation_mesh.cpp msgid "Cells" -msgstr "" +msgstr "Células" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Agents" -msgstr "Argumentos da Cena Principal:" +msgstr "Agentes" #: scene/resources/navigation_mesh.cpp msgid "Max Climb" @@ -27189,7 +26893,7 @@ msgstr "Fundir a partir de Cena" #: scene/resources/navigation_mesh.cpp msgid "Edges" -msgstr "" +msgstr "Arestas" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -27206,9 +26910,8 @@ msgid "Details" msgstr "Detalhe" #: scene/resources/navigation_mesh.cpp -#, fuzzy msgid "Sample Distance" -msgstr "Escolha uma Distância:" +msgstr "Distância de Amostra" #: scene/resources/navigation_mesh.cpp #, fuzzy @@ -27278,9 +26981,8 @@ msgid "Color Modifier" msgstr "Modificador de velocidade lenta da Visão Livre" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Point Texture" -msgstr "Pontos de Emissão:" +msgstr "Textura de Ponto" #: scene/resources/particles_material.cpp msgid "Normal Texture" @@ -27297,9 +26999,8 @@ msgid "Point Count" msgstr "Adicionar porta de entrada" #: scene/resources/particles_material.cpp -#, fuzzy msgid "Scale Random" -msgstr "Razão de Escala:" +msgstr "Randomização de Escala" #: scene/resources/particles_material.cpp #, fuzzy @@ -27315,9 +27016,8 @@ msgid "Absorbent" msgstr "" #: scene/resources/plane_shape.cpp -#, fuzzy msgid "Plane" -msgstr "Plano:" +msgstr "Plano" #: scene/resources/primitive_meshes.cpp #, fuzzy @@ -27341,9 +27041,8 @@ msgid "Subdivide Depth" msgstr "" #: scene/resources/primitive_meshes.cpp -#, fuzzy msgid "Top Radius" -msgstr "Raio:" +msgstr "Raio do Topo" #: scene/resources/primitive_meshes.cpp #, fuzzy @@ -27392,13 +27091,12 @@ msgid "Bone" msgstr "Ossos" #: scene/resources/sky.cpp -#, fuzzy msgid "Radiance Size" -msgstr "Tamanho do Contorno:" +msgstr "Tamanho da Radiância" #: scene/resources/sky.cpp msgid "Panorama" -msgstr "" +msgstr "Panorama" #: scene/resources/sky.cpp #, fuzzy @@ -27406,9 +27104,8 @@ msgid "Top Color" msgstr "Próximo Chão" #: scene/resources/sky.cpp -#, fuzzy msgid "Horizon Color" -msgstr "Armazenando Arquivo:" +msgstr "Cor do Horizonte" #: scene/resources/sky.cpp #, fuzzy @@ -27432,7 +27129,7 @@ msgstr "Substituir" #: scene/resources/sky.cpp msgid "Longitude" -msgstr "" +msgstr "Longitude" #: scene/resources/sky.cpp msgid "Angle Min" @@ -27467,7 +27164,7 @@ msgstr "" #: scene/resources/style_box.cpp msgid "Anti Aliasing" -msgstr "" +msgstr "Anti Aliasing" #: scene/resources/style_box.cpp msgid "Grow Begin" @@ -27517,9 +27214,8 @@ msgid "Lossy Storage Quality" msgstr "Capturar" #: scene/resources/texture.cpp -#, fuzzy msgid "From" -msgstr "Modo Panorâmico:" +msgstr "À Partir de" #: scene/resources/texture.cpp #, fuzzy @@ -27723,9 +27419,8 @@ msgid "Audio Stream" msgstr "Item Rádio" #: servers/audio/audio_stream.cpp -#, fuzzy msgid "Random Pitch" -msgstr "Inclinação aleatória:" +msgstr "Timbre Aleatório" #: servers/audio/effects/audio_effect_capture.cpp #: servers/audio/effects/audio_effect_spectrum_analyzer.cpp @@ -27741,21 +27436,21 @@ msgstr "" #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Dry" -msgstr "" +msgstr "Seco" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_reverb.cpp msgid "Wet" -msgstr "" +msgstr "Molhado" #: servers/audio/effects/audio_effect_chorus.cpp msgid "Voice" -msgstr "" +msgstr "Voz" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp msgid "Delay (ms)" -msgstr "" +msgstr "Atraso (ms)" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_phaser.cpp @@ -27770,23 +27465,22 @@ msgstr "Profundidade" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp msgid "Level dB" -msgstr "" +msgstr "NÃvel dB" #: servers/audio/effects/audio_effect_chorus.cpp #: servers/audio/effects/audio_effect_delay.cpp #: servers/audio/effects/audio_effect_panner.cpp -#, fuzzy msgid "Pan" -msgstr "Plano:" +msgstr "Panoramizar" #: servers/audio/effects/audio_effect_compressor.cpp #: servers/audio/effects/audio_effect_filter.cpp msgid "Gain" -msgstr "" +msgstr "Ganho" #: servers/audio/effects/audio_effect_compressor.cpp msgid "Attack (µs)" -msgstr "" +msgstr "Ataque (µs)" #: servers/audio/effects/audio_effect_compressor.cpp #, fuzzy @@ -27823,7 +27517,7 @@ msgstr "Ignorar" #: servers/audio/effects/audio_effect_distortion.cpp msgid "Pre Gain" -msgstr "" +msgstr "Pré Ganho" #: servers/audio/effects/audio_effect_distortion.cpp msgid "Keep Hf Hz" @@ -27831,7 +27525,7 @@ msgstr "" #: servers/audio/effects/audio_effect_distortion.cpp msgid "Drive" -msgstr "" +msgstr "Drive" #: servers/audio/effects/audio_effect_distortion.cpp #, fuzzy @@ -27873,21 +27567,20 @@ msgstr "" #: servers/audio/effects/audio_effect_pitch_shift.cpp #: servers/audio/effects/audio_effect_spectrum_analyzer.cpp -#, fuzzy msgid "FFT Size" -msgstr "Tamanho:" +msgstr "Tamanho FFT" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Predelay" -msgstr "" +msgstr "Pré Atraso" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Msec" -msgstr "" +msgstr "Msec" #: servers/audio/effects/audio_effect_reverb.cpp msgid "Room Size" -msgstr "" +msgstr "Tamanho da Sala" #: servers/audio/effects/audio_effect_reverb.cpp #, fuzzy @@ -27970,9 +27663,8 @@ msgid "Time Before Sleep" msgstr "" #: servers/physics_2d/physics_2d_server_sw.cpp -#, fuzzy msgid "BP Hash Table Size" -msgstr "Tamanho:" +msgstr "Tamanho da \"BP Hash Table\"" #: servers/physics_2d/physics_2d_server_sw.cpp msgid "Large Object Surface Threshold In Cells" @@ -28345,7 +28037,7 @@ msgstr "" #: servers/visual_server.cpp msgid "Compatibility" -msgstr "" +msgstr "Compatibilidade" #: servers/visual_server.cpp msgid "Disable Half Float" diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 395185bd3e..aaa6e1cbcb 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -2186,14 +2186,15 @@ msgstr "Favorite:" msgid "Recent:" msgstr "Recent:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "CautaÈ›i:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Potriviri:" @@ -2253,8 +2254,8 @@ msgstr "CautaÈ›i ÃŽnlocuitor Resursă:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5633,6 +5634,10 @@ msgid "Drag And Drop Selection" msgstr "Toată selecÈ›ia" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12024,6 +12029,11 @@ msgid "New Animation" msgstr "AnimaÈ›ie" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Metode de filtrare" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index befaceac4c..c50dce8e01 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -85,7 +85,7 @@ # kyanukovich <ianu0001@algonquinlive.com>, 2020. # Ron788 <ustinov200511@gmail.com>, 2020. # Daniel <dan.ef1999@gmail.com>, 2020. -# NeoLan Qu <it.bulla@mail.ru>, 2020. +# NeoLan Qu <it.bulla@mail.ru>, 2020, 2022. # Nikita Epifanov <nikgreens@protonmail.com>, 2020. # Cube Show <griiv.06@gmail.com>, 2020. # Roman Tolkachyov <roman@tolkachyov.name>, 2020. @@ -118,13 +118,14 @@ # Jasuse <jasusemaele@gmail.com>, 2022. # Vadim Mitroshkin <Vadim7540@yandex.ru>, 2022. # Maksim Marchukov <mar.maksim63@gmail.com>, 2022. +# Slava Beloglazov <slavathedeveloper@gmail.com>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-17 07:14+0000\n" -"Last-Translator: Maksim Marchukov <mar.maksim63@gmail.com>\n" +"PO-Revision-Date: 2022-07-26 01:55+0000\n" +"Last-Translator: NeoLan Qu <it.bulla@mail.ru>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" "Language: ru\n" @@ -561,7 +562,7 @@ msgstr "Давление" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Перо Инвертировано" #: core/os/input_event.cpp msgid "Relative" @@ -1244,9 +1245,8 @@ msgid "Value" msgstr "Значение" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Arg Count" -msgstr "КоличеÑтво" +msgstr "КоличеÑтво Ðргументов" #: editor/animation_track_editor.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp @@ -1437,24 +1437,22 @@ msgid "(Invalid, expected type: %s)" msgstr "(Ðеверный, ожидаемый тип: %s)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Easing:" -msgstr "Переход Ð’-ИЗ" +msgstr "Переход Ð’-ИЗ:" #: editor/animation_track_editor.cpp #, fuzzy msgid "In-Handle:" -msgstr "Задать обработчик" +msgstr "Обработчик Ввода:" #: editor/animation_track_editor.cpp #, fuzzy msgid "Out-Handle:" -msgstr "Задать обработчик" +msgstr "Обработчик Вывода:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Stream:" -msgstr "Поток" +msgstr "Поток:" #: editor/animation_track_editor.cpp msgid "Start (s):" @@ -2215,14 +2213,15 @@ msgstr "Избранное:" msgid "Recent:" msgstr "Ðедавнее:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "ПоиÑк:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "СовпадениÑ:" @@ -2282,8 +2281,8 @@ msgstr "Ðайти заменÑемый реÑурÑ:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2292,7 +2291,7 @@ msgstr "Открыть" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Владельцы: %s (Ð’Ñего: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2342,9 +2341,8 @@ msgid "Fix Dependencies" msgstr "ИÑправить завиÑимоÑти" #: editor/dependency_editor.cpp -#, fuzzy msgid "Errors loading!" -msgstr "Ошибки загружаютÑÑ!" +msgstr "Ошибки при загрузке!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" @@ -2851,17 +2849,15 @@ msgstr "Выбрать" #: editor/editor_export.cpp msgid "Project export for platform:" -msgstr "" +msgstr "ÐкÑпорт проекта Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ñ‹:" #: editor/editor_export.cpp -#, fuzzy msgid "Completed with errors." -msgstr "Завершать пути файлов" +msgstr "Завершено Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°Ð¼Ð¸." #: editor/editor_export.cpp -#, fuzzy msgid "Completed successfully." -msgstr "Пакет уÑпешно уÑтановлен!" +msgstr "Завершено без ошибок." #: editor/editor_export.cpp #, fuzzy @@ -2881,9 +2877,8 @@ msgid "Packing" msgstr "Упаковывание" #: editor/editor_export.cpp -#, fuzzy msgid "Save PCK" -msgstr "Сохранить как" +msgstr "Сохранить PCK" #: editor/editor_export.cpp #, fuzzy @@ -2910,16 +2905,16 @@ msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" -"Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° требует Ñжатие текÑтур «ETC» Ð´Ð»Ñ GLES2. Включите «Import " -"Etc» в ÐаÑтройках проекта." +"Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° требует Ñжатие текÑтур «ETC» Ð´Ð»Ñ GLES2. Включите " +"«Импортировать Etc» в ÐаÑтройках Проекта." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" -"Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° требует компреÑÑию текÑтур «ETC2» Ð´Ð»Ñ GLES2. Включите " -"«Import Etc 2» в ÐаÑтройках проекта." +"Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° требует компреÑÑию текÑтур «ETC2» Ð´Ð»Ñ GLES3. Включите " +"«Импортировать Etc 2» в ÐаÑтройках Проекта." #: editor/editor_export.cpp msgid "" @@ -2929,8 +2924,8 @@ msgid "" "Enabled'." msgstr "" "Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° требует ÑÐ¶Ð°Ñ‚Ð¸Ñ Ñ‚ÐµÐºÑтур «ETC» Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ°Ñ‚Ð° драйвера к GLES2.\n" -"Включите «Import Etc» в ÐаÑтройках проекта или отключите «Driver Fallback " -"Enabled»." +"Включите «Импортировать Etc» в ÐаÑтройках проекта или отключите «Driver " +"Fallback Enabled»." #: editor/editor_export.cpp msgid "" @@ -2946,7 +2941,8 @@ msgid "" "Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings." msgstr "" "Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð° требует компреÑÑию текÑтур «ETC2» или «PVRTC» Ð´Ð»Ñ GLES3. " -"Включите «Import Etc 2» или «Import Pvrtc» в ÐаÑтройках проекта." +"Включите «Импортировать Etc 2» или «Импортировать Pvrtc» в ÐаÑтройках " +"Проекта." #: editor/editor_export.cpp msgid "" @@ -5604,6 +5600,10 @@ msgid "Drag And Drop Selection" msgstr "Выделение Ñетки" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Внешний вид" @@ -7257,12 +7257,17 @@ msgid "" "%s: Texture detected as used as a normal map in 3D. Enabling red-green " "texture compression to reduce memory usage (blue channel is discarded)." msgstr "" +"%s: Ð’Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ñ‚ÐµÐºÑтура иÑпользуетÑÑ ÐºÐ°Ðº карта нормалей в 3D. Включено краÑно-" +"зелёное Ñжатие текÑтуры Ð´Ð»Ñ ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð°Ð¼Ñти (Ñиний канал " +"отбраÑываетÑÑ)." #: editor/import/resource_importer_texture.cpp msgid "" "%s: Texture detected as used in 3D. Enabling filter, repeat, mipmap " "generation and VRAM texture compression." msgstr "" +"%s: ТекÑтура иÑпользуетÑÑ Ð² 3D. Включена фильтрациÑ, повторение и Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ " +"mipmap-карт, а также VRAM Ñжатие текÑтуры." #: editor/import/resource_importer_texture.cpp msgid "2D, Detect 3D" @@ -11699,6 +11704,11 @@ msgid "New Animation" msgstr "ÐÐ¾Ð²Ð°Ñ Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Фильтр методов" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "СкороÑть:" @@ -15361,7 +15371,7 @@ msgstr "Сделать локальным" #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Another node already uses this unique name in the scene." -msgstr "Ð˜Ð¼Ñ ÑƒÐ·Ð»Ð° уже иÑпользовано в Ñцене" +msgstr "Данное уникальное Ð¸Ð¼Ñ ÑƒÐ¶Ðµ иÑпользовано у другого узла в Ñцене." #: editor/scene_tree_dock.cpp msgid "Enable Scene Unique Name" @@ -15794,9 +15804,8 @@ msgid "Attach Node Script" msgstr "Прикрепить Ñкрипт" #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Remote %s:" -msgstr "Удаленный " +msgstr "Удаленный %s:" #: editor/script_editor_debugger.cpp msgid "Bytes:" @@ -16774,7 +16783,7 @@ msgstr "Выключен GDNative Ñинглтон" #: modules/gdnative/gdnative_library_singleton_editor.cpp #, fuzzy msgid "Libraries:" -msgstr "Библиотеки: " +msgstr "Библиотеки:" #: modules/gdnative/nativescript/nativescript.cpp msgid "Class Name" @@ -17050,7 +17059,7 @@ msgstr "СфокуÑироватьÑÑ Ð½Ð° начале координат" #: modules/gltf/gltf_skin.cpp msgid "Inverse Binds" -msgstr "" +msgstr "Инвертировать СвÑзи" #: modules/gltf/gltf_skin.cpp #, fuzzy @@ -17059,11 +17068,11 @@ msgstr "Передвинуть ÑуÑтав" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Bone I" -msgstr "" +msgstr "Узел I к КоÑти I" #: modules/gltf/gltf_skin.cpp msgid "Joint I To Name" -msgstr "" +msgstr "Узел I К Имени" #: modules/gltf/gltf_skin.cpp msgid "Godot Skin" @@ -17079,7 +17088,7 @@ msgstr "Диффузный фактор" #: modules/gltf/gltf_spec_gloss.cpp msgid "Gloss Factor" -msgstr "" +msgstr "КоÑфф. ГлÑнца" #: modules/gltf/gltf_spec_gloss.cpp #, fuzzy @@ -17628,9 +17637,8 @@ msgstr "" "памÑти! ИÑправьте узел пожалуйÑта." #: modules/visual_script/visual_script.cpp -#, fuzzy msgid "Node returned an invalid sequence output:" -msgstr "Узел вернул ошибочную поÑледовательноÑть: " +msgstr "Узел вернул ошибочный вывод поÑледовательноÑти:" #: modules/visual_script/visual_script.cpp msgid "Found sequence bit but not the node in the stack, report bug!" @@ -17640,7 +17648,7 @@ msgstr "" #: modules/visual_script/visual_script.cpp #, fuzzy msgid "Stack overflow with stack depth:" -msgstr "Переполнение Ñтека Ñ Ð³Ð»ÑƒÐ±Ð¸Ð½Ð¾Ð¹ Ñтека: " +msgstr "Переполнение Ñтека Ñ Ð³Ð»ÑƒÐ±Ð¸Ð½Ð¾Ð¹ Ñтека:" #: modules/visual_script/visual_script.cpp msgid "Visual Script" @@ -18009,7 +18017,7 @@ msgstr "Ð´Ð»Ñ (Ñлемент) в (вход):" #: modules/visual_script/visual_script_flow_control.cpp #, fuzzy msgid "Input type not iterable:" -msgstr "Входной тип не итерируемый: " +msgstr "Входной тип не итерируемый:" #: modules/visual_script/visual_script_flow_control.cpp msgid "Iterator became invalid" @@ -18018,7 +18026,7 @@ msgstr "Итератор Ñтал недейÑтвительным" #: modules/visual_script/visual_script_flow_control.cpp #, fuzzy msgid "Iterator became invalid:" -msgstr "Итератор Ñтал недейÑтвительным: " +msgstr "Итератор Ñтал недейÑтвительным:" #: modules/visual_script/visual_script_flow_control.cpp msgid "Sequence" @@ -18172,14 +18180,12 @@ msgid "Operator" msgstr "Оператор" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Invalid argument of type:" -msgstr ": ÐедопуÑтимый аргумент типа: " +msgstr "ÐедопуÑтимый аргумент типа:" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "Invalid arguments:" -msgstr ": ÐедопуÑтимые аргументы: " +msgstr "ÐедопуÑтимые аргументы:" #: modules/visual_script/visual_script_nodes.cpp msgid "a if cond, else b" @@ -18190,14 +18196,13 @@ msgid "Var Name" msgstr "Ð˜Ð¼Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹" #: modules/visual_script/visual_script_nodes.cpp -#, fuzzy msgid "VariableGet not found in script:" -msgstr "VariableGet не найден в Ñкрипте: " +msgstr "VariableGet отÑутÑтвует в Ñкрипте:" #: modules/visual_script/visual_script_nodes.cpp #, fuzzy msgid "VariableSet not found in script:" -msgstr "VariableSet не найден в Ñкрипте: " +msgstr "VariableSet не найден в Ñкрипте:" #: modules/visual_script/visual_script_nodes.cpp msgid "Preload" @@ -18334,7 +18339,7 @@ msgstr "Режим запиÑи" #: modules/webrtc/webrtc_data_channel.h msgid "WebRTC" -msgstr "" +msgstr "WebRTC" #: modules/webrtc/webrtc_data_channel.h #, fuzzy @@ -18350,36 +18355,32 @@ msgid "Trusted SSL Certificate" msgstr "Доверенный SSL-Ñертификат" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Client" -msgstr "Сетевой узел" +msgstr "Клиент WebSocket" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max In Buffer (KB)" -msgstr "МакÑимальный размер (КБ)" +msgstr "МакÑимальный Входной Буфер (КБ)" #: modules/websocket/websocket_macros.h msgid "Max In Packets" -msgstr "" +msgstr "МакÑимальные ВходÑщие Пакеты" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "Max Out Buffer (KB)" -msgstr "МакÑимальный размер (КБ)" +msgstr "МакÑимальный Буфер Вывода (КБ)" #: modules/websocket/websocket_macros.h msgid "Max Out Packets" -msgstr "" +msgstr "МакÑимальный Вывод Пакетов" #: modules/websocket/websocket_macros.h -#, fuzzy msgid "WebSocket Server" -msgstr "Сетевой узел" +msgstr "Сервер WebSocket" #: modules/websocket/websocket_server.cpp msgid "Bind IP" -msgstr "" +msgstr "ПривÑзать IP" #: modules/websocket/websocket_server.cpp msgid "Private Key" @@ -18403,14 +18404,12 @@ msgid "Session Mode" msgstr "Режим ÑеÑÑии" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Required Features" -msgstr "Ðеобходимые функции" +msgstr "Ðеобходимые Компоненты" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Optional Features" -msgstr "Дополнительные функции" +msgstr "Дополнительные Компоненты" #: modules/webxr/webxr_interface.cpp msgid "Requested Reference Space Types" @@ -18421,9 +18420,8 @@ msgid "Reference Space Type" msgstr "" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "Visibility State" -msgstr "Переключить видимоÑть" +msgstr "ВидимоÑть" #: modules/webxr/webxr_interface.cpp #, fuzzy @@ -18431,9 +18429,8 @@ msgid "Bounds Geometry" msgstr "Повторить" #: modules/webxr/webxr_interface.cpp -#, fuzzy msgid "XR Standard Mapping" -msgstr "Ð˜Ð½Ñ‚ÐµÐ»Ð»ÐµÐºÑ‚ÑƒÐ°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¸Ð²Ñзка" +msgstr "Стандартный Маппинг XR" #: platform/android/export/export.cpp msgid "Android SDK Path" @@ -18462,19 +18459,19 @@ msgstr "Выключение ADB при выходе" #: platform/android/export/export_plugin.cpp msgid "Launcher Icons" -msgstr "" +msgstr "Иконки Лаунчера" #: platform/android/export/export_plugin.cpp msgid "Main 192 X 192" -msgstr "" +msgstr "ОÑÐ½Ð¾Ð²Ð½Ð°Ñ 192 X 192" #: platform/android/export/export_plugin.cpp msgid "Adaptive Foreground 432 X 432" -msgstr "" +msgstr "Ðдаптивный Передний Фон 432 X 432" #: platform/android/export/export_plugin.cpp msgid "Adaptive Background 432 X 432" -msgstr "" +msgstr "Ðдаптивный Задний Фон 432 X 432" #: platform/android/export/export_plugin.cpp msgid "Package name is missing." @@ -18501,39 +18498,32 @@ msgid "The package must have at least one '.' separator." msgstr "Пакет должен иметь Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один разделитель «.»." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Custom Build" -msgstr "ИÑпользовать ÑобÑтвенную директорию данных пользователÑ" +msgstr "ÐаÑÑ‚Ñ€Ð°Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ð¡Ð±Ð¾Ñ€ÐºÐ°" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Use Custom Build" -msgstr "ИÑпользовать ÑобÑтвенную директорию данных пользователÑ" +msgstr "ИÑпользовать ÐаÑтраиваемую Сборку" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Export Format" -msgstr "Путь ÑкÑпорта" +msgstr "Формат ÐкÑпорта" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Min SDK" -msgstr "Минимальный размер" +msgstr "Min SDK" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Target SDK" -msgstr "Целевой FPS" +msgstr "Целевой SDK" #: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp -#, fuzzy msgid "Architectures" -msgstr "Добавить поле архитектуры" +msgstr "Ðрхитектуры" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Keystore" -msgstr "Отладочное хранилище ключей" +msgstr "Хранилище ключей" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18557,31 +18547,27 @@ msgstr "Пароль" #: platform/android/export/export_plugin.cpp msgid "One Click Deploy" -msgstr "" +msgstr "Развёртывание в Один Клик" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Clear Previous Install" -msgstr "ОÑмотреть предыдущий ÑкземплÑÑ€" +msgstr "ОчиÑтить Предыдущую УÑтановку" #: platform/android/export/export_plugin.cpp msgid "Code" msgstr "Код" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Package" -msgstr "Упаковывание" +msgstr "Пакет" #: platform/android/export/export_plugin.cpp platform/uwp/export/export.cpp -#, fuzzy msgid "Unique Name" -msgstr "Уникальные имена" +msgstr "Уникальное ИмÑ" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Signed" -msgstr "Сигнал" +msgstr "ПодпиÑано" #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18891,14 +18877,12 @@ msgid "Code Signing" msgstr "ПодпиÑÑŒ кода DMG" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "'apksigner' could not be found. Please check that the command is available " "in the Android SDK build-tools directory. The resulting %s is unsigned." msgstr "" -"Ðе удалоÑÑŒ найти команду «apksigner».\n" -"ПожалуйÑта, проверьте наличие программы в каталоге Android SDK build-tools.\n" -"Результат %s не подпиÑан." +"Ðе удалоÑÑŒ найти «apksigner». ПожалуйÑта, убедитеÑÑŒ в наличии команды в " +"каталоге build-tools Android SDK. Результирующий %s не подпиÑан." #: platform/android/export/export_plugin.cpp msgid "Signing debug %s..." @@ -18913,9 +18897,8 @@ msgid "Could not find keystore, unable to export." msgstr "Ðе удалоÑÑŒ найти хранилище ключей, невозможно ÑкÑпортировать." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not start apksigner executable." -msgstr "Ðе удаётÑÑ Ð·Ð°Ð¿ÑƒÑтить подпроцеÑÑ!" +msgstr "Ðе удаётÑÑ Ð·Ð°Ð¿ÑƒÑтить иÑполнÑемый файл apksigner." #: platform/android/export/export_plugin.cpp msgid "'apksigner' returned with error #%d" @@ -18946,9 +18929,8 @@ msgid "Invalid filename! Android APK requires the *.apk extension." msgstr "Ðеверное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°! Android APK требует раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ *.apk." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Unsupported export format!" -msgstr "Ðеподдерживаемый формат ÑкÑпорта!\n" +msgstr "Ðеподдерживаемый формат ÑкÑпорта!" #: platform/android/export/export_plugin.cpp msgid "" @@ -18959,15 +18941,12 @@ msgstr "" "не ÑущеÑтвует. ПожалуйÑта, переуÑтановите из меню «Проект»." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Android build version mismatch: Template installed: %s, Godot version: %s. " "Please reinstall Android build template from 'Project' menu." msgstr "" -"ÐеÑоответÑтвие верÑии Ñборки Android:\n" -" УÑтановлен шаблон: %s\n" -" ВерÑÐ¸Ñ Godot: %s\n" -"ПожалуйÑта, переуÑтановите шаблон Ñборки Android из меню «Проект»." +"ÐеÑоответÑтвие верÑии Ñборки Android: УÑтановлен шаблон: %s, верÑÐ¸Ñ Godot: " +"%s. ПожалуйÑта, переуÑтановите шаблон Ñборки Android из меню «Проект»." #: platform/android/export/export_plugin.cpp #, fuzzy @@ -18977,9 +18956,8 @@ msgstr "" "Ðевозможно перезапиÑать файлы res://android/build/res/*.xml Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ проекта" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not export project files to gradle project." -msgstr "Ðе удалоÑÑŒ ÑкÑпортировать файлы проекта в проект gradle\n" +msgstr "Ðе удалоÑÑŒ ÑкÑпортировать файлы проекта в проект gradle." #: platform/android/export/export_plugin.cpp msgid "Could not write expansion package file!" @@ -18990,14 +18968,13 @@ msgid "Building Android Project (gradle)" msgstr "Сборка проекта Android (gradle)" #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Building of Android project failed, check output for the error. " "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" -"Сборка проекта Android не удалаÑÑŒ, проверьте вывод на ошибки.\n" -"Также поÑетите docs.godotengine.org Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ð¸ по Ñборке " -"Android." +"Сборка Android проекта не удалаÑÑŒ, проверьте вывод на ошибки. Ð’Ñ‹ также " +"можете поÑетить docs.godotengine.org Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ð¸ по Ñборке " +"Ð´Ð»Ñ Android." #: platform/android/export/export_plugin.cpp msgid "Moving output" @@ -19021,22 +18998,18 @@ msgid "Creating APK..." msgstr "Создание APK..." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "Could not find template APK to export: \"%s\"." -msgstr "" -"Ðе удалоÑÑŒ найти шаблон APK Ð´Ð»Ñ ÑкÑпорта:\n" -"%s" +msgstr "Ðе удалоÑÑŒ найти шаблон APK Ð´Ð»Ñ ÑкÑпорта: \"%s\"." #: platform/android/export/export_plugin.cpp -#, fuzzy msgid "" "Missing libraries in the export template for the selected architectures: %s. " "Please build a template with all required libraries, or uncheck the missing " "architectures in the export preset." msgstr "" -"Ð’ шаблоне ÑкÑпорта отÑутÑтвуют библиотеки Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… архитектур: %s.\n" -"ПожалуйÑта, Ñоздайте шаблон Ñо вÑеми необходимыми библиотеками или Ñнимите " -"флажки Ñ Ð¾Ñ‚ÑутÑтвующих архитектур в преÑете ÑкÑпорта." +"Ð’ шаблоне ÑкÑпорта отÑутÑтвуют библиотеки Ð´Ð»Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ñ… архитектур: %s. " +"ПожалуйÑта, поÑтройте шаблон Ñо вÑеми необходимыми библиотеками или Ñнимите " +"флажки Ñ Ð¾Ñ‚ÑутÑтвующих архитектур в предуÑтановках ÑкÑпорта." #: platform/android/export/export_plugin.cpp msgid "Adding files..." @@ -19726,9 +19699,8 @@ msgid "Could not open icon file \"%s\"." msgstr "Ðе удалоÑÑŒ ÑкÑпортировать файлы проекта" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start xcrun executable." -msgstr "Ðе удаётÑÑ Ð·Ð°Ð¿ÑƒÑтить подпроцеÑÑ!" +msgstr "Ðе удаётÑÑ Ð·Ð°Ð¿ÑƒÑтить иÑполнÑемый файл xcrun." #: platform/osx/export/export.cpp #, fuzzy @@ -19812,9 +19784,8 @@ msgid "DMG Creation" msgstr "Ðаправление" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not start hdiutil executable." -msgstr "Ðе удаётÑÑ Ð·Ð°Ð¿ÑƒÑтить подпроцеÑÑ!" +msgstr "Ðе удаётÑÑ Ð·Ð°Ð¿ÑƒÑтить иÑполнÑемый файл hdiutil." #: platform/osx/export/export.cpp msgid "`hdiutil create` failed - file exists." @@ -19901,9 +19872,8 @@ msgid "ZIP Creation" msgstr "ПроекциÑ" #: platform/osx/export/export.cpp -#, fuzzy msgid "Could not open file to read from path \"%s\"." -msgstr "Ðе удалоÑÑŒ ÑкÑпортировать файлы проекта в проект gradle\n" +msgstr "Ðе удалоÑÑŒ открыть файл Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¿Ð¾ пути \"%s\"." #: platform/osx/export/export.cpp msgid "Invalid bundle identifier:" @@ -22940,11 +22910,11 @@ msgstr "" #: scene/3d/physics_body.cpp msgid "Angular Spring Damping" -msgstr "" +msgstr "Угловое Затухание Пружины" #: scene/3d/physics_body.cpp msgid "Angular Equilibrium Point" -msgstr "" +msgstr "Ð£Ð³Ð»Ð¾Ð²Ð°Ñ Ð¢Ð¾Ñ‡ÐºÐ° РавновеÑиÑ" #: scene/3d/physics_body.cpp #, fuzzy @@ -22973,7 +22943,7 @@ msgstr "Узел Ри Узел Ð’ должны быть различными о #: scene/3d/physics_joint.cpp msgid "Solver" -msgstr "" +msgstr "Разрешитель" #: scene/3d/physics_joint.cpp #, fuzzy @@ -22987,7 +22957,7 @@ msgstr "Параметры" #: scene/3d/physics_joint.cpp msgid "Angular Limit" -msgstr "" +msgstr "Угловой Предел" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23001,7 +22971,7 @@ msgstr "нижний региÑтр" #: scene/3d/physics_joint.cpp msgid "Motor" -msgstr "" +msgstr "Мотор" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23085,11 +23055,11 @@ msgstr "МежÑтрочный интервал" #: scene/3d/physics_joint.cpp msgid "Equilibrium Point" -msgstr "" +msgstr "Точка РавновеÑиÑ" #: scene/3d/physics_joint.cpp msgid "Angular Limit X" -msgstr "" +msgstr "X Углового Предела" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23098,7 +23068,7 @@ msgstr "Ð£Ð³Ð»Ð¾Ð²Ð°Ñ ÑкороÑть" #: scene/3d/physics_joint.cpp msgid "Angular Spring X" -msgstr "" +msgstr "X Угловой Пружины" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23117,7 +23087,7 @@ msgstr "МежÑтрочный интервал" #: scene/3d/physics_joint.cpp msgid "Angular Limit Y" -msgstr "" +msgstr "Y Углового Предела" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23126,7 +23096,7 @@ msgstr "Ð£Ð³Ð»Ð¾Ð²Ð°Ñ ÑкороÑть" #: scene/3d/physics_joint.cpp msgid "Angular Spring Y" -msgstr "" +msgstr "Y Угловой Пружины" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23145,7 +23115,7 @@ msgstr "МежÑтрочный интервал" #: scene/3d/physics_joint.cpp msgid "Angular Limit Z" -msgstr "" +msgstr "Z Углового Предела" #: scene/3d/physics_joint.cpp #, fuzzy @@ -23154,7 +23124,7 @@ msgstr "Ð£Ð³Ð»Ð¾Ð²Ð°Ñ ÑкороÑть" #: scene/3d/physics_joint.cpp msgid "Angular Spring Z" -msgstr "" +msgstr "Z Угловой Пружины" #: scene/3d/portal.cpp msgid "The RoomManager should not be a child or grandchild of a Portal." @@ -23174,7 +23144,7 @@ msgstr "Портал активен" #: scene/3d/portal.cpp scene/resources/occluder_shape_polygon.cpp msgid "Two Way" -msgstr "" +msgstr "Ð’ обе Стороны" #: scene/3d/portal.cpp msgid "Linked Room" @@ -27789,14 +27759,12 @@ msgid "Import S3TC" msgstr "Импорт" #: servers/visual_server.cpp -#, fuzzy msgid "Import ETC" -msgstr "Импорт" +msgstr "Импортировать ETC" #: servers/visual_server.cpp -#, fuzzy msgid "Import ETC2" -msgstr "Импорт" +msgstr "Импортировать ETC2" #: servers/visual_server.cpp #, fuzzy diff --git a/editor/translations/si.po b/editor/translations/si.po index bfba193a6a..e30d6c27ab 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -2120,14 +2120,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2183,8 +2184,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5345,6 +5346,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11392,6 +11397,11 @@ msgid "New Animation" msgstr "සජීවීකරණ පුනරà·à·€à¶»à·Šà¶®à¶±à¶º" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "à·à·Šâ€à¶»à·’à¶:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index f711be3039..c3a64ecc2f 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -2204,14 +2204,15 @@ msgstr "Obľúbené:" msgid "Recent:" msgstr "Nedávne:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "HľadaÅ¥:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Zhody:" @@ -2271,8 +2272,8 @@ msgstr "HľadaÅ¥ Náhradný Zdroj:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5658,6 +5659,10 @@ msgid "Drag And Drop Selection" msgstr "VÅ¡etky vybrané" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11963,6 +11968,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filter:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/sl.po b/editor/translations/sl.po index aae6c8ba68..4f7f11baa3 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -2223,14 +2223,15 @@ msgstr "Priljubljene:" msgid "Recent:" msgstr "Nedavni:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Iskanje:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Zadetki:" @@ -2292,8 +2293,8 @@ msgstr "Iskanje Nadomestnih Virov:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5729,6 +5730,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap IzbriÅ¡i Izbor" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12183,6 +12188,11 @@ msgid "New Animation" msgstr "Animacija" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Lastnosti objekta." + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/sq.po b/editor/translations/sq.po index f405b8b8a9..d011c34407 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -2162,14 +2162,15 @@ msgstr "Të Preferuarat:" msgid "Recent:" msgstr "Të fundit:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Kërko:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Përputhjet:" @@ -2231,8 +2232,8 @@ msgstr "Kërko Resursin Zëvendësues:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5665,6 +5666,10 @@ msgid "Drag And Drop Selection" msgstr "Fshi të Selektuarat" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11886,6 +11891,11 @@ msgid "New Animation" msgstr "Animacionin i Ri" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Nyjet filtruese" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index 9d7c4c5db8..4a9d933004 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -2333,14 +2333,15 @@ msgstr "Омиљене:" msgid "Recent:" msgstr "ЧеÑте:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Тражи:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Подударање:" @@ -2402,8 +2403,8 @@ msgstr "Потражи замену за реÑурÑ:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5978,6 +5979,10 @@ msgid "Drag And Drop Selection" msgstr "МапаМреже ИÑпуни Одабрано" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12753,6 +12758,11 @@ msgstr "Ðнимација" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy +msgid "Filter animations" +msgstr "Филтрирај методе" + +#: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Speed:" msgstr "Брзина (FPS):" diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index d3f588aca6..41b23339de 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -2137,14 +2137,15 @@ msgstr "Omiljeno:" msgid "Recent:" msgstr "Nedavno:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Pretraga:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Podudaranja:" @@ -2204,8 +2205,8 @@ msgstr "Traži Resurs Zamene:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5364,6 +5365,10 @@ msgid "Drag And Drop Selection" msgstr "Sve sekcije" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11398,6 +11403,11 @@ msgid "New Animation" msgstr "Nova Animacija" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Animacija" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index 08b57d1a25..3baefa6356 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -14,7 +14,7 @@ # Mattias Münster <mattiasmun@gmail.com>, 2019. # Anonymous <noreply@weblate.org>, 2020. # Joakim Lundberg <joakim@joakimlundberg.com>, 2020. -# Kristoffer Grundström <swedishsailfishosuser@tutanota.com>, 2020, 2021. +# Kristoffer Grundström <swedishsailfishosuser@tutanota.com>, 2020, 2021, 2022. # Jonas Robertsson <jonas.robertsson@posteo.net>, 2020, 2021. # André Andersson <andre.eric.andersson@gmail.com>, 2020. # Andreas Westrell <andreas.westrell@gmail.com>, 2020. @@ -22,16 +22,18 @@ # Shaggy <anton_christoffersson@hotmail.com>, 2020. # Marcus Toftedahl <marcus.toftedahl@his.se>, 2020. # Alex25820 <Alexander_sjogren@hotmail.se>, 2021. -# Leon <joel.lundborg@gmail.com>, 2021. +# Leon <joel.lundborg@gmail.com>, 2021, 2022. # Kent Jofur <kent.jofur@gmail.com>, 2021. # Alex25820 <alexs25820@gmail.com>, 2021. +# Björn Ã…kesson <bjorn.akesson@gmail.com>, 2022. +# Kenny Andersson <kenny@ordinary.se>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-12-20 18:53+0000\n" -"Last-Translator: Alex25820 <alexs25820@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Kenny Andersson <kenny@ordinary.se>\n" "Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/" "godot/sv/>\n" "Language: sv\n" @@ -39,11 +41,12 @@ 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.10\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp +#, fuzzy msgid "Tablet Driver" -msgstr "" +msgstr "Drivrutin för surfplatta" #: core/bind/core_bind.cpp #, fuzzy @@ -51,18 +54,16 @@ msgid "Clipboard" msgstr "Klippbordet är tomt!" #: core/bind/core_bind.cpp -#, fuzzy msgid "Current Screen" -msgstr "Nuvarande Scen" +msgstr "Nuvarande Skärm" #: core/bind/core_bind.cpp msgid "Exit Code" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "V-Sync Enabled" -msgstr "Aktivera" +msgstr "V-Synk Aktivt" #: core/bind/core_bind.cpp main/main.cpp msgid "V-Sync Via Compositor" @@ -73,9 +74,8 @@ msgid "Delta Smoothing" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "Low Processor Usage Mode" -msgstr "Exportera Projekt" +msgstr "Läge för lÃ¥g processoranvändning" #: core/bind/core_bind.cpp msgid "Low Processor Usage Mode Sleep (µsec)" @@ -86,9 +86,8 @@ msgid "Keep Screen On" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "Min Window Size" -msgstr "Storlek:" +msgstr "Minsta fönsterstorlek" #: core/bind/core_bind.cpp #, fuzzy @@ -108,11 +107,11 @@ msgstr "Nytt Fönster" #: core/bind/core_bind.cpp core/project_settings.cpp msgid "Borderless" -msgstr "" +msgstr "Kantlös" #: core/bind/core_bind.cpp msgid "Per Pixel Transparency Enabled" -msgstr "" +msgstr "Genomskinlighet per pixel aktiverad" #: core/bind/core_bind.cpp core/project_settings.cpp #, fuzzy @@ -121,16 +120,16 @@ msgstr "Växla Fullskärm" #: core/bind/core_bind.cpp msgid "Maximized" -msgstr "" +msgstr "Maximerad" #: core/bind/core_bind.cpp msgid "Minimized" -msgstr "" +msgstr "Minimerad" #: core/bind/core_bind.cpp core/project_settings.cpp scene/gui/dialogs.cpp #: scene/gui/graph_node.cpp msgid "Resizable" -msgstr "" +msgstr "Anpassningsbar" #: core/bind/core_bind.cpp core/os/input_event.cpp scene/2d/node_2d.cpp #: scene/2d/physics_body_2d.cpp scene/2d/remote_transform_2d.cpp @@ -150,36 +149,32 @@ msgstr "Dockposition" #: scene/resources/primitive_meshes.cpp scene/resources/sky.cpp #: scene/resources/style_box.cpp scene/resources/texture.cpp #: scene/resources/visual_shader.cpp servers/visual_server.cpp -#, fuzzy msgid "Size" -msgstr "Storlek:" +msgstr "Storlek" #: core/bind/core_bind.cpp msgid "Endian Swap" msgstr "" #: core/bind/core_bind.cpp -#, fuzzy msgid "Editor Hint" -msgstr "Redigera Tema" +msgstr "Redigeringsförslag" #: core/bind/core_bind.cpp msgid "Print Error Messages" -msgstr "" +msgstr "Skriv ut felmeddelanden" #: core/bind/core_bind.cpp -#, fuzzy msgid "Iterations Per Second" -msgstr "Interpolationsläge" +msgstr "Upprepningar per sekund" #: core/bind/core_bind.cpp msgid "Target FPS" -msgstr "" +msgstr "MÃ¥l FPS" #: core/bind/core_bind.cpp -#, fuzzy msgid "Time Scale" -msgstr "Skala" +msgstr "Tidsskala" #: core/bind/core_bind.cpp main/main.cpp #, fuzzy @@ -201,13 +196,12 @@ msgid "Error Line" msgstr "Fel vid sparande" #: core/bind/core_bind.cpp -#, fuzzy msgid "Result" -msgstr "Sök Hjälp" +msgstr "Resultat" #: core/command_queue_mt.cpp core/message_queue.cpp main/main.cpp msgid "Memory" -msgstr "" +msgstr "Minne" #: core/command_queue_mt.cpp core/message_queue.cpp #: core/register_core_types.cpp drivers/gles2/rasterizer_canvas_base_gles2.cpp @@ -218,7 +212,7 @@ msgstr "" #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: servers/visual_server.cpp msgid "Limits" -msgstr "" +msgstr "Begränsningar" #: core/command_queue_mt.cpp #, fuzzy @@ -227,68 +221,63 @@ msgstr "Ctrl: Rotera" #: core/command_queue_mt.cpp msgid "Multithreading Queue Size (KB)" -msgstr "" +msgstr "FlertrÃ¥dsköstorlek (KB)" #: core/func_ref.cpp modules/visual_script/visual_script_builtin_funcs.cpp #: modules/visual_script/visual_script_func_nodes.cpp #: modules/visual_script/visual_script_nodes.cpp #: scene/resources/visual_shader_nodes.cpp -#, fuzzy msgid "Function" -msgstr "Funktioner" +msgstr "Funktion" #: core/image.cpp core/packed_data_container.cpp scene/2d/polygon_2d.cpp #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Data" -msgstr "" +msgstr "Data" #: core/io/file_access_network.cpp core/register_core_types.cpp #: editor/editor_file_dialog.cpp editor/editor_settings.cpp main/main.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp #: modules/webrtc/webrtc_data_channel.h modules/websocket/websocket_macros.h #: scene/gui/file_dialog.cpp -#, fuzzy msgid "Network" -msgstr "Nätverksprofilerare" +msgstr "Nätverk" #: core/io/file_access_network.cpp -#, fuzzy msgid "Remote FS" -msgstr "Ta bort" +msgstr "Fjärr FS" #: core/io/file_access_network.cpp -#, fuzzy msgid "Page Size" -msgstr "Sida: " +msgstr "Sidstorlek" #: core/io/file_access_network.cpp msgid "Page Read Ahead" -msgstr "" +msgstr "Sida läs framÃ¥t" #: core/io/http_client.cpp msgid "Blocking Mode Enabled" -msgstr "" +msgstr "Blockeringsläge Aktiverat" #: core/io/http_client.cpp -#, fuzzy msgid "Connection" -msgstr "Anslut" +msgstr "Anslutning" #: core/io/http_client.cpp msgid "Read Chunk Size" -msgstr "" +msgstr "Läs segmentstorlek" #: core/io/marshalls.cpp msgid "Object ID" -msgstr "" +msgstr "Objekt ID" #: core/io/multiplayer_api.cpp core/io/packet_peer.cpp msgid "Allow Object Decoding" -msgstr "" +msgstr "TillÃ¥t objekt avkodning" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp msgid "Refuse New Network Connections" -msgstr "" +msgstr "Neka nya nätverksanslutningar" #: core/io/multiplayer_api.cpp scene/main/scene_tree.cpp #, fuzzy @@ -312,36 +301,35 @@ msgstr "Transformera" #: core/io/packet_peer.cpp msgid "Encode Buffer Max Size" -msgstr "" +msgstr "Maxstorlek för kodningsbufferten" #: core/io/packet_peer.cpp msgid "Input Buffer Max Size" -msgstr "" +msgstr "Maximal storlek pÃ¥ inmatningsbufferten" #: core/io/packet_peer.cpp msgid "Output Buffer Max Size" -msgstr "" +msgstr "Maxstorlek för utgÃ¥ngsbuffert" #: core/io/packet_peer.cpp msgid "Stream Peer" -msgstr "" +msgstr "Strömningsenhet" #: core/io/stream_peer.cpp msgid "Big Endian" -msgstr "" +msgstr "Big Endian" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Datamatris" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" -msgstr "" +msgstr "Blockering av handskakning" #: core/io/udp_server.cpp -#, fuzzy msgid "Max Pending Connections" -msgstr "Redigera Koppling:" +msgstr "Max väntande anslutningar" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -356,12 +344,11 @@ msgstr "Förväntade en sträng av längden 1 (ett tecken)." #: 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 "Inte nog med bytes för att avkoda, eller ogiltigt format." +msgstr "Otillräckligt antal bytes för att avkoda, eller ogiltigt format." #: core/math/expression.cpp -#, fuzzy msgid "Invalid input %d (not passed) in expression" -msgstr "Ogiltig indata %i (ej överförd) i uttrycket" +msgstr "Ogiltig inmatning %d (ej överförd) i uttrycket" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -390,7 +377,7 @@ msgstr "I anrop till '%s':" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp msgid "Seed" -msgstr "" +msgstr "Seed" #: core/math/random_number_generator.cpp #, fuzzy @@ -399,11 +386,11 @@ msgstr "Status" #: core/message_queue.cpp msgid "Message Queue" -msgstr "" +msgstr "Meddelandekö" #: core/message_queue.cpp msgid "Max Size (KB)" -msgstr "" +msgstr "Maxstorlek (KB)" #: core/os/input.cpp #, fuzzy @@ -412,7 +399,7 @@ msgstr "Växla Läge" #: core/os/input.cpp msgid "Use Accumulated Input" -msgstr "" +msgstr "Använd ackumulerad input" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -420,13 +407,12 @@ msgid "Device" msgstr "Enhet" #: core/os/input_event.cpp -#, fuzzy msgid "Alt" -msgstr "Alla" +msgstr "Alt" #: core/os/input_event.cpp msgid "Shift" -msgstr "" +msgstr "Shift" #: core/os/input_event.cpp #, fuzzy @@ -435,7 +421,7 @@ msgstr "Versionshantering" #: core/os/input_event.cpp msgid "Meta" -msgstr "" +msgstr "Meta" #: core/os/input_event.cpp #, fuzzy @@ -455,9 +441,8 @@ msgid "Pressed" msgstr "Ã…terställ Zoom" #: core/os/input_event.cpp -#, fuzzy msgid "Scancode" -msgstr "Skanna" +msgstr "Scancode" #: core/os/input_event.cpp msgid "Physical Scancode" @@ -465,7 +450,7 @@ msgstr "" #: core/os/input_event.cpp msgid "Unicode" -msgstr "" +msgstr "Unicode" #: core/os/input_event.cpp msgid "Echo" @@ -482,9 +467,8 @@ msgid "Global Position" msgstr "Konstant" #: core/os/input_event.cpp -#, fuzzy msgid "Factor" -msgstr "Vektor" +msgstr "Faktor" #: core/os/input_event.cpp #, fuzzy @@ -493,25 +477,23 @@ msgstr "Automatisk Indentering" #: core/os/input_event.cpp msgid "Doubleclick" -msgstr "" +msgstr "Dubbelklick" #: core/os/input_event.cpp msgid "Tilt" msgstr "" #: core/os/input_event.cpp -#, fuzzy msgid "Pressure" -msgstr "Ã…terställ Zoom" +msgstr "Tryck" #: core/os/input_event.cpp msgid "Pen Inverted" -msgstr "" +msgstr "Invertera penna" #: core/os/input_event.cpp -#, fuzzy msgid "Relative" -msgstr "GDNative" +msgstr "Relativ" #: core/os/input_event.cpp scene/2d/camera_2d.cpp scene/2d/cpu_particles_2d.cpp #: scene/3d/cpu_particles.cpp scene/3d/interpolated_camera.cpp @@ -527,9 +509,8 @@ msgid "Axis" msgstr "Axel" #: core/os/input_event.cpp -#, fuzzy msgid "Axis Value" -msgstr "Värde" +msgstr "Axelvärde" #: core/os/input_event.cpp modules/visual_script/visual_script_func_nodes.cpp #, fuzzy @@ -545,21 +526,19 @@ msgstr "Ã…tgärd" #: core/os/input_event.cpp scene/resources/environment.cpp #: scene/resources/material.cpp msgid "Strength" -msgstr "" +msgstr "Styrka" #: core/os/input_event.cpp msgid "Delta" -msgstr "" +msgstr "Delta" #: core/os/input_event.cpp -#, fuzzy msgid "Channel" -msgstr "Ändra" +msgstr "Kanal" #: core/os/input_event.cpp main/main.cpp -#, fuzzy msgid "Message" -msgstr "Synkronisera Skript-ändringar" +msgstr "Meddelande" #: core/os/input_event.cpp #, fuzzy @@ -570,11 +549,11 @@ msgstr "Växla" #: scene/2d/physics_body_2d.cpp scene/3d/cpu_particles.cpp #: scene/3d/physics_body.cpp scene/resources/particles_material.cpp msgid "Velocity" -msgstr "" +msgstr "Hastighet" #: core/os/input_event.cpp msgid "Instrument" -msgstr "" +msgstr "Instrument" #: core/os/input_event.cpp #, fuzzy @@ -588,13 +567,13 @@ msgstr "" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp #: platform/windows/export/export.cpp -#, fuzzy msgid "Application" -msgstr "Ã…tgärd" +msgstr "Applikation" #: core/project_settings.cpp main/main.cpp +#, fuzzy msgid "Config" -msgstr "" +msgstr "Konfigurera" #: core/project_settings.cpp #, fuzzy @@ -630,7 +609,7 @@ msgstr "Kör" #: core/project_settings.cpp editor/editor_node.cpp #: editor/run_settings_dialog.cpp main/main.cpp msgid "Main Scene" -msgstr "" +msgstr "Huvudscen" #: core/project_settings.cpp #, fuzzy @@ -644,15 +623,15 @@ msgstr "Avaktiverad" #: core/project_settings.cpp msgid "Use Hidden Project Data Directory" -msgstr "" +msgstr "Använda dold projektdatakatalog" #: core/project_settings.cpp msgid "Use Custom User Dir" -msgstr "" +msgstr "Använd anpassad användarkatalog" #: core/project_settings.cpp msgid "Custom User Dir Name" -msgstr "" +msgstr "Anpassad användarkatalognamn" #: core/project_settings.cpp main/main.cpp #: platform/javascript/export/export.cpp platform/osx/export/export.cpp @@ -665,7 +644,7 @@ msgstr "Ersätt Alla" #: modules/opensimplex/noise_texture.cpp scene/2d/line_2d.cpp #: scene/3d/label_3d.cpp scene/gui/text_edit.cpp scene/resources/texture.cpp msgid "Width" -msgstr "" +msgstr "Bredd" #: core/project_settings.cpp main/main.cpp modules/csg/csg_shape.cpp #: modules/gltf/gltf_node.cpp modules/opensimplex/noise_texture.cpp @@ -673,13 +652,12 @@ msgstr "" #: scene/resources/capsule_shape_2d.cpp scene/resources/cylinder_shape.cpp #: scene/resources/font.cpp scene/resources/navigation_mesh.cpp #: scene/resources/primitive_meshes.cpp scene/resources/texture.cpp -#, fuzzy msgid "Height" -msgstr "Höger" +msgstr "Höjd" #: core/project_settings.cpp msgid "Always On Top" -msgstr "" +msgstr "Alltid överst" #: core/project_settings.cpp #, fuzzy @@ -706,11 +684,11 @@ msgstr "Ladda standard Buss-Layouten." #: editor/editor_settings.cpp editor/script_create_dialog.cpp #: scene/2d/camera_2d.cpp scene/3d/light.cpp scene/main/node.cpp msgid "Editor" -msgstr "" +msgstr "Redigerare" #: core/project_settings.cpp msgid "Main Run Args" -msgstr "" +msgstr "Huvudkörnings arg" #: core/project_settings.cpp #, fuzzy @@ -719,11 +697,12 @@ msgstr "Scen Filsökväg:" #: core/project_settings.cpp msgid "Search In File Extensions" -msgstr "" +msgstr "Sök i filändelser" #: core/project_settings.cpp +#, fuzzy msgid "Script Templates Search Path" -msgstr "" +msgstr "Sökväg för skriptmallar" #: core/project_settings.cpp #, fuzzy @@ -738,16 +717,16 @@ msgstr "Versionshantering" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp msgid "Input" -msgstr "" +msgstr "Input" #: core/project_settings.cpp +#, fuzzy msgid "UI Accept" -msgstr "" +msgstr "UI Acceptera" #: core/project_settings.cpp -#, fuzzy msgid "UI Select" -msgstr "Välj" +msgstr "Ui Välj" #: core/project_settings.cpp #, fuzzy @@ -779,9 +758,8 @@ msgid "UI Up" msgstr "" #: core/project_settings.cpp -#, fuzzy msgid "UI Down" -msgstr "Ladda ner" +msgstr "UI Ner" #: core/project_settings.cpp #, fuzzy @@ -790,11 +768,11 @@ msgstr "Sida: " #: core/project_settings.cpp msgid "UI Page Down" -msgstr "" +msgstr "UI sida ner" #: core/project_settings.cpp msgid "UI Home" -msgstr "" +msgstr "UI hem" #: core/project_settings.cpp msgid "UI End" @@ -931,7 +909,7 @@ msgstr "" #: core/register_core_types.cpp msgid "TCP" -msgstr "" +msgstr "TCP" #: core/register_core_types.cpp #, fuzzy @@ -944,11 +922,12 @@ msgstr "" #: core/register_core_types.cpp msgid "Max Buffer (Power of 2)" -msgstr "" +msgstr "Max buffer (2 potenser)" #: core/register_core_types.cpp editor/editor_settings.cpp main/main.cpp +#, fuzzy msgid "SSL" -msgstr "" +msgstr "SSL" #: core/register_core_types.cpp main/main.cpp #, fuzzy @@ -964,7 +943,7 @@ msgstr "Resurs" #: core/resource.cpp #, fuzzy msgid "Local To Scene" -msgstr "Stäng Scen" +msgstr "Lokalt till scenen" #: core/resource.cpp editor/dependency_editor.cpp #: editor/editor_autoload_settings.cpp editor/plugins/path_editor_plugin.cpp @@ -983,12 +962,13 @@ msgid "Locale" msgstr "" #: core/translation.cpp +#, fuzzy msgid "Test" -msgstr "" +msgstr "Test" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "" +msgstr "Reserv" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -1023,18 +1003,21 @@ msgstr "EiB" #: drivers/gles3/rasterizer_canvas_base_gles3.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp modules/gltf/gltf_state.cpp +#, fuzzy msgid "Buffers" -msgstr "" +msgstr "Buffertar" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp +#, fuzzy msgid "Canvas Polygon Buffer Size (KB)" -msgstr "" +msgstr "Buffertstorlek för canvaspolygon (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp +#, fuzzy msgid "Canvas Polygon Index Buffer Size (KB)" -msgstr "" +msgstr "Buffertstorlek för Canvas Polygon Index (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp @@ -1045,8 +1028,9 @@ msgstr "" #: servers/physics_2d/physics_2d_server_wrap_mt.h #: servers/physics_2d/space_2d_sw.cpp servers/physics_2d_server.cpp #: servers/visual_server.cpp +#, fuzzy msgid "2D" -msgstr "" +msgstr "2D" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp @@ -1057,42 +1041,47 @@ msgstr "Alternativ" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Use GPU Pixel Snap" -msgstr "" +msgstr "Använd GPU pixel vidhäftning" #: drivers/gles2/rasterizer_scene_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Immediate Buffer Size (KB)" -msgstr "" +msgstr "Omedelbar buffertstorlek (KB)" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp +#, fuzzy msgid "Lightmapping" -msgstr "" +msgstr "Ljusmappning" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp +#, fuzzy msgid "Use Bicubic Sampling" -msgstr "" +msgstr "Använd bikubisk sampling" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Max Renderable Elements" -msgstr "" +msgstr "Max Ã¥tergivningsbara element" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Lights" -msgstr "" +msgstr "Max renderbara ljuskällor" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Max Renderable Reflections" -msgstr "" +msgstr "Max renderingsbara reflektioner" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Lights Per Object" -msgstr "" +msgstr "Max antal ljuskällor per objekt" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Subsurface Scattering" -msgstr "" +msgstr "Subsurface Scattering" #: drivers/gles3/rasterizer_scene_gles3.cpp editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp @@ -1116,16 +1105,19 @@ msgid "Weight Samples" msgstr "" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Voxel Cone Tracing" -msgstr "" +msgstr "Voxel Kon SpÃ¥rning" #: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp +#, fuzzy msgid "High Quality" -msgstr "" +msgstr "Hög kvalitet" #: drivers/gles3/rasterizer_storage_gles3.cpp +#, fuzzy msgid "Blend Shape Max Buffer Size (KB)" -msgstr "" +msgstr "Mixform Max buffertstorlek (KB)" #. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror). #: editor/animation_bezier_editor.cpp @@ -1178,7 +1170,7 @@ msgstr "Anim Ta Bort Nycklar" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Time" -msgstr "Anim Ändra Nyckelbildstid" +msgstr "Anim Ändra Tidsnyckelns Tid" #: editor/animation_track_editor.cpp msgid "Anim Change Transition" @@ -1236,7 +1228,7 @@ msgstr "Välj Färg" #: editor/animation_track_editor.cpp main/main.cpp #: modules/mono/mono_gd/gd_mono.cpp msgid "Args" -msgstr "" +msgstr "Argument" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #: editor/script_editor_debugger.cpp modules/gltf/gltf_accessor.cpp @@ -1247,23 +1239,25 @@ msgstr "Typ" #: editor/animation_track_editor.cpp msgid "In Handle" -msgstr "" +msgstr "Handtag in" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Out Handle" -msgstr "" +msgstr "Handtag ut" #: editor/animation_track_editor.cpp #: editor/import/resource_importer_texture.cpp #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp +#, fuzzy msgid "Stream" -msgstr "" +msgstr "Ström" #: editor/animation_track_editor.cpp #, fuzzy msgid "Start Offset" -msgstr "Icon Läge" +msgstr "Startförskjutning" #: editor/animation_track_editor.cpp #, fuzzy @@ -1282,7 +1276,7 @@ msgstr "Animation" #: editor/animation_track_editor.cpp msgid "Easing" -msgstr "" +msgstr "Lätta" #: editor/animation_track_editor.cpp msgid "Anim Multi Change Keyframe Time" @@ -1435,7 +1429,7 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Out-Handle:" -msgstr "" +msgstr "Handtag ut:" #: editor/animation_track_editor.cpp #, fuzzy @@ -1448,8 +1442,9 @@ msgid "Start (s):" msgstr "Starta" #: editor/animation_track_editor.cpp +#, fuzzy msgid "End (s):" -msgstr "" +msgstr "Slut (s):" #: editor/animation_track_editor.cpp #, fuzzy @@ -1509,7 +1504,7 @@ msgstr "Duplicera Nycklar" #: editor/animation_track_editor.cpp msgid "Add RESET Value(s)" -msgstr "" +msgstr "Lägg till RESET-värde(n)" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -1591,7 +1586,7 @@ msgstr "" #. TRANSLATORS: This describes the target of new animation track, will be inserted into another string. #: editor/animation_track_editor.cpp msgid "property '%s'" -msgstr "egenskapen '%s'" +msgstr "egenskap '%s'" #: editor/animation_track_editor.cpp msgid "Anim Create & Insert" @@ -1824,9 +1819,8 @@ msgid "Go to Previous Step" msgstr "GÃ¥ till FöregÃ¥ende Steg" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Apply Reset" -msgstr "Ã…terställ Zoom" +msgstr "Verkställ Ã¥terställning" #: editor/animation_track_editor.cpp msgid "Optimize Animation" @@ -2209,14 +2203,15 @@ msgstr "Favoriter:" msgid "Recent:" msgstr "Senaste:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Sök:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Matchar:" @@ -2276,8 +2271,8 @@ msgstr "Sök Ersättningsresurs:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2286,17 +2281,17 @@ msgstr "Öppna" #: editor/dependency_editor.cpp msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Ägare av: %s (Totalt: %d)" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Remove the selected files from the project? (Cannot be undone.)\n" "Depending on your filesystem configuration, the files will either be moved " "to the system trash or deleted permanently." msgstr "" -"Ta bort valda filer frÃ¥n projektet? (Kan ej Ã¥terställas)\n" -"Du kan hitta de borttagna filerna i systemets papperskorg." +"Ta bort de valda filerna frÃ¥n projektet? (Kan ej Ã¥ngras.)\n" +"Beroende pÃ¥ hur ditt filsystem är konfigurerat sÃ¥ kommer filerna antingen " +"flyttas till systemets papperskorg eller tas bort permanent." #: editor/dependency_editor.cpp msgid "" @@ -2381,7 +2376,7 @@ msgstr "Tack frÃ¥n Godot-gemenskapen!" #: editor/editor_about.cpp editor/editor_node.cpp editor/project_manager.cpp msgid "Click to copy." -msgstr "Klicka för att kopiera." +msgstr "Klicka för att kopiera" #: editor/editor_about.cpp msgid "Godot Engine contributors" @@ -2479,30 +2474,32 @@ msgid "Licenses" msgstr "Licenser" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Error opening asset file for \"%s\" (not in ZIP format)." -msgstr "Fel vid öppning av paketetfil, inte i zip-format." +msgstr "Fel vid öppning av tillgÃ¥ngsfilen för \"%s\" (inte i ZIP-format)." #: editor/editor_asset_installer.cpp msgid "%s (already exists)" msgstr "%s (existerar redan)" #: editor/editor_asset_installer.cpp +#, fuzzy msgid "Contents of asset \"%s\" - %d file(s) conflict with your project:" msgstr "" +"InnehÃ¥llet i resursen \"%s\" - %d fil(er) stÃ¥r i konflikt med ditt projekt:" #: editor/editor_asset_installer.cpp +#, fuzzy msgid "Contents of asset \"%s\" - No files conflict with your project:" msgstr "" +"InnehÃ¥llet i resursen \"%s\" - Inga filer stÃ¥r i konflikt med ditt projekt:" #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" msgstr "Dekomprimerar TillgÃ¥ngar" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "The following files failed extraction from asset \"%s\":" -msgstr "Följande filer misslyckades att packas upp frÃ¥n paketet:" +msgstr "Följande filer misslyckades att packas upp frÃ¥n paketet \"%s\":" #: editor/editor_asset_installer.cpp msgid "(and %s more files)" @@ -2510,7 +2507,7 @@ msgstr "(och %s fler filer)" #: editor/editor_asset_installer.cpp msgid "Asset \"%s\" installed successfully!" -msgstr "Paketet \"%s\" har installerats!" +msgstr "Installation av tillgÃ¥ngen \"%s\" lyckades!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -2522,9 +2519,8 @@ msgid "Install" msgstr "Installera" #: editor/editor_asset_installer.cpp -#, fuzzy msgid "Asset Installer" -msgstr "Paketinstallerare" +msgstr "TillgÃ¥ngsinstallerare" #: editor/editor_audio_buses.cpp msgid "Speakers" @@ -2705,8 +2701,9 @@ msgid "Invalid name." msgstr "Ogiltigt namn." #: editor/editor_autoload_settings.cpp +#, fuzzy msgid "Cannot begin with a digit." -msgstr "" +msgstr "Kan inte börja med en siffra." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" @@ -2771,7 +2768,7 @@ msgstr "%s är en ogiltig genväg. Filen existerar inte." #: editor/editor_autoload_settings.cpp msgid "%s is an invalid path. Not in resource path (res://)." -msgstr "" +msgstr "%s är en ogiltig genväg. Inte i resurs-genväg (res://)." #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" @@ -2851,7 +2848,7 @@ msgstr "Välj" #: editor/editor_export.cpp msgid "Project export for platform:" -msgstr "" +msgstr "Projektexport för plattformen:" #: editor/editor_export.cpp #, fuzzy @@ -2938,8 +2935,8 @@ msgid "" "Target platform requires 'PVRTC' texture compression for GLES2. Enable " "'Import Pvrtc' in Project Settings." msgstr "" -"MÃ¥lplattformen kräver 'PVRTC'-texturkomprimering för GLES2. Aktivera 'Import " -"Pvrtc' i projektinställningarna." +"MÃ¥lplattformen kräver 'PVRTC' texturkomprimering för GLES2. Aktivera " +"'Importera Pvrtc' i Projektinställningarna." #: editor/editor_export.cpp msgid "" @@ -2971,7 +2968,7 @@ msgstr "Redigera Tema" #: platform/javascript/export/export.cpp platform/osx/export/export.cpp #: platform/uwp/export/export.cpp msgid "Release" -msgstr "" +msgstr "Släpp" #: editor/editor_export.cpp #, fuzzy @@ -2980,11 +2977,12 @@ msgstr "Färg enhetlig." #: editor/editor_export.cpp msgid "64 Bits" -msgstr "" +msgstr "64 bitar" #: editor/editor_export.cpp +#, fuzzy msgid "Embed PCK" -msgstr "" +msgstr "Bädda in PCK" #: editor/editor_export.cpp platform/osx/export/export.cpp #, fuzzy @@ -3046,7 +3044,7 @@ msgstr "Hantera exportmallar..." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp msgid "PCK Embedding" -msgstr "" +msgstr "PCK Inbäddning" #: editor/editor_export.cpp msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." @@ -3054,7 +3052,7 @@ msgstr "Den inbäddade PCK fÃ¥r inte vara större än 4 GiB pÃ¥ 32 bitars export #: editor/editor_export.cpp msgid "Convert Text Resources To Binary On Export" -msgstr "" +msgstr "Konvertera textresurser till binära vid export" #: editor/editor_feature_profile.cpp msgid "3D Editor" @@ -3083,9 +3081,8 @@ msgid "FileSystem Dock" msgstr "FilSystem" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Importera" +msgstr "Importera Brygga" #: editor/editor_feature_profile.cpp msgid "Allows to view and edit 3D scenes." @@ -3097,17 +3094,19 @@ msgstr "TillÃ¥ter att redigera skript via den integrerade skript-redigeraren." #: editor/editor_feature_profile.cpp msgid "Provides built-in access to the Asset Library." -msgstr "" +msgstr "Ger inbyggd tillgÃ¥ng till tillgÃ¥ngsbiblioteket." #: editor/editor_feature_profile.cpp +#, fuzzy msgid "Allows editing the node hierarchy in the Scene dock." -msgstr "" +msgstr "TillÃ¥ter redigering av nodhierarkin i scendockan." #: editor/editor_feature_profile.cpp msgid "" "Allows to work with signals and groups of the node selected in the Scene " "dock." msgstr "" +"TillÃ¥ter arbete med signaler och grupper av noden som valts i Scendockan." #: editor/editor_feature_profile.cpp msgid "Allows to browse the local file system via a dedicated dock." @@ -3145,19 +3144,16 @@ msgid "(Editor Disabled, Properties Disabled)" msgstr "(Editor inaktiverad, Egenskaper inaktiverad)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Egenskaper" +msgstr "(Egenskaper avstängda)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Redigera Variabel" +msgstr "(Redigeraren är avstängd)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Beskrivning:" +msgstr "Klassalternativ:" #: editor/editor_feature_profile.cpp msgid "Enable Contextual Editor" @@ -3194,9 +3190,8 @@ msgid "Error saving profile to path: '%s'." msgstr "Fel vid laddning av mall '%s'." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Reset to Default" -msgstr "Ladda Standard" +msgstr "Ã…terställ till Standard" #: editor/editor_feature_profile.cpp msgid "Current Profile:" @@ -3249,18 +3244,16 @@ msgid "Create or import a profile to edit available classes and properties." msgstr "" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nytt namn:" +msgstr "Nytt profilnamn:" #: editor/editor_feature_profile.cpp msgid "Godot Feature Profile" msgstr "Godot funktions profil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "%d fler filer" +msgstr "Importera profil(er)" #: editor/editor_feature_profile.cpp #, fuzzy @@ -3294,9 +3287,8 @@ msgid "Copy Path" msgstr "Kopiera Sökväg" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "Open in File Manager" -msgstr "Visa I Filhanteraren" +msgstr "Öppna i filhanteraren" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp @@ -5556,7 +5548,7 @@ msgstr "Miniatyr..." #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "Anslutningar" #: editor/editor_settings.cpp #, fuzzy @@ -5674,6 +5666,10 @@ msgid "Drag And Drop Selection" msgstr "Alla urval" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11301,7 +11297,7 @@ msgstr "Spela" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" -msgstr "" +msgstr "Ortogonal" #: editor/plugins/spatial_editor_plugin.cpp modules/gltf/gltf_camera.cpp msgid "Perspective" @@ -11468,7 +11464,7 @@ msgstr "Partiklar" #: editor/plugins/spatial_editor_plugin.cpp msgid "FPS: %d (%s ms)" -msgstr "" +msgstr "FPS: %d (%s ms)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View." @@ -12049,6 +12045,11 @@ msgid "New Animation" msgstr "Animation" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Filtrera noder" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" @@ -24738,8 +24739,9 @@ msgid "Alpha" msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#, fuzzy msgid "Caret" -msgstr "" +msgstr "Markör" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Blink" @@ -25397,9 +25399,8 @@ msgid "Draw 2D Outlines" msgstr "" #: scene/main/scene_tree.cpp servers/visual_server.cpp -#, fuzzy msgid "Reflections" -msgstr "Riktningar" +msgstr "Reflektioner" #: scene/main/scene_tree.cpp msgid "Atlas Size" @@ -28332,12 +28333,13 @@ msgid "UV Contract Amount" msgstr "" #: servers/visual_server.cpp +#, fuzzy msgid "Use Simple PVS" -msgstr "" +msgstr "Använd enkel PVS" #: servers/visual_server.cpp msgid "PVS Logging" -msgstr "" +msgstr "PVS loggning" #: servers/visual_server.cpp #, fuzzy @@ -28350,8 +28352,9 @@ msgid "Remove Danglers" msgstr "Ta Bort Mall" #: servers/visual_server.cpp +#, fuzzy msgid "Flip Imported Portals" -msgstr "" +msgstr "Vänd importerade portaler" #: servers/visual_server.cpp #, fuzzy @@ -28359,8 +28362,9 @@ msgid "Occlusion Culling" msgstr "Redigera Polygon" #: servers/visual_server.cpp +#, fuzzy msgid "Max Active Spheres" -msgstr "" +msgstr "Max aktiva sfärer" #: servers/visual_server.cpp #, fuzzy @@ -28373,13 +28377,15 @@ msgid "Shader Compilation Mode" msgstr "Interpolationsläge" #: servers/visual_server.cpp +#, fuzzy msgid "Max Simultaneous Compiles" -msgstr "" +msgstr "Max samtidiga kompileringar" #: servers/visual_server.cpp msgid "Log Active Async Compiles Count" msgstr "" #: servers/visual_server.cpp +#, fuzzy msgid "Shader Cache Size (MB)" -msgstr "" +msgstr "Shader Cache Storlek (MB)" diff --git a/editor/translations/te.po b/editor/translations/te.po index 98eb54ce5c..03919233f7 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -2074,14 +2074,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2137,8 +2138,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5271,6 +5272,10 @@ msgid "Drag And Drop Selection" msgstr "" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11232,6 +11237,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "గణనలà±" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/th.po b/editor/translations/th.po index 9460318ef8..1690916a54 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -2223,14 +2223,15 @@ msgstr "ที่ชื่นชà¸à¸š:" msgid "Recent:" msgstr "ล่าสุด:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "ค้นหา:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "พบ:" @@ -2291,8 +2292,8 @@ msgstr "ค้นหาทรัพยาà¸à¸£à¸¡à¸²à¹à¸—นที่:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5653,6 +5654,10 @@ msgid "Drag And Drop Selection" msgstr "เติมที่เลืà¸à¸à¹ƒà¸™ GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11947,6 +11952,11 @@ msgid "New Animation" msgstr "à¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹ƒà¸«à¸¡à¹ˆ" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "วิธีà¸à¸²à¸£à¸à¸£à¸à¸‡" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "ความเร็ว:" diff --git a/editor/translations/tl.po b/editor/translations/tl.po index a7a9bacaeb..cc20958dd1 100644 --- a/editor/translations/tl.po +++ b/editor/translations/tl.po @@ -2175,14 +2175,15 @@ msgstr "Mga Paborito:" msgid "Recent:" msgstr "Kamakailan:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Maghanap:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Mga Tugma:" @@ -2242,8 +2243,8 @@ msgstr "Maghanap ng Pangpalit na Resource:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5467,6 +5468,10 @@ msgid "Drag And Drop Selection" msgstr "Kopyahin Ang Pinagpipilian" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11573,6 +11578,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Salain ang mga method" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Bilis:" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 3cbd52b7e4..4980240671 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -74,13 +74,16 @@ # Ramazan Aslan <legendraslan@gmail.com>, 2022. # paledega <paledega@yandex.ru>, 2022. # Yekez <yasintonge@gmail.com>, 2022. +# Deleted User <noreply+46833@weblate.org>, 2022. +# Emre <mr.inkaya@gmail.com>, 2022. +# Deleted User <noreply+46858@weblate.org>, 2022. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-03 00:44+0000\n" -"Last-Translator: Yekez <yasintonge@gmail.com>\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" +"Last-Translator: Deleted User <noreply+46858@weblate.org>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\n" @@ -88,7 +91,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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -333,15 +336,15 @@ msgstr "Transfer Modu" #: core/io/packet_peer.cpp msgid "Encode Buffer Max Size" -msgstr "" +msgstr "Kodlama ArabelleÄŸi Maksimum Boyutu" #: core/io/packet_peer.cpp msgid "Input Buffer Max Size" -msgstr "" +msgstr "GiriÅŸ ArabelleÄŸi Maksimum Boyutu" #: core/io/packet_peer.cpp msgid "Output Buffer Max Size" -msgstr "" +msgstr "Çıkış ArabelleÄŸi Maksimum Boyutu" #: core/io/packet_peer.cpp msgid "Stream Peer" @@ -349,11 +352,11 @@ msgstr "" #: core/io/stream_peer.cpp msgid "Big Endian" -msgstr "" +msgstr "big-endian" #: core/io/stream_peer.cpp msgid "Data Array" -msgstr "" +msgstr "Veri Dizisi" #: core/io/stream_peer_ssl.cpp msgid "Blocking Handshake" @@ -383,12 +386,10 @@ msgid "Invalid input %d (not passed) in expression" msgstr "İfadede geçersiz giriÅŸ %d" #: core/math/expression.cpp -#, fuzzy msgid "self can't be used because instance is null (not passed)" msgstr "self kullanılamaz çünkü örnek boÅŸ (geçilmedi)" #: core/math/expression.cpp -#, fuzzy msgid "Invalid operands to operator %s, %s and %s." msgstr "\"%s\" iÅŸlecinde geçersiz terimler, '%s' ve '%s'." @@ -410,8 +411,9 @@ msgstr "'%s' çaÄŸrıldığında:" #: core/math/random_number_generator.cpp #: modules/opensimplex/open_simplex_noise.cpp +#, fuzzy msgid "Seed" -msgstr "" +msgstr "Tohum" #: core/math/random_number_generator.cpp msgid "State" @@ -426,14 +428,12 @@ msgid "Max Size (KB)" msgstr "En Büyük Boyut (KB)" #: core/os/input.cpp -#, fuzzy msgid "Mouse Mode" -msgstr "Biçimi Taşı" +msgstr "Fare Modu" #: core/os/input.cpp -#, fuzzy msgid "Use Accumulated Input" -msgstr "GiriÅŸi Sil" +msgstr "BirikmiÅŸ Girdiyi Kullan" #: core/os/input_event.cpp editor/project_settings_editor.cpp #: servers/audio_server.cpp @@ -451,10 +451,9 @@ msgstr "Shift" #: core/os/input_event.cpp #, fuzzy msgid "Control" -msgstr "Ctrl" +msgstr "Kontrol TuÅŸu" #: core/os/input_event.cpp -#, fuzzy msgid "Meta" msgstr "Meta" @@ -463,9 +462,8 @@ msgid "Command" msgstr "Komut" #: core/os/input_event.cpp -#, fuzzy msgid "Physical" -msgstr " (Fiziksel)" +msgstr "Fiziksel" #: core/os/input_event.cpp scene/2d/touch_screen_button.cpp #: scene/gui/base_button.cpp scene/gui/texture_button.cpp @@ -474,7 +472,6 @@ msgid "Pressed" msgstr "Basılmış" #: core/os/input_event.cpp -#, fuzzy msgid "Scancode" msgstr "Tarama kodu" @@ -483,14 +480,12 @@ msgid "Physical Scancode" msgstr "Fiziksel TuÅŸ Kodu" #: core/os/input_event.cpp -#, fuzzy msgid "Unicode" -msgstr "Unicode" +msgstr "Evrensel Kod" #: core/os/input_event.cpp -#, fuzzy msgid "Echo" -msgstr "Eko" +msgstr "Yankı" #: core/os/input_event.cpp scene/gui/base_button.cpp msgid "Button Mask" @@ -501,9 +496,8 @@ msgid "Global Position" msgstr "Global Pozisyon" #: core/os/input_event.cpp -#, fuzzy msgid "Factor" -msgstr "Vektör" +msgstr "Etken" #: core/os/input_event.cpp msgid "Button Index" @@ -522,8 +516,9 @@ msgid "Pressure" msgstr "Baskı" #: core/os/input_event.cpp +#, fuzzy msgid "Pen Inverted" -msgstr "" +msgstr "Ters Kalem" #: core/os/input_event.cpp msgid "Relative" @@ -584,18 +579,16 @@ msgid "Velocity" msgstr "Hız" #: core/os/input_event.cpp -#, fuzzy msgid "Instrument" msgstr "Alet" #: core/os/input_event.cpp -#, fuzzy msgid "Controller Number" -msgstr "Satır Numarası:" +msgstr "Denetleyici Numarası" #: core/os/input_event.cpp msgid "Controller Value" -msgstr "" +msgstr "Denetleyici DeÄŸeri" #: core/project_settings.cpp editor/editor_node.cpp main/main.cpp #: platform/iphone/export/export.cpp platform/osx/export/export.cpp @@ -719,7 +712,7 @@ msgstr "Ana Sahne DeÄŸiÅŸtirgenleri:" #: core/project_settings.cpp #, fuzzy msgid "Scene Naming" -msgstr "Sahne Yolu:" +msgstr "Sahne Adlandırma" #: core/project_settings.cpp msgid "Search In File Extensions" @@ -732,12 +725,12 @@ msgstr "Script Dosyalarını Aramak İçin Dosya Yolu" #: core/project_settings.cpp #, fuzzy msgid "Version Control Autoload On Startup" -msgstr "BaÅŸlangıçta Otomatik Yükleme" +msgstr "BaÅŸlangıçta Otomatik Sürüm Kontrolü" #: core/project_settings.cpp #, fuzzy msgid "Version Control Plugin Name" -msgstr "Sürüm Kontrol" +msgstr "Sürüm Denetimi Eklenti Adı" #: core/project_settings.cpp scene/2d/collision_object_2d.cpp #: scene/3d/collision_object.cpp scene/gui/control.cpp @@ -921,7 +914,6 @@ msgid "Modules" msgstr "Modüller" #: core/register_core_types.cpp -#, fuzzy msgid "TCP" msgstr "TCP" @@ -930,8 +922,9 @@ msgid "Connect Timeout Seconds" msgstr "BaÄŸlanma Zaman Aşımı Süresi(Saniye)" #: core/register_core_types.cpp +#, fuzzy msgid "Packet Peer Stream" -msgstr "" +msgstr "Paket EÅŸ Akışı" #: core/register_core_types.cpp msgid "Max Buffer (Power of 2)" @@ -977,7 +970,7 @@ msgstr "Deneme" #: core/translation.cpp scene/resources/font.cpp msgid "Fallback" -msgstr "" +msgstr "Geri Dönüş" #: core/ustring.cpp scene/resources/segment_shape_2d.cpp msgid "B" @@ -1018,12 +1011,12 @@ msgstr "Arabellek" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Buffer Size (KB)" -msgstr "" +msgstr "Tuval Çokgen Arabellek Boyutu (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp msgid "Canvas Polygon Index Buffer Size (KB)" -msgstr "" +msgstr "Tuval Çokgen Dizini Arabellek Boyutu (KB)" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp editor/editor_settings.cpp @@ -1039,36 +1032,33 @@ msgstr "2D" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Snapping" msgstr "Akıllı Hizalama" #: drivers/gles2/rasterizer_canvas_base_gles2.cpp #: drivers/gles3/rasterizer_canvas_base_gles3.cpp -#, fuzzy msgid "Use GPU Pixel Snap" msgstr "Piksel Yapışması Kullan" #: drivers/gles2/rasterizer_scene_gles2.cpp #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Immediate Buffer Size (KB)" -msgstr "" +msgstr "Anlık Arabellek Boyutu (KB)" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp -#, fuzzy msgid "Lightmapping" -msgstr "Işık-Haritalarını PiÅŸir" +msgstr "Işık Haritalama" #: drivers/gles2/rasterizer_storage_gles2.cpp #: drivers/gles3/rasterizer_storage_gles3.cpp +#, fuzzy msgid "Use Bicubic Sampling" -msgstr "" +msgstr "Bicubic Örneklemeyi Kullanın" #: drivers/gles3/rasterizer_scene_gles3.cpp -#, fuzzy msgid "Max Renderable Elements" -msgstr "Maks. Renderlanabilinecek Ögeler" +msgstr "Maksimum İşlenebilir Öğeler" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Max Renderable Lights" @@ -1105,11 +1095,12 @@ msgstr "Yüzeyi Takip Et" #: drivers/gles3/rasterizer_scene_gles3.cpp msgid "Weight Samples" -msgstr "" +msgstr "Ağırlık Örnekleri" #: drivers/gles3/rasterizer_scene_gles3.cpp +#, fuzzy msgid "Voxel Cone Tracing" -msgstr "" +msgstr "Işın İzleme" #: drivers/gles3/rasterizer_scene_gles3.cpp scene/resources/environment.cpp msgid "High Quality" @@ -1117,7 +1108,7 @@ msgstr "Yüksek Kalite" #: drivers/gles3/rasterizer_storage_gles3.cpp msgid "Blend Shape Max Buffer Size (KB)" -msgstr "" +msgstr "Karışım Åžekli Maksimum Arabellek Boyutu (KB)" #. TRANSLATORS: Adjective, refers to the mode for Bezier handles (Free, Balanced, Mirror). #: editor/animation_bezier_editor.cpp @@ -1191,9 +1182,8 @@ msgstr "Animasyon DeÄŸiÅŸikliÄŸi ÇaÄŸrısı" #: editor/animation_track_editor.cpp scene/2d/animated_sprite.cpp #: scene/2d/sprite.cpp scene/3d/sprite_3d.cpp #: scene/resources/default_theme/default_theme.cpp -#, fuzzy msgid "Frame" -msgstr "Kare %" +msgstr "Kare" #: editor/animation_track_editor.cpp editor/editor_profiler.cpp #: scene/2d/cpu_particles_2d.cpp scene/2d/particles_2d.cpp @@ -1248,8 +1238,9 @@ msgstr "Tutamacı Ayarla" #: editor/import/resource_importer_texture.cpp #: scene/2d/audio_stream_player_2d.cpp scene/3d/audio_stream_player_3d.cpp #: scene/audio/audio_stream_player.cpp scene/gui/video_player.cpp +#, fuzzy msgid "Stream" -msgstr "" +msgstr "Aktarım" #: editor/animation_track_editor.cpp #, fuzzy @@ -1410,7 +1401,7 @@ msgstr "Tür:" #: editor/animation_track_editor.cpp #, fuzzy msgid "(Invalid, expected type: %s)" -msgstr "Geçersiz Dışa Aktarım Åžablonu:" +msgstr "(Geçersiz Dışa Aktarım Åžablonu: %s)" #: editor/animation_track_editor.cpp msgid "Easing:" @@ -1429,22 +1420,22 @@ msgstr "Tutamacı Ayarla" #: editor/animation_track_editor.cpp #, fuzzy msgid "Stream:" -msgstr "Radyo Ögesi" +msgstr "Aktarım:" #: editor/animation_track_editor.cpp #, fuzzy msgid "Start (s):" -msgstr "Yeniden BaÅŸlat (sn):" +msgstr "BaÅŸlangıç (lar):" #: editor/animation_track_editor.cpp #, fuzzy msgid "End (s):" -msgstr "Açılma (sn):" +msgstr "BitiÅŸ (ler):" #: editor/animation_track_editor.cpp #, fuzzy msgid "Animation Clip:" -msgstr "Animasyonlar:" +msgstr "Animasyon Klibi:" #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" @@ -1535,7 +1526,7 @@ msgstr "Düzenleyici" #: editor/animation_track_editor.cpp editor/editor_settings.cpp #, fuzzy msgid "Confirm Insert Track" -msgstr "Animasyon İz & Anahtar Ekle" +msgstr "Parça Eklemeyi Onayla" #. TRANSLATORS: %s will be replaced by a phrase describing the target of track. #: editor/animation_track_editor.cpp @@ -1662,7 +1653,7 @@ msgstr "Yöntem İz Anahtarı Ekle" #: editor/animation_track_editor.cpp #, fuzzy msgid "Method not found in object:" -msgstr "Metot, nesne içinde bulunamadı: " +msgstr "Metot, nesne içinde bulunamadı:" #: editor/animation_track_editor.cpp msgid "Anim Move Keys" @@ -2195,14 +2186,15 @@ msgstr "BeÄŸeniler:" msgid "Recent:" msgstr "Yakın zamanda:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Ara:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "EÅŸleÅŸmeler:" @@ -2262,8 +2254,8 @@ msgstr "Yerine Geçecek Kaynak Ara:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -2271,8 +2263,9 @@ msgid "Open" msgstr "Aç" #: editor/dependency_editor.cpp +#, fuzzy msgid "Owners of: %s (Total: %d)" -msgstr "" +msgstr "Sahipleri: %s (Toplam: %d)" #: editor/dependency_editor.cpp msgid "" @@ -2631,7 +2624,7 @@ msgstr "'%s' dosyası bulunamadı." #: editor/editor_audio_buses.cpp #, fuzzy msgid "Layout:" -msgstr "YerleÅŸim Düzeni" +msgstr "YerleÅŸim Düzeni:" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -2682,7 +2675,7 @@ msgstr "Yeni bir Bus YerleÅŸim Düzeni oluÅŸtur." #: editor/editor_audio_buses.cpp #, fuzzy msgid "Audio Bus Layout" -msgstr "Audio Bus YerleÅŸim Düzenini Aç" +msgstr "Ses Veri Yolu Düzeni" #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -2834,23 +2827,24 @@ msgid "Choose" msgstr "Seç" #: editor/editor_export.cpp +#, fuzzy msgid "Project export for platform:" -msgstr "" +msgstr "Platform için proje dışa aktarımı:" #: editor/editor_export.cpp #, fuzzy msgid "Completed with errors." -msgstr "Düğüm Yolunu Kopyala" +msgstr "Hatalarla tamamlandı." #: editor/editor_export.cpp #, fuzzy msgid "Completed successfully." -msgstr "Paket BaÅŸarı ile Kuruldu!" +msgstr "BaÅŸarıyla tamamlandı." #: editor/editor_export.cpp #, fuzzy msgid "Failed." -msgstr "BaÅŸarısız:" +msgstr "BaÅŸarısız." #: editor/editor_export.cpp msgid "Storing File:" @@ -2867,27 +2861,27 @@ msgstr "Çıkınla" #: editor/editor_export.cpp #, fuzzy msgid "Save PCK" -msgstr "Farklı Kaydet" +msgstr "PCK'yi kaydet" #: editor/editor_export.cpp #, fuzzy msgid "Cannot create file \"%s\"." -msgstr "Klasör oluÅŸturulamadı." +msgstr "\"%s\" dosyası oluÅŸturulamıyor." #: editor/editor_export.cpp #, fuzzy msgid "Failed to export project files." -msgstr "Proje dosyaları dışa aktarılamadı" +msgstr "Proje dosyaları dışa aktarılamadı." #: editor/editor_export.cpp #, fuzzy msgid "Can't open file to read from path \"%s\"." -msgstr "Dosya yazmak için açılamıyor:" +msgstr "\"%s\" yolundan okunacak dosya açılamıyor." #: editor/editor_export.cpp #, fuzzy msgid "Save ZIP" -msgstr "Farklı Kaydet" +msgstr "ZIP dosyasını kaydet" #: editor/editor_export.cpp msgid "" @@ -2950,7 +2944,7 @@ msgstr "" #: platform/osx/export/export.cpp platform/uwp/export/export.cpp #, fuzzy msgid "Custom Template" -msgstr "Editör Teması" +msgstr "Özel Åžablon" #: editor/editor_export.cpp editor/project_export.cpp #: platform/android/export/export_plugin.cpp platform/iphone/export/export.cpp @@ -2962,36 +2956,42 @@ msgstr "Yayınlamak" #: editor/editor_export.cpp #, fuzzy msgid "Binary Format" -msgstr "Renk operatörü." +msgstr "Çift Biçim" #: editor/editor_export.cpp +#, fuzzy msgid "64 Bits" -msgstr "" +msgstr "64 Bit" #: editor/editor_export.cpp +#, fuzzy msgid "Embed PCK" -msgstr "" +msgstr "PCK'yı yerleÅŸtirin" #: editor/editor_export.cpp platform/osx/export/export.cpp #, fuzzy msgid "Texture Format" -msgstr "DokuBölgesi" +msgstr "Doku Biçimi" #: editor/editor_export.cpp +#, fuzzy msgid "BPTC" -msgstr "" +msgstr "BPTC" #: editor/editor_export.cpp platform/osx/export/export.cpp +#, fuzzy msgid "S3TC" -msgstr "" +msgstr "S3TC" #: editor/editor_export.cpp platform/osx/export/export.cpp +#, fuzzy msgid "ETC" -msgstr "" +msgstr "ETC" #: editor/editor_export.cpp platform/osx/export/export.cpp +#, fuzzy msgid "ETC2" -msgstr "" +msgstr "ETC2" #: editor/editor_export.cpp #, fuzzy @@ -3013,7 +3013,7 @@ msgstr "Özel yayınlama ÅŸablonu bulunamadı." #: editor/editor_export.cpp #, fuzzy msgid "Prepare Template" -msgstr "Åžablonlarını Yönet" +msgstr "Åžablon Hazırla" #: editor/editor_export.cpp platform/osx/export/export.cpp #, fuzzy @@ -3023,12 +3023,12 @@ msgstr "Belirtilen Dışa aktarım yolu mevcut deÄŸil:" #: editor/editor_export.cpp platform/javascript/export/export.cpp #, fuzzy msgid "Template file not found: \"%s\"." -msgstr "Åžablon dosyası bulunamadı:" +msgstr "Åžablon dosyası bulunamadı: \"%s\"." #: editor/editor_export.cpp #, fuzzy msgid "Failed to copy export template." -msgstr "Geçersiz Dışa Aktarım Åžablonu:" +msgstr "Dışa aktarma ÅŸablonu kopyalanamadı." #: editor/editor_export.cpp platform/windows/export/export.cpp #: platform/x11/export/export.cpp @@ -3041,8 +3041,9 @@ msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." msgstr "32-bit dışa aktarımlarda gömülü PCK 4GiB'tan büyük olamaz." #: editor/editor_export.cpp +#, fuzzy msgid "Convert Text Resources To Binary On Export" -msgstr "" +msgstr "Dışa Aktarmada Metin Kaynaklarını İkili Dosyaya Dönüştür" #: editor/editor_feature_profile.cpp msgid "3D Editor" @@ -3253,7 +3254,7 @@ msgstr "Dışa Aktarım Åžablonlarını Yönet" #: editor/editor_feature_profile.cpp #, fuzzy msgid "Default Feature Profile" -msgstr "Godot Özellik Profili" +msgstr "Varsayılan Özellik Profili" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -3327,12 +3328,12 @@ msgstr "Bir Dosya Kaydet" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp #, fuzzy msgid "Access" -msgstr "BaÅŸarılı!" +msgstr "EriÅŸim" #: editor/editor_file_dialog.cpp editor/editor_settings.cpp #, fuzzy msgid "Display Mode" -msgstr "Oynatma Modu:" +msgstr "Ekran Modu" #: editor/editor_file_dialog.cpp #: editor/import/resource_importer_layered_texture.cpp @@ -3347,32 +3348,33 @@ msgstr "Oynatma Modu:" #: servers/audio/effects/audio_effect_distortion.cpp #, fuzzy msgid "Mode" -msgstr "Kaydırma Biçimi" +msgstr "Mod" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp #, fuzzy msgid "Current Dir" -msgstr "Geçerli:" +msgstr "Geçerli Dizin" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp #, fuzzy msgid "Current File" -msgstr "Åžu Anki Profil:" +msgstr "Geçerli Dosya" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp #, fuzzy msgid "Current Path" -msgstr "Geçerli:" +msgstr "Geçerli Yol" #: editor/editor_file_dialog.cpp editor/editor_settings.cpp #: scene/gui/file_dialog.cpp #, fuzzy msgid "Show Hidden Files" -msgstr "Gizli Dosyalari Aç / Kapat" +msgstr "Gizli Dosyaları Göster" #: editor/editor_file_dialog.cpp +#, fuzzy msgid "Disable Overwrite Warning" -msgstr "" +msgstr "Üzerine Yazma Uyarısını Devre Dışı Bırak" #: editor/editor_file_dialog.cpp msgid "Go Back" @@ -3474,8 +3476,9 @@ msgid "(Re)Importing Assets" msgstr "Varlıklar Yeniden-İçe Aktarılıyor" #: editor/editor_file_system.cpp +#, fuzzy msgid "Reimport Missing Imported Files" -msgstr "" +msgstr "İçe Aktarılan Eksik Dosyaları Yeniden İçe Aktar" #: editor/editor_help.cpp scene/2d/camera_2d.cpp scene/gui/control.cpp #: scene/gui/nine_patch_rect.cpp scene/resources/dynamic_font.cpp @@ -3507,7 +3510,7 @@ msgstr "Özellikler" #: editor/editor_help.cpp #, fuzzy msgid "overrides %s:" -msgstr "% üzerine yazılmışlar:" +msgstr "%s'yi geçersiz kılar:" #: editor/editor_help.cpp msgid "default:" @@ -3579,7 +3582,7 @@ msgstr "" #: modules/gdscript/gdscript_editor.cpp #, fuzzy msgid "Text Editor" -msgstr "Düzenleyiciyi Aç" +msgstr "Metin Düzenleyici" #: editor/editor_help.cpp editor/editor_node.cpp editor/editor_settings.cpp #: editor/plugins/shader_editor_plugin.cpp @@ -3587,8 +3590,9 @@ msgid "Help" msgstr "Yardım" #: editor/editor_help.cpp +#, fuzzy msgid "Sort Functions Alphabetically" -msgstr "" +msgstr "Fonksiyonları Alfabetik Olarak Sırala" #: editor/editor_help_search.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp @@ -3670,34 +3674,34 @@ msgstr "Özellik:" #: editor/editor_inspector.cpp editor/editor_spin_slider.cpp #, fuzzy msgid "Label" -msgstr "DeÄŸer" +msgstr "Etiket" #: editor/editor_inspector.cpp editor/editor_spin_slider.cpp #: scene/resources/default_theme/default_theme.cpp #, fuzzy msgid "Read Only" -msgstr "Sadece Metotlar" +msgstr "Sadece Okunur" #: editor/editor_inspector.cpp editor/plugins/item_list_editor_plugin.cpp #, fuzzy msgid "Checkable" -msgstr "Öğeyi Denetle" +msgstr "Kontrol edilebilir" #: editor/editor_inspector.cpp editor/plugins/item_list_editor_plugin.cpp #: scene/resources/default_theme/default_theme.cpp #, fuzzy msgid "Checked" -msgstr "Denetlenen Öğe" +msgstr "Kontrol edildi" #: editor/editor_inspector.cpp #, fuzzy msgid "Draw Red" -msgstr "Çizim ÇaÄŸrıları:" +msgstr "Kırmızı Çiz" #: editor/editor_inspector.cpp #, fuzzy msgid "Keying" -msgstr "Oynat" +msgstr "Anahtarlama" #: editor/editor_inspector.cpp msgid "Pin value" @@ -4062,12 +4066,12 @@ msgstr "BetiÄŸi Hızlı Aç..." #: editor/editor_node.cpp #, fuzzy msgid "Save & Reload" -msgstr "Kaydet ve BaÅŸtan BaÅŸlat" +msgstr "Kaydet ve Yeniden Yükle" #: editor/editor_node.cpp #, fuzzy msgid "Save changes to '%s' before reloading?" -msgstr "Kapatmadan önce deÄŸiÅŸklikler buraya '%s' kaydedilsin mi?" +msgstr "Çıkmadan önce deÄŸiÅŸiklikler '%s' ‘ye kaydedilsin mi?" #: editor/editor_node.cpp msgid "Save & Close" @@ -4188,7 +4192,7 @@ msgstr "Proje Yöneticisi Açılsın Mı?" #: editor/editor_node.cpp #, fuzzy msgid "Save changes to the following scene(s) before reloading?" -msgstr "Çıkmadan önce deÄŸiÅŸiklikler aÅŸağıdaki sahne(ler)e kaydedilsin mi?" +msgstr "Çıkmadan önce deÄŸiÅŸiklikler sahne(ler)e kaydedilsin mi?" #: editor/editor_node.cpp msgid "Save & Quit" @@ -4372,54 +4376,53 @@ msgid "%d more files" msgstr "%d daha fazla dosyalar" #: editor/editor_node.cpp +#, fuzzy msgid "" "Unable to write to file '%s', file in use, locked or lacking permissions." msgstr "" +"'%s' dosyasına yazılamıyor, dosya kullanımda, kilitli veya izinler eksik." #: editor/editor_node.cpp editor/editor_settings.cpp editor/scene_tree_dock.cpp #: servers/arvr/arvr_interface.cpp -#, fuzzy msgid "Interface" -msgstr "Kullanıcı Arayüzü" +msgstr "Arayüz" #: editor/editor_node.cpp editor/editor_settings.cpp -#, fuzzy msgid "Scene Tabs" -msgstr "Sahne Sekmesine Geç" +msgstr "Sahne Sekmeleri" #: editor/editor_node.cpp -#, fuzzy msgid "Always Show Close Button" -msgstr "Daima Izgarayı Göster" +msgstr "Daima Kapatma Düğmesini Göster" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Resize If Many Tabs" -msgstr "" +msgstr "Çok Sayıda Sekme Varsa Yeniden Boyutlandır" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Minimum Width" -msgstr "" +msgstr "Minimum GeniÅŸlik" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Output" msgstr "Çıktı" #: editor/editor_node.cpp editor/editor_settings.cpp -#, fuzzy msgid "Always Clear Output On Play" -msgstr "Çıktıyı Temizle" +msgstr "Oynatıldığında Çıktıyı Daima Temizle" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Always Open Output On Play" -msgstr "" +msgstr "Oynatıldığında Çıktıyı Daima Aç" #: editor/editor_node.cpp editor/editor_settings.cpp msgid "Always Close Output On Stop" -msgstr "" +msgstr "DurdurulduÄŸunda Çıktıyı Daima Kapat" #: editor/editor_node.cpp +#, fuzzy msgid "Save On Focus Loss" -msgstr "" +msgstr "Odak Kaybından Tasarruf Edin" #: editor/editor_node.cpp editor/editor_settings.cpp #, fuzzy @@ -5235,9 +5238,8 @@ msgid "Size:" msgstr "Boyut:" #: editor/editor_properties_array_dict.cpp -#, fuzzy msgid "Page:" -msgstr "Sayfa: " +msgstr "Sayfa:" #: editor/editor_properties_array_dict.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -5537,7 +5539,7 @@ msgstr "Küçük Resim..." #: editor/editor_settings.cpp msgid "Docks" -msgstr "" +msgstr "Eklentiler" #: editor/editor_settings.cpp #, fuzzy @@ -5658,6 +5660,10 @@ msgid "Drag And Drop Selection" msgstr "GridMap Seçimi" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -6204,7 +6210,7 @@ msgstr "Önden Görünüm" #: modules/gdscript/language_server/gdscript_language_server.cpp #, fuzzy msgid "Remote Host" -msgstr "Uzak " +msgstr "Uzak Ana Bilgisayar" #: editor/editor_settings.cpp #: modules/gdscript/language_server/gdscript_language_server.cpp @@ -7199,7 +7205,7 @@ msgstr "İfade" #: editor/import/resource_importer_obj.cpp #, fuzzy msgid "Optimize Mesh Flags" -msgstr "Boyut: " +msgstr "Boyut:" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" @@ -7403,7 +7409,7 @@ msgstr "Işık-haritaları Üretiliyor" #: editor/import/resource_importer_scene.cpp #, fuzzy msgid "Generating for Mesh:" -msgstr "Örüntü için Üretiliyor: " +msgstr "Örüntü için Üretiliyor:" #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." @@ -7503,7 +7509,7 @@ msgstr "Rastgele Ölçek:" #: editor/import/resource_importer_texture.cpp #, fuzzy msgid "Size Limit" -msgstr "Boyut: " +msgstr "Boyut Limiti" #: editor/import/resource_importer_texture.cpp msgid "Detect 3D" @@ -8426,7 +8432,7 @@ msgstr "" #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy msgid "Transition:" -msgstr "GeçiÅŸ: " +msgstr "GeçiÅŸ:" #: editor/plugins/animation_state_machine_editor.cpp msgid "Play Mode:" @@ -10195,7 +10201,7 @@ msgstr "Oylum" #: editor/plugins/particles_editor_plugin.cpp #, fuzzy msgid "Emission Source:" -msgstr "Emisyon Kaynağı: " +msgstr "Emisyon Kaynağı:" #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -11293,15 +11299,13 @@ msgstr "Çevir" #. TRANSLATORS: Refers to changing the scale of a node in the 3D editor. #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Scaling:" -msgstr "Ölçekleniyor: " +msgstr "Ölçekleniyor:" #. TRANSLATORS: Refers to changing the position of a node in the 3D editor. #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Translating:" -msgstr "Çeviriliyor: " +msgstr "Çevriliyor:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotating %s degrees." @@ -11843,19 +11847,17 @@ msgid "Sprite" msgstr "HayaliÇizimlik" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Simplification:" -msgstr "SadeleÅŸtirme: " +msgstr "SadeleÅŸtirme:" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy msgid "Shrink (Pixels):" -msgstr "Sıkıştır (Pikselleri): " +msgstr "Sıkıştır (Pikselleri):" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Grow (Pixels):" -msgstr "Büyüt (Pikselleri): " +msgstr "Büyüt (Piksel):" #: editor/plugins/sprite_editor_plugin.cpp msgid "Update Preview" @@ -11918,6 +11920,11 @@ msgid "New Animation" msgstr "Yeni Animasyon" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Metotları filtrele" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Hız:" @@ -13308,7 +13315,6 @@ msgid "Select SSH private key path" msgstr "SSH özel anahtar yolu seç" #: editor/plugins/version_control_editor_plugin.cpp -#, fuzzy msgid "SSH Passphrase" msgstr "SSH Parolası" @@ -16017,7 +16023,7 @@ msgstr "Düğüm BetiÄŸi İliÅŸtir" #: editor/script_editor_debugger.cpp #, fuzzy msgid "Remote %s:" -msgstr "Uzak " +msgstr "Uzak %s:" #: editor/script_editor_debugger.cpp msgid "Bytes:" @@ -17077,9 +17083,8 @@ msgid "Disabled GDNative Singleton" msgstr "GDNative İskeleti PasifleÅŸtirildi" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Libraries:" -msgstr "Kütüphaneler: " +msgstr "Kütüphaneler:" #: modules/gdnative/nativescript/nativescript.cpp #, fuzzy @@ -17983,7 +17988,7 @@ msgstr "" #: modules/visual_script/visual_script.cpp #, fuzzy msgid "Node returned an invalid sequence output:" -msgstr "Düğüm geçersiz bir dizi çıktısı döndürdü: " +msgstr "Düğüm geçersiz bir dizi çıktısı döndürdü:" #: modules/visual_script/visual_script.cpp msgid "Found sequence bit but not the node in the stack, report bug!" @@ -18345,8 +18350,9 @@ msgid "if (cond) is:" msgstr "" #: modules/visual_script/visual_script_flow_control.cpp +#, fuzzy msgid "While" -msgstr "While" +msgstr "Sürece" #: modules/visual_script/visual_script_flow_control.cpp msgid "while (cond):" @@ -22071,7 +22077,7 @@ msgstr "Kenar BoÅŸluk Belirle" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy msgid "Sync To Physics" -msgstr " (Fiziksel)" +msgstr "FiziÄŸe Senkronize Et" #: scene/2d/physics_body_2d.cpp scene/3d/physics_body.cpp #, fuzzy @@ -23575,7 +23581,7 @@ msgstr "Bir RoomGroup, bir Portal'ın çocuÄŸu veya torunu olmamalıdır." #: scene/3d/portal.cpp #, fuzzy msgid "Portal Active" -msgstr " [portallar aktif]" +msgstr "Portal Aktif" #: scene/3d/portal.cpp scene/resources/occluder_shape_polygon.cpp msgid "Two Way" @@ -24866,7 +24872,7 @@ msgstr "" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Caret" -msgstr "" +msgstr "Karet" #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Blink" @@ -25788,14 +25794,12 @@ msgid "3D Render" msgstr "OluÅŸturucu:" #: scene/register_scene_types.cpp -#, fuzzy msgid "2D Physics" -msgstr " (Fiziksel)" +msgstr "2B Fizik" #: scene/register_scene_types.cpp -#, fuzzy msgid "3D Physics" -msgstr " (Fiziksel)" +msgstr "3B Fizik" #: scene/register_scene_types.cpp #, fuzzy diff --git a/editor/translations/uk.po b/editor/translations/uk.po index fd20ea0a29..0feae1a849 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -29,7 +29,7 @@ msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-03 00:44+0000\n" +"PO-Revision-Date: 2022-07-26 01:55+0000\n" "Last-Translator: Artem <artem@molotov.work>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -39,7 +39,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -2116,14 +2116,15 @@ msgstr "Вибране:" msgid "Recent:" msgstr "Ðещодавні:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Пошук:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Збіги:" @@ -2183,8 +2184,8 @@ msgstr "Знайти замінний реÑурÑ:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5500,6 +5501,10 @@ msgid "Drag And Drop Selection" msgstr "Вибір GridMap" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "ВиглÑд" @@ -11612,6 +11617,11 @@ msgid "New Animation" msgstr "Ðова анімаціÑ" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Фільтрувати методи" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "ШвидкіÑть:" @@ -25888,11 +25898,11 @@ msgstr "Розмір крапки" #: scene/resources/material.cpp msgid "Billboard Mode" -msgstr "Режим афіші" +msgstr "Режим розголоÑника" #: scene/resources/material.cpp msgid "Billboard Keep Scale" -msgstr "Зберегти маÑштаб афіші" +msgstr "Зберегти маÑштаб розголоÑника" #: scene/resources/material.cpp msgid "Grow" diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index 46cd56a57b..9cb56f3c21 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -2132,14 +2132,15 @@ msgstr "" msgid "Recent:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "" @@ -2195,8 +2196,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5421,6 +5422,10 @@ msgid "Drag And Drop Selection" msgstr ".تمام کا انتخاب" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -11599,6 +11604,11 @@ msgid "New Animation" msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "سب سکریپشن بنائیں" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 32fe3c1087..4a6164f7e1 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -2149,14 +2149,15 @@ msgstr "Ưa thÃch:" msgid "Recent:" msgstr "Gần đây:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "Tìm kiếm:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "Phù hợp:" @@ -2216,8 +2217,8 @@ msgstr "Tìm kiếm tà i nguyên thay thế:" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5506,6 +5507,10 @@ msgid "Drag And Drop Selection" msgstr "Chá»n tất cả" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "Ngoại hình" @@ -11788,6 +11793,11 @@ msgid "New Animation" msgstr "Hoạt hình má»›i" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "Lá»c phương thức" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "Tốc độ:" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index a2183dd550..bd012a4c76 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -89,7 +89,7 @@ msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2022-07-09 21:12+0000\n" +"PO-Revision-Date: 2022-07-19 16:26+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" @@ -98,7 +98,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.13.1-dev\n" +"X-Generator: Weblate 4.14-dev\n" #: core/bind/core_bind.cpp main/main.cpp msgid "Tablet Driver" @@ -521,9 +521,8 @@ msgid "Pressure" msgstr "压力" #: core/os/input_event.cpp -#, fuzzy msgid "Pen Inverted" -msgstr "翻转" +msgstr "笔触翻转" #: core/os/input_event.cpp msgid "Relative" @@ -2157,14 +2156,15 @@ msgstr "æ”¶è—:" msgid "Recent:" msgstr "最近使用:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "æœç´¢ï¼š" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "匹é…项:" @@ -2224,8 +2224,8 @@ msgstr "查找替æ¢èµ„æºï¼š" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5444,6 +5444,10 @@ msgid "Drag And Drop Selection" msgstr "拖放选ä¸å†…容" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "外观" @@ -10700,7 +10704,7 @@ msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"æ¤ç€è‰²å™¨å·²åœ¨ç£ç›˜ä¸Šä¿®æ”¹ã€‚\n" +"这个ç€è‰²å™¨å·²åœ¨ç£ç›˜ä¸Šä¿®æ”¹ã€‚\n" "应该采å–什么行动?" #: editor/plugins/shader_editor_plugin.cpp scene/resources/material.cpp @@ -11466,6 +11470,11 @@ msgid "New Animation" msgstr "新建动画" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ç›é€‰æ–¹æ³•" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "速度:" @@ -22562,9 +22571,8 @@ msgstr "" "建议修改å节点的碰撞体形状尺寸。" #: scene/3d/spatial.cpp -#, fuzzy msgid "Global Translation" -msgstr "å…¨å±€å˜æ¢" +msgstr "全局平移" #: scene/3d/spatial.cpp msgid "Matrix" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index dcd0403c6a..424752a849 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -2228,14 +2228,15 @@ msgstr "最愛:" msgid "Recent:" msgstr "最近:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "æœå°‹ï¼š" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "å»åˆï¼š" @@ -2291,8 +2292,8 @@ msgstr "" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5677,6 +5678,10 @@ msgid "Drag And Drop Selection" msgstr "刪除é¸ä¸æª”案" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "" @@ -12116,6 +12121,11 @@ msgid "New Animation" msgstr "新的動畫å稱:" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "篩é¸:" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index d56bc9ec23..f5568c41b5 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -41,7 +41,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-07-18 08:11+0000\n" +"PO-Revision-Date: 2022-07-23 03:57+0000\n" "Last-Translator: è˜è˜ <rrt467778@gmail.com>\n" "Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hant/>\n" @@ -2112,14 +2112,15 @@ msgstr "我的最愛:" msgid "Recent:" msgstr "最近å˜å–:" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp editor/rename_dialog.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp +#: editor/rename_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Search:" msgstr "æœå°‹ï¼š" -#: editor/create_dialog.cpp editor/plugins/script_editor_plugin.cpp -#: editor/property_selector.cpp editor/quick_open.cpp +#: editor/create_dialog.cpp editor/editor_quick_open.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: modules/visual_script/visual_script_property_selector.cpp msgid "Matches:" msgstr "ç¬¦åˆæ¢ä»¶ï¼š" @@ -2179,8 +2180,8 @@ msgstr "æœå°‹ä¸¦å–代資æºï¼š" #: 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/editor_quick_open.cpp editor/filesystem_dock.cpp +#: editor/plugins/script_editor_plugin.cpp editor/property_selector.cpp #: editor/script_create_dialog.cpp #: modules/visual_script/visual_script_property_selector.cpp #: scene/gui/file_dialog.cpp @@ -5402,6 +5403,10 @@ msgid "Drag And Drop Selection" msgstr "æ‹–ç§»é¸æ“‡çš„æª”案" #: editor/editor_settings.cpp +msgid "Stay In Script Editor On Node Selected" +msgstr "" + +#: editor/editor_settings.cpp msgid "Appearance" msgstr "外觀" @@ -11438,6 +11443,11 @@ msgid "New Animation" msgstr "新增動畫" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy +msgid "Filter animations" +msgstr "ç¯©é¸æ–¹æ³•" + +#: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed:" msgstr "速度:" @@ -23144,9 +23154,8 @@ msgstr "" "請改為修改其å節點的碰撞形狀之大å°ã€‚" #: scene/3d/spatial.cpp -#, fuzzy msgid "Global Translation" -msgstr "ä¿æŒå…¨åŸŸè®Šæ›" +msgstr "全域變æ›" #: scene/3d/spatial.cpp msgid "Matrix" diff --git a/gles3_builders.py b/gles3_builders.py index 6b2d315603..a9fabd93ce 100644 --- a/gles3_builders.py +++ b/gles3_builders.py @@ -436,7 +436,7 @@ def build_gles3_header(filename, include, class_suffix, output_attribs): ) fd.write( - """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix,RID p_version,ShaderVariant p_variant""" + """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Projection& p_matrix,RID p_version,ShaderVariant p_variant""" + defvariant + """,uint64_t p_specialization=""" + str(defspec) diff --git a/main/main.cpp b/main/main.cpp index 2bb67f17f1..a9037806bf 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -148,7 +148,7 @@ static bool cmdline_tool = false; static String locale; static bool show_help = false; static bool auto_quit = false; -static OS::ProcessID allow_focus_steal_pid = 0; +static OS::ProcessID editor_pid = 0; #ifdef TOOLS_ENABLED static bool auto_build_solutions = false; static String debug_server_uri; @@ -181,7 +181,6 @@ static bool debug_navigation = false; static int frame_delay = 0; static bool disable_render_loop = false; static int fixed_fps = -1; -static String write_movie_path; static MovieWriter *movie_writer = nullptr; static bool disable_vsync = false; static bool print_fps = false; @@ -344,6 +343,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n"); OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n"); OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n"); + OS::get_singleton()->print(" --xr-mode <mode> Select XR mode (default/off/on).\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Debug options:\n"); @@ -410,6 +410,8 @@ Error Main::test_setup() { String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues")); GLOBAL_DEF_RST("rendering/occlusion_culling/bvh_build_quality", 2); + register_core_settings(); //here globals are present + translation_server = memnew(TranslationServer); tsman = memnew(TextServerManager); @@ -685,7 +687,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph I = args.front(); while (I) { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED // Ignore the process serial number argument passed by macOS Gatekeeper. // Otherwise, Godot would try to open a non-existent project on the first start and abort. if (I->get().begins_with("-psn_")) { @@ -1044,10 +1046,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph if (I->next()) { String p = I->next()->get(); - if (OS::get_singleton()->set_cwd(p) == OK) { - //nothing - } else { - project_path = I->next()->get(); //use project_path instead + if (OS::get_singleton()->set_cwd(p) != OK) { + OS::get_singleton()->print("Invalid project path specified: \"%s\", aborting.\n", p.utf8().get_data()); + goto error; } N = I->next()->next(); } else { @@ -1141,9 +1142,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing remote debug host address, aborting.\n"); goto error; } - } else if (I->get() == "--allow_focus_steal_pid") { // not exposed to user + } else if (I->get() == "--editor-pid") { // not exposed to user if (I->next()) { - allow_focus_steal_pid = I->next()->get().to_int(); + editor_pid = I->next()->get().to_int(); N = I->next()->next(); } else { OS::get_singleton()->print("Missing editor PID argument, aborting.\n"); @@ -1161,7 +1162,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } else if (I->get() == "--write-movie") { if (I->next()) { - write_movie_path = I->next()->get(); + Engine::get_singleton()->set_write_movie_path(I->next()->get()); N = I->next()->next(); if (fixed_fps == -1) { fixed_fps = 60; @@ -1181,6 +1182,25 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->disable_crash_handler(); } else if (I->get() == "--skip-breakpoints") { skip_breakpoints = true; + } else if (I->get() == "--xr-mode") { + if (I->next()) { + String xr_mode = I->next()->get().to_lower(); + N = I->next()->next(); + if (xr_mode == "default") { + XRServer::set_xr_mode(XRServer::XRMODE_DEFAULT); + } else if (xr_mode == "off") { + XRServer::set_xr_mode(XRServer::XRMODE_OFF); + } else if (xr_mode == "on") { + XRServer::set_xr_mode(XRServer::XRMODE_ON); + } else { + OS::get_singleton()->print("Unknown --xr-mode argument \"%s\", aborting.\n", xr_mode.ascii().get_data()); + goto error; + } + } else { + OS::get_singleton()->print("Missing --xr-mode argument, aborting.\n"); + goto error; + } + } else { main_args.push_back(I->get()); } @@ -1273,7 +1293,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph PROPERTY_HINT_RANGE, "0, 200, 1, or_greater")); - EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints); + EngineDebugger::initialize(debug_uri, skip_breakpoints, breakpoints, []() { + if (editor_pid) { + DisplayServer::get_singleton()->enable_for_stealing_focus(editor_pid); + } + }); #ifdef TOOLS_ENABLED if (editor) { @@ -1431,7 +1455,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } - GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false); + GLOBAL_DEF_RST("internationalization/rendering/force_right_to_left_layout_direction", false); GLOBAL_DEF("internationalization/locale/include_text_server_data", false); OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", true); @@ -1507,7 +1531,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph audio_driver_idx = 0; } - if (write_movie_path != String()) { + if (Engine::get_singleton()->get_write_movie_path() != String()) { // Always use dummy driver for audio driver (which is last), also in no threaded mode. audio_driver_idx = AudioDriverManager::get_driver_count() - 1; AudioDriverDummy::get_dummy_singleton()->set_use_threads(false); @@ -1604,7 +1628,7 @@ error: display_driver = ""; audio_driver = ""; tablet_driver = ""; - write_movie_path = ""; + Engine::get_singleton()->set_write_movie_path(String()); project_path = ""; args.clear(); @@ -1779,11 +1803,11 @@ Error Main::setup2(Thread::ID p_main_tid_override) { rendering_server->set_print_gpu_profile(true); } - if (write_movie_path != String()) { - movie_writer = MovieWriter::find_writer_for_file(write_movie_path); + if (Engine::get_singleton()->get_write_movie_path() != String()) { + movie_writer = MovieWriter::find_writer_for_file(Engine::get_singleton()->get_write_movie_path()); if (movie_writer == nullptr) { - ERR_PRINT("Can't find movie writer for file type, aborting: " + write_movie_path); - write_movie_path = String(); + ERR_PRINT("Can't find movie writer for file type, aborting: " + Engine::get_singleton()->get_write_movie_path()); + Engine::get_singleton()->set_write_movie_path(String()); } } @@ -1838,10 +1862,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) { DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP, true); } - if (allow_focus_steal_pid) { - DisplayServer::get_singleton()->enable_for_stealing_focus(allow_focus_steal_pid); - } - MAIN_PRINT("Main: Load Boot Image"); Color clear = GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3)); @@ -1965,7 +1985,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { MAIN_PRINT("Main: Load TextServer"); /* Enum text drivers */ - GLOBAL_DEF("internationalization/rendering/text_driver", ""); + GLOBAL_DEF_RST("internationalization/rendering/text_driver", ""); String text_driver_options; for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { if (i > 0) { @@ -2078,7 +2098,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // able to load resources, load the global shader variables. // If running on editor, don't load the textures because the editor // may want to import them first. Editor will reload those later. - rendering_server->global_variables_load_settings(!editor); + rendering_server->global_shader_uniforms_load_settings(!editor); } _start_success = true; @@ -2575,7 +2595,7 @@ bool Main::start() { PropertyInfo(Variant::FLOAT, "display/window/stretch/scale", PROPERTY_HINT_RANGE, - "1.0,8.0,0.1")); + "0.5,8.0,0.01")); sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true)); sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true)); GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true); @@ -2669,7 +2689,7 @@ bool Main::start() { ERR_FAIL_COND_V_MSG(!scene, false, "Failed loading scene: " + local_game_path); sml->add_current_scene(scene); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED String mac_iconpath = GLOBAL_DEF("application/config/macos_native_icon", "Variant()"); if (!mac_iconpath.is_empty()) { DisplayServer::get_singleton()->set_native_icon(mac_iconpath); @@ -2723,7 +2743,7 @@ bool Main::start() { OS::get_singleton()->set_main_loop(main_loop); if (movie_writer) { - movie_writer->begin(DisplayServer::get_singleton()->window_get_size(), fixed_fps, write_movie_path); + movie_writer->begin(DisplayServer::get_singleton()->window_get_size(), fixed_fps, Engine::get_singleton()->get_write_movie_path()); } if (minimum_time_msec) { @@ -2991,7 +3011,7 @@ void Main::cleanup(bool p_force) { RenderingServer::get_singleton()->sync(); //clear global shader variables before scene and other graphics stuff are deinitialized. - rendering_server->global_variables_clear(); + rendering_server->global_shader_uniforms_clear(); if (xr_server) { // Now that we're unregistering properly in plugins we need to keep access to xr_server for a little longer diff --git a/methods.py b/methods.py index b4a55cab79..571b134c8a 100644 --- a/methods.py +++ b/methods.py @@ -125,9 +125,21 @@ def update_version(module_version_string=""): if os.path.isfile(os.path.join(gitfolder, "HEAD")): head = open(os.path.join(gitfolder, "HEAD"), "r", encoding="utf8").readline().strip() if head.startswith("ref: "): - head = os.path.join(gitfolder, head[5:]) + ref = head[5:] + head = os.path.join(gitfolder, ref) + packedrefs = os.path.join(gitfolder, "packed-refs") if os.path.isfile(head): githash = open(head, "r").readline().strip() + elif os.path.isfile(packedrefs): + # Git may pack refs into a single file. This code searches .git/packed-refs file for the current ref's hash. + # https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-pack-refs.html + for line in open(packedrefs, "r").read().splitlines(): + if line.startswith("#"): + continue + (line_hash, line_ref) = line.split(" ") + if ref == line_ref: + githash = line_hash + break else: githash = head @@ -833,15 +845,15 @@ def Run(env, function, short_message, subprocess=True): def detect_darwin_sdk_path(platform, env): sdk_name = "" - if platform == "osx": + if platform == "macos": sdk_name = "macosx" var_name = "MACOS_SDK_PATH" - elif platform == "iphone": + elif platform == "ios": sdk_name = "iphoneos" - var_name = "IPHONESDK" - elif platform == "iphonesimulator": + var_name = "IOS_SDK_PATH" + elif platform == "iossimulator": sdk_name = "iphonesimulator" - var_name = "IPHONESDK" + var_name = "IOS_SDK_PATH" else: raise Exception("Invalid platform argument passed to detect_darwin_sdk_path") diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/Info.plist index 846533594f..846533594f 100644 --- a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/Info.plist +++ b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/Info.plist diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/empty index bd3e894333..bd3e894333 100644 --- a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64/empty +++ b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/empty diff --git a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/empty index bd3e894333..bd3e894333 100644 --- a/misc/dist/ios_xcode/libgodot.iphone.debug.xcframework/ios-arm64_x86_64-simulator/empty +++ b/misc/dist/ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/empty diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/Info.plist index 846533594f..846533594f 100644 --- a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/Info.plist +++ b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/Info.plist diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64/empty index bd3e894333..bd3e894333 100644 --- a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64/empty +++ b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64/empty diff --git a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/empty index bd3e894333..bd3e894333 100644 --- a/misc/dist/ios_xcode/libgodot.iphone.release.xcframework/ios-arm64_x86_64-simulator/empty +++ b/misc/dist/ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/empty diff --git a/misc/dist/osx/editor.entitlements b/misc/dist/macos/editor.entitlements index d0137910a3..d0137910a3 100644 --- a/misc/dist/osx/editor.entitlements +++ b/misc/dist/macos/editor.entitlements diff --git a/misc/dist/osx_template.app/Contents/Info.plist b/misc/dist/macos_template.app/Contents/Info.plist index 542146cdb8..542146cdb8 100644 --- a/misc/dist/osx_template.app/Contents/Info.plist +++ b/misc/dist/macos_template.app/Contents/Info.plist diff --git a/misc/dist/osx_template.app/Contents/PkgInfo b/misc/dist/macos_template.app/Contents/PkgInfo index 6f749b0f37..6f749b0f37 100644 --- a/misc/dist/osx_template.app/Contents/PkgInfo +++ b/misc/dist/macos_template.app/Contents/PkgInfo diff --git a/misc/dist/osx_template.app/Contents/Resources/icon.icns b/misc/dist/macos_template.app/Contents/Resources/icon.icns Binary files differindex be9254630c..be9254630c 100644 --- a/misc/dist/osx_template.app/Contents/Resources/icon.icns +++ b/misc/dist/macos_template.app/Contents/Resources/icon.icns diff --git a/misc/dist/osx_tools.app/Contents/Info.plist b/misc/dist/macos_tools.app/Contents/Info.plist index 886df87cc6..886df87cc6 100644 --- a/misc/dist/osx_tools.app/Contents/Info.plist +++ b/misc/dist/macos_tools.app/Contents/Info.plist diff --git a/misc/dist/osx_tools.app/Contents/PkgInfo b/misc/dist/macos_tools.app/Contents/PkgInfo index 6f749b0f37..6f749b0f37 100644 --- a/misc/dist/osx_tools.app/Contents/PkgInfo +++ b/misc/dist/macos_tools.app/Contents/PkgInfo diff --git a/misc/dist/osx_tools.app/Contents/Resources/GDScript.icns b/misc/dist/macos_tools.app/Contents/Resources/GDScript.icns Binary files differindex b08e8df339..b08e8df339 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/GDScript.icns +++ b/misc/dist/macos_tools.app/Contents/Resources/GDScript.icns diff --git a/misc/dist/osx_tools.app/Contents/Resources/Godot.icns b/misc/dist/macos_tools.app/Contents/Resources/Godot.icns Binary files differindex 61697976c6..61697976c6 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/Godot.icns +++ b/misc/dist/macos_tools.app/Contents/Resources/Godot.icns diff --git a/misc/dist/osx_tools.app/Contents/Resources/Project.icns b/misc/dist/macos_tools.app/Contents/Resources/Project.icns Binary files differindex 10e31528e4..10e31528e4 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/Project.icns +++ b/misc/dist/macos_tools.app/Contents/Resources/Project.icns diff --git a/misc/dist/osx_tools.app/Contents/Resources/Resource.icns b/misc/dist/macos_tools.app/Contents/Resources/Resource.icns Binary files differindex 9648cb616e..9648cb616e 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/Resource.icns +++ b/misc/dist/macos_tools.app/Contents/Resources/Resource.icns diff --git a/misc/dist/osx_tools.app/Contents/Resources/Scene.icns b/misc/dist/macos_tools.app/Contents/Resources/Scene.icns Binary files differindex c8c3dee07e..c8c3dee07e 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/Scene.icns +++ b/misc/dist/macos_tools.app/Contents/Resources/Scene.icns diff --git a/misc/dist/osx_tools.app/Contents/Resources/Shader.icns b/misc/dist/macos_tools.app/Contents/Resources/Shader.icns Binary files differindex a76e648a1a..a76e648a1a 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/Shader.icns +++ b/misc/dist/macos_tools.app/Contents/Resources/Shader.icns diff --git a/misc/dist/osx_tools.app/Contents/Resources/af.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/af.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/af.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/af.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ar.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/az.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/az.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/az.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/az.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/bg.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/bn.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/br.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/br.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/br.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/br.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ca.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/cs.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/da.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/da.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/da.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/da.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/de.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/de.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/de.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/de.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/el.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/el.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/el.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/el.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/en.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/en.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/en.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/en.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/eo.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/es.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/es.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/es.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/es.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/es_AR.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/et.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/et.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/et.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/et.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/eu.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/fa.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/fi.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/fil.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/fr.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ga.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/gl.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/he.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/he.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/he.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/he.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/hi.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/hr.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/hu.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/id.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/id.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/id.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/id.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/is.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/is.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/is.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/is.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/it.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/it.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/it.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/it.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ja.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ka.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/km.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/km.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/km.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/km.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ko.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/lt.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/lv.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/mi.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/mk.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ml.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/mr.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ms.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/nb.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/nl.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/or.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/or.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/or.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/or.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/pl.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/pt.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/pt_BR.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ro.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ru.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/si.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/si.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/si.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/si.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/sk.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/sl.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/sq.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/sr-Cyrl.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/sr-Latn.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/sv.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ta.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/te.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/te.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/te.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/te.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/th.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/th.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/th.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/th.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/tr.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/tt.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/tzm.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/uk.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/ur_PK.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/vi.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/zh_CN.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/zh_HK.lproj/InfoPlist.strings diff --git a/misc/dist/osx_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings b/misc/dist/macos_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings index e69de29bb2..e69de29bb2 100644 --- a/misc/dist/osx_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings +++ b/misc/dist/macos_tools.app/Contents/Resources/zh_TW.lproj/InfoPlist.strings diff --git a/misc/dist/osx_template.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json b/misc/dist/osx_template.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json deleted file mode 100644 index c4f8f71d0e..0000000000 --- a/misc/dist/osx_template.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "file_format_version" : "1.0.0", - "ICD": { - "library_path": "../../../Frameworks/libMoltenVK.dylib", - "api_version" : "1.1.0" - } -} diff --git a/misc/dist/osx_tools.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json b/misc/dist/osx_tools.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json deleted file mode 100644 index c4f8f71d0e..0000000000 --- a/misc/dist/osx_tools.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "file_format_version" : "1.0.0", - "ICD": { - "library_path": "../../../Frameworks/libMoltenVK.dylib", - "api_version" : "1.1.0" - } -} diff --git a/misc/scripts/header_guards.sh b/misc/scripts/header_guards.sh new file mode 100755 index 0000000000..9a830f3ad2 --- /dev/null +++ b/misc/scripts/header_guards.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +if [ ! -f "version.py" ]; then + echo "Warning: This script is intended to be run from the root of the Godot repository." + echo "Some of the paths checks may not work as intended from a different folder." +fi + +for file in $(find -name "thirdparty" -prune -o -name "*.h" -print); do + # Skip *.gen.h and *-so_wrap.h, they're generated. + if [[ "$file" == *".gen.h" || "$file" == *"-so_wrap.h" ]]; then continue; fi + # Has important define before normal header guards. + if [[ "$file" == *"thread.h" || "$file" == *"platform_config.h" ]]; then continue; fi + + bname=$(basename $file .h) + + # Add custom prefix or suffix for generic filenames with a well-defined namespace. + + prefix= + if [[ "$file" == "./modules/"*"/register_types.h" ]]; then + module=$(echo $file | sed "s@.*modules/\([^/]*\).*@\1@") + prefix="${module^^}_" + fi + if [[ "$file" == "./platform/"*"/api/api.h" || "$file" == "./platform/"*"/export/"* ]]; then + platform=$(echo $file | sed "s@.*platform/\([^/]*\).*@\1@") + prefix="${platform^^}_" + fi + if [[ "$file" == "./modules/mono/utils/"* && "$bname" != *"mono"* ]]; then prefix="MONO_"; fi + if [[ "$file" == "./servers/rendering/storage/utilities.h" ]]; then prefix="RENDERER_"; fi + + suffix= + if [[ "$file" == *"dummy"* && "$bname" != *"dummy"* ]]; then suffix="_DUMMY"; fi + if [[ "$file" == *"gles3"* && "$bname" != *"gles3"* ]]; then suffix="_GLES3"; fi + if [[ "$file" == *"renderer_rd"* && "$bname" != *"rd"* ]]; then suffix="_RD"; fi + if [[ "$file" == *"ustring.h" ]]; then suffix="_GODOT"; fi + + # ^^ is bash builtin for UPPERCASE. + guard="${prefix}${bname^^}${suffix}_H" + + # Replaces guards to use computed name. + # We also add some \n to make sure there's a proper separation. + sed -i $file -e "0,/ifndef/s/#ifndef.*/\n#ifndef $guard/" + sed -i $file -e "0,/define/s/#define.*/#define $guard\n/" + sed -i $file -e "$ s/#endif.*/\n#endif \/\/ $guard/" + # Removes redundant \n added before, if they weren't needed. + sed -i $file -e "/^$/N;/^\n$/D" +done + +diff=$(git diff --color) + +# If no diff has been generated all is OK, clean up, and exit. +if [ -z "$diff" ] ; then + printf "Files in this commit comply with the header guards formatting rules.\n" + exit 0 +fi + +# A diff has been created, notify the user, clean up, and exit. +printf "\n*** The following differences were found between the code " +printf "and the header guards formatting rules:\n\n" +echo "$diff" +printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n" +exit 1 diff --git a/modules/camera/SCsub b/modules/camera/SCsub index de97724d09..9a6147d433 100644 --- a/modules/camera/SCsub +++ b/modules/camera/SCsub @@ -9,6 +9,6 @@ if env["platform"] == "windows": env_camera.add_source_files(env.modules_sources, "register_types.cpp") env_camera.add_source_files(env.modules_sources, "camera_win.cpp") -elif env["platform"] == "osx": +elif env["platform"] == "macos": env_camera.add_source_files(env.modules_sources, "register_types.cpp") - env_camera.add_source_files(env.modules_sources, "camera_osx.mm") + env_camera.add_source_files(env.modules_sources, "camera_macos.mm") diff --git a/modules/camera/camera_osx.h b/modules/camera/camera_macos.h index b0db844599..903eda51bf 100644 --- a/modules/camera/camera_osx.h +++ b/modules/camera/camera_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* camera_osx.h */ +/* camera_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,19 +28,19 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERAOSX_H -#define CAMERAOSX_H +#ifndef CAMERA_MACOS_H +#define CAMERA_MACOS_H ///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimize code duplication!!!! // If you fix something here, make sure you fix it there as well! #include "servers/camera_server.h" -class CameraOSX : public CameraServer { +class CameraMacOS : public CameraServer { public: - CameraOSX(); + CameraMacOS(); void update_feeds(); }; -#endif /* CAMERAOSX_H */ +#endif // CAMERA_MACOS_H diff --git a/modules/camera/camera_osx.mm b/modules/camera/camera_macos.mm index d199c31b2f..0b9696a3e9 100644 --- a/modules/camera/camera_osx.mm +++ b/modules/camera/camera_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* camera_osx.mm */ +/* camera_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -31,7 +31,7 @@ ///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimize code duplication!!!! // If you fix something here, make sure you fix it there as well! -#include "camera_osx.h" +#include "camera_macos.h" #include "servers/camera/camera_feed.h" #import <AVFoundation/AVFoundation.h> @@ -191,9 +191,9 @@ @end ////////////////////////////////////////////////////////////////////////// -// CameraFeedOSX - Subclass for camera feeds in OSX +// CameraFeedMacOS - Subclass for camera feeds in macOS -class CameraFeedOSX : public CameraFeed { +class CameraFeedMacOS : public CameraFeed { private: AVCaptureDevice *device; MyCaptureSession *capture_session; @@ -201,7 +201,7 @@ private: public: AVCaptureDevice *get_device() const; - CameraFeedOSX(); + CameraFeedMacOS(); void set_device(AVCaptureDevice *p_device); @@ -209,16 +209,16 @@ public: void deactivate_feed(); }; -AVCaptureDevice *CameraFeedOSX::get_device() const { +AVCaptureDevice *CameraFeedMacOS::get_device() const { return device; }; -CameraFeedOSX::CameraFeedOSX() { +CameraFeedMacOS::CameraFeedMacOS() { device = nullptr; capture_session = nullptr; }; -void CameraFeedOSX::set_device(AVCaptureDevice *p_device) { +void CameraFeedMacOS::set_device(AVCaptureDevice *p_device) { device = p_device; // get some info @@ -232,7 +232,7 @@ void CameraFeedOSX::set_device(AVCaptureDevice *p_device) { }; }; -bool CameraFeedOSX::activate_feed() { +bool CameraFeedMacOS::activate_feed() { if (capture_session) { // Already recording! } else { @@ -258,7 +258,7 @@ bool CameraFeedOSX::activate_feed() { return true; }; -void CameraFeedOSX::deactivate_feed() { +void CameraFeedMacOS::deactivate_feed() { // end camera capture if we have one if (capture_session) { [capture_session cleanup]; @@ -271,7 +271,7 @@ void CameraFeedOSX::deactivate_feed() { // when devices are connected/disconnected @interface MyDeviceNotifications : NSObject { - CameraOSX *camera_server; + CameraMacOS *camera_server; } @end @@ -282,7 +282,7 @@ void CameraFeedOSX::deactivate_feed() { camera_server->update_feeds(); } -- (id)initForServer:(CameraOSX *)p_server { +- (id)initForServer:(CameraMacOS *)p_server { if (self = [super init]) { camera_server = p_server; @@ -303,9 +303,9 @@ void CameraFeedOSX::deactivate_feed() { MyDeviceNotifications *device_notifications = nil; ////////////////////////////////////////////////////////////////////////// -// CameraOSX - Subclass for our camera server on OSX +// CameraMacOS - Subclass for our camera server on macOS -void CameraOSX::update_feeds() { +void CameraMacOS::update_feeds() { #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101500 AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeExternalUnknown, AVCaptureDeviceTypeBuiltInWideAngleCamera, nil] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified]; NSArray *devices = session.devices; @@ -315,7 +315,7 @@ void CameraOSX::update_feeds() { // remove devices that are gone.. for (int i = feeds.size() - 1; i >= 0; i--) { - Ref<CameraFeedOSX> feed = (Ref<CameraFeedOSX>)feeds[i]; + Ref<CameraFeedMacOS> feed = (Ref<CameraFeedMacOS>)feeds[i]; if (![devices containsObject:feed->get_device()]) { // remove it from our array, this will also destroy it ;) @@ -326,14 +326,14 @@ void CameraOSX::update_feeds() { for (AVCaptureDevice *device in devices) { bool found = false; for (int i = 0; i < feeds.size() && !found; i++) { - Ref<CameraFeedOSX> feed = (Ref<CameraFeedOSX>)feeds[i]; + Ref<CameraFeedMacOS> feed = (Ref<CameraFeedMacOS>)feeds[i]; if (feed->get_device() == device) { found = true; }; }; if (!found) { - Ref<CameraFeedOSX> newfeed; + Ref<CameraFeedMacOS> newfeed; newfeed.instantiate(); newfeed->set_device(device); @@ -346,7 +346,7 @@ void CameraOSX::update_feeds() { }; }; -CameraOSX::CameraOSX() { +CameraMacOS::CameraMacOS() { // Find available cameras we have at this time update_feeds(); diff --git a/modules/camera/camera_win.h b/modules/camera/camera_win.h index 9563326acb..ebfc117190 100644 --- a/modules/camera/camera_win.h +++ b/modules/camera/camera_win.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERAWIN_H -#define CAMERAWIN_H +#ifndef CAMERA_WIN_H +#define CAMERA_WIN_H #include "servers/camera/camera_feed.h" #include "servers/camera_server.h" @@ -43,4 +43,4 @@ public: ~CameraWindows() {} }; -#endif /* CAMERAWIN_H */ +#endif // CAMERA_WIN_H diff --git a/modules/camera/config.py b/modules/camera/config.py index 8a22751aa7..d2b2542dd9 100644 --- a/modules/camera/config.py +++ b/modules/camera/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return platform == "osx" or platform == "windows" + return platform == "macos" or platform == "windows" def configure(env): diff --git a/modules/camera/register_types.cpp b/modules/camera/register_types.cpp index 98a4b5ca1a..40e2224d6b 100644 --- a/modules/camera/register_types.cpp +++ b/modules/camera/register_types.cpp @@ -33,8 +33,8 @@ #if defined(WINDOWS_ENABLED) #include "camera_win.h" #endif -#if defined(OSX_ENABLED) -#include "camera_osx.h" +#if defined(MACOS_ENABLED) +#include "camera_macos.h" #endif void initialize_camera_module(ModuleInitializationLevel p_level) { @@ -45,8 +45,8 @@ void initialize_camera_module(ModuleInitializationLevel p_level) { #if defined(WINDOWS_ENABLED) CameraServer::make_default<CameraWindows>(); #endif -#if defined(OSX_ENABLED) - CameraServer::make_default<CameraOSX>(); +#if defined(MACOS_ENABLED) + CameraServer::make_default<CameraMacOS>(); #endif } diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 0f09eb2020..56be4e65f0 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -1858,7 +1858,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { } Transform3D facing = Transform3D().looking_at(direction, current_up); - current_xform = base_xform.translated(current_point) * facing; + current_xform = base_xform.translated_local(current_point) * facing; } // Create the mesh. @@ -1897,7 +1897,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { switch (mode) { case MODE_DEPTH: { - current_xform.translate(Vector3(0, 0, -depth)); + current_xform.translate_local(Vector3(0, 0, -depth)); } break; case MODE_SPIN: { current_xform.rotate(Vector3(0, 1, 0), spin_step); @@ -1945,7 +1945,7 @@ CSGBrush *CSGPolygon3D::_build_brush() { } Transform3D facing = Transform3D().looking_at(direction, current_up); - current_xform = base_xform.translated(current_point) * facing; + current_xform = base_xform.translated_local(current_point) * facing; } break; } diff --git a/modules/denoise/config.py b/modules/denoise/config.py index 3aa840acb0..521115dae5 100644 --- a/modules/denoise/config.py +++ b/modules/denoise/config.py @@ -4,7 +4,7 @@ def can_build(env, platform): # It's also only relevant for tools build and desktop platforms, # as doing lightmap generation and denoising on Android or HTML5 # would be a bit far-fetched. - desktop_platforms = ["linuxbsd", "osx", "windows"] + desktop_platforms = ["linuxbsd", "macos", "windows"] supported_arch = env["bits"] == "64" if env["arch"] == "arm64": supported_arch = False diff --git a/modules/enet/enet_multiplayer_peer.cpp b/modules/enet/enet_multiplayer_peer.cpp index cd94cc9425..dfdd08c9f4 100644 --- a/modules/enet/enet_multiplayer_peer.cpp +++ b/modules/enet/enet_multiplayer_peer.cpp @@ -441,15 +441,15 @@ Error ENetMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size channel = SYSCH_MAX + transfer_channel - 1; } else { switch (get_transfer_mode()) { - case Multiplayer::TRANSFER_MODE_UNRELIABLE: { + case TRANSFER_MODE_UNRELIABLE: { packet_flags = ENET_PACKET_FLAG_UNSEQUENCED | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT; channel = SYSCH_UNRELIABLE; } break; - case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: { + case TRANSFER_MODE_UNRELIABLE_ORDERED: { packet_flags = ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT; channel = SYSCH_UNRELIABLE; } break; - case Multiplayer::TRANSFER_MODE_RELIABLE: { + case TRANSFER_MODE_RELIABLE: { packet_flags = ENET_PACKET_FLAG_RELIABLE; channel = SYSCH_RELIABLE; } break; diff --git a/modules/enet/enet_multiplayer_peer.h b/modules/enet/enet_multiplayer_peer.h index 18eca18e51..3152068d46 100644 --- a/modules/enet/enet_multiplayer_peer.h +++ b/modules/enet/enet_multiplayer_peer.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NETWORKED_MULTIPLAYER_ENET_H -#define NETWORKED_MULTIPLAYER_ENET_H +#ifndef ENET_MULTIPLAYER_PEER_H +#define ENET_MULTIPLAYER_PEER_H #include "core/crypto/crypto.h" -#include "core/multiplayer/multiplayer_peer.h" +#include "scene/main/multiplayer_peer.h" #include "enet_connection.h" #include <enet/enet.h> @@ -135,4 +135,4 @@ public: ~ENetMultiplayerPeer(); }; -#endif // NETWORKED_MULTIPLAYER_ENET_H +#endif // ENET_MULTIPLAYER_PEER_H diff --git a/modules/freetype/uwpdef.h b/modules/freetype/uwpdef.h index 05aaae61b5..f85f293171 100644 --- a/modules/freetype/uwpdef.h +++ b/modules/freetype/uwpdef.h @@ -28,6 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef UWPDEF_H +#define UWPDEF_H + // "generic" is a reserved keyword in C++/CX code // this avoids the errors in the variable name from Freetype code #define generic freetype_generic + +#endif // UWPDEF_H diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index e995cce651..10cf783e73 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -144,6 +144,7 @@ [/codeblock] [b]Important:[/b] The path must be absolute, a local path will just return [code]null[/code]. This method is a simplified version of [method ResourceLoader.load], which can be used for more advanced scenarios. + [b]Note:[/b] You have to import the files into the engine first to load them using [method load]. If you want to load [Image]s at run-time, you may use [method Image.load]. If you want to import audio files, you can use the snippet described in [member AudioStreamMP3.data]. </description> </method> <method name="preload"> diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index b86e9b386d..4372bb33ba 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -55,7 +55,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l bool in_function_args = false; bool in_member_variable = false; bool in_node_path = false; + bool in_node_ref = false; bool in_annotation = false; + bool in_string_name = false; bool is_hex_notation = false; bool is_bin_notation = false; bool expect_type = false; @@ -165,6 +167,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l if (in_node_path && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) { region_color = node_path_color; } + if (in_node_ref && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) { + region_color = node_ref_color; + } + if (in_string_name && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) { + region_color = string_name_color; + } prev_color = region_color; highlighter_info["color"] = region_color; @@ -387,24 +395,42 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_member_variable = false; } - if (!in_node_path && in_region == -1 && (str[j] == '$' || str[j] == '%')) { + if (!in_node_path && in_region == -1 && (str[j] == '^')) { in_node_path = true; } else if (in_region != -1 || (is_a_symbol && str[j] != '/' && str[j] != '%')) { in_node_path = false; } + if (!in_node_ref && in_region == -1 && (str[j] == '$' || str[j] == '%')) { + in_node_ref = true; + } else if (in_region != -1 || (is_a_symbol && str[j] != '/' && str[j] != '%')) { + in_node_ref = false; + } + if (!in_annotation && in_region == -1 && str[j] == '@') { in_annotation = true; } else if (in_region != -1 || is_a_symbol) { in_annotation = false; } + if (!in_string_name && in_region == -1 && str[j] == '&') { + in_string_name = true; + } else if (in_region != -1 || is_a_symbol) { + in_string_name = false; + } + if (in_node_path) { next_type = NODE_PATH; color = node_path_color; + } else if (in_node_ref) { + next_type = NODE_REF; + color = node_ref_color; } else if (in_annotation) { next_type = ANNOTATION; color = annotation_color; + } else if (in_string_name) { + next_type = STRING_NAME; + color = string_name_color; } else if (in_keyword) { next_type = KEYWORD; color = keyword_color; @@ -592,17 +618,23 @@ void GDScriptSyntaxHighlighter::_update_cache() { if (godot_2_theme || EditorSettings::get_singleton()->is_dark_theme()) { function_definition_color = Color(0.4, 0.9, 1.0); - node_path_color = Color(0.39, 0.76, 0.35); + node_path_color = Color(0.72, 0.77, 0.49); + node_ref_color = Color(0.39, 0.76, 0.35); annotation_color = Color(1.0, 0.7, 0.45); + string_name_color = Color(1.0, 0.66, 0.72); } else { function_definition_color = Color(0.0, 0.65, 0.73); - node_path_color = Color(0.32, 0.55, 0.29); + node_path_color = Color(0.62, 0.67, 0.39); + node_ref_color = Color(0.32, 0.55, 0.29); annotation_color = Color(0.8, 0.5, 0.25); + string_name_color = Color(0.9, 0.56, 0.62); } EDITOR_DEF("text_editor/theme/highlighting/gdscript/function_definition_color", function_definition_color); EDITOR_DEF("text_editor/theme/highlighting/gdscript/node_path_color", node_path_color); + EDITOR_DEF("text_editor/theme/highlighting/gdscript/node_reference_color", node_ref_color); EDITOR_DEF("text_editor/theme/highlighting/gdscript/annotation_color", annotation_color); + EDITOR_DEF("text_editor/theme/highlighting/gdscript/string_name_color", string_name_color); if (text_edit_color_theme == "Default" || godot_2_theme) { EditorSettings::get_singleton()->set_initial_value( "text_editor/theme/highlighting/gdscript/function_definition_color", @@ -613,14 +645,24 @@ void GDScriptSyntaxHighlighter::_update_cache() { node_path_color, true); EditorSettings::get_singleton()->set_initial_value( + "text_editor/theme/highlighting/gdscript/node_reference_color", + node_ref_color, + true); + EditorSettings::get_singleton()->set_initial_value( "text_editor/theme/highlighting/gdscript/annotation_color", annotation_color, true); + EditorSettings::get_singleton()->set_initial_value( + "text_editor/theme/highlighting/gdscript/string_name_color", + string_name_color, + true); } function_definition_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/function_definition_color"); node_path_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/node_path_color"); + node_ref_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/node_reference_color"); annotation_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/annotation_color"); + string_name_color = EDITOR_GET("text_editor/theme/highlighting/gdscript/string_name_color"); type_color = EDITOR_GET("text_editor/theme/highlighting/base_type_color"); } diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h index 92764e3891..7987582f07 100644 --- a/modules/gdscript/editor/gdscript_highlighter.h +++ b/modules/gdscript/editor/gdscript_highlighter.h @@ -54,7 +54,9 @@ private: NONE, REGION, NODE_PATH, + NODE_REF, ANNOTATION, + STRING_NAME, SYMBOL, NUMBER, FUNCTION, @@ -74,7 +76,9 @@ private: Color number_color; Color member_color; Color node_path_color; + Color node_ref_color; Color annotation_color; + Color string_name_color; Color type_color; void add_color_region(const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only = false); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index e74314389d..4a3dbce2b9 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -278,6 +278,11 @@ void GDScript::_get_script_method_list(List<MethodInfo> *r_list, bool p_include_ GDScriptFunction *func = E.value; MethodInfo mi; mi.name = E.key; + + if (func->is_static()) { + mi.flags |= METHOD_FLAG_STATIC; + } + for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arginfo = func->get_argument_type(i); #ifdef TOOLS_ENABLED @@ -870,7 +875,7 @@ Error GDScript::reload(bool p_keep_state) { } // TODO: Show all error messages. _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT); - ERR_FAIL_V(ERR_PARSE_ERROR); + return ERR_PARSE_ERROR; } GDScriptAnalyzer analyzer(&parser); @@ -886,7 +891,7 @@ Error GDScript::reload(bool p_keep_state) { _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT); e = e->next(); } - ERR_FAIL_V(ERR_PARSE_ERROR); + return ERR_PARSE_ERROR; } bool can_run = ScriptServer::is_scripting_enabled() || parser.is_tool(); @@ -904,7 +909,7 @@ Error GDScript::reload(bool p_keep_state) { GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error()); } _err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), compiler.get_error_line(), ("Compile Error: " + compiler.get_error()).utf8().get_data(), false, ERR_HANDLER_SCRIPT); - ERR_FAIL_V(ERR_COMPILATION_FAILED); + return ERR_COMPILATION_FAILED; } else { return err; } @@ -949,8 +954,8 @@ void GDScript::get_members(HashSet<StringName> *p_members) { } } -const Vector<Multiplayer::RPCConfig> GDScript::get_rpc_methods() const { - return rpc_functions; +const Variant GDScript::get_rpc_config() const { + return rpc_config; } Variant GDScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { @@ -1207,9 +1212,9 @@ void GDScript::_save_orphaned_subclasses() { void GDScript::_init_rpc_methods_properties() { // Copy the base rpc methods so we don't mask their IDs. - rpc_functions.clear(); + rpc_config.clear(); if (base.is_valid()) { - rpc_functions = base->rpc_functions; + rpc_config = base->rpc_config.duplicate(); } GDScript *cscript = this; @@ -1217,12 +1222,9 @@ void GDScript::_init_rpc_methods_properties() { while (cscript) { // RPC Methods for (KeyValue<StringName, GDScriptFunction *> &E : cscript->member_functions) { - Multiplayer::RPCConfig config = E.value->get_rpc_config(); - if (config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) { - config.name = E.value->get_name(); - if (rpc_functions.find(config) == -1) { - rpc_functions.push_back(config); - } + Variant config = E.value->get_rpc_config(); + if (config.get_type() != Variant::NIL) { + rpc_config[E.value->get_name()] = config; } } @@ -1236,9 +1238,6 @@ void GDScript::_init_rpc_methods_properties() { cscript = nullptr; } } - - // Sort so we are 100% that they are always the same. - rpc_functions.sort_custom<Multiplayer::SortRPCConfig>(); } GDScript::~GDScript() { @@ -1403,9 +1402,7 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { while (sl) { HashMap<StringName, GDScriptFunction *>::ConstIterator E = sl->member_functions.find(p_name); if (E) { - Multiplayer::RPCConfig config; - config.name = p_name; - if (sptr->rpc_functions.find(config) != -1) { + if (sptr->rpc_config.has(p_name)) { r_ret = Callable(memnew(GDScriptRPCCallable(this->owner, E->key))); } else { r_ret = Callable(this->owner, E->key); @@ -1624,15 +1621,13 @@ ScriptLanguage *GDScriptInstance::get_language() { return GDScriptLanguage::get_singleton(); } -const Vector<Multiplayer::RPCConfig> GDScriptInstance::get_rpc_methods() const { - return script->get_rpc_methods(); +const Variant GDScriptInstance::get_rpc_config() const { + return script->get_rpc_config(); } void GDScriptInstance::reload_members() { #ifdef DEBUG_ENABLED - members.resize(script->member_indices.size()); //resize - Vector<Variant> new_members; new_members.resize(script->member_indices.size()); @@ -1644,6 +1639,8 @@ void GDScriptInstance::reload_members() { } } + members.resize(new_members.size()); //resize + //apply members = new_members; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index e9a206f48b..47de3ad088 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -87,7 +87,7 @@ class GDScript : public Script { HashMap<StringName, MemberInfo> member_indices; //members are just indices to the instantiated script. HashMap<StringName, Ref<GDScript>> subclasses; HashMap<StringName, Vector<StringName>> _signals; - Vector<Multiplayer::RPCConfig> rpc_functions; + Dictionary rpc_config; #ifdef TOOLS_ENABLED @@ -250,7 +250,7 @@ public: virtual void get_constants(HashMap<StringName, Variant> *p_constants) override; virtual void get_members(HashSet<StringName> *p_members) override; - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override; + virtual const Variant get_rpc_config() const override; #ifdef TOOLS_ENABLED virtual bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; } @@ -304,7 +304,7 @@ public: void reload_members(); - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const; + virtual const Variant get_rpc_config() const; GDScriptInstance(); ~GDScriptInstance(); diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 8b4c245bf6..7ed440929c 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3329,8 +3329,11 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::VECTOR2I: case Variant::VECTOR3: case Variant::VECTOR3I: + case Variant::VECTOR4: + case Variant::VECTOR4I: case Variant::TRANSFORM2D: case Variant::TRANSFORM3D: + case Variant::PROJECTION: error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::FLOAT && index_type.builtin_type != Variant::STRING; break; @@ -3393,6 +3396,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::PACKED_INT64_ARRAY: case Variant::VECTOR2I: case Variant::VECTOR3I: + case Variant::VECTOR4I: result_type.builtin_type = Variant::INT; break; // Return float. @@ -3400,6 +3404,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::PACKED_FLOAT64_ARRAY: case Variant::VECTOR2: case Variant::VECTOR3: + case Variant::VECTOR4: case Variant::QUATERNION: result_type.builtin_type = Variant::FLOAT; break; @@ -3430,6 +3435,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri break; // Depends on the index. case Variant::TRANSFORM3D: + case Variant::PROJECTION: case Variant::PLANE: case Variant::COLOR: case Variant::DICTIONARY: diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 6a1effd680..fa158591fd 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -84,11 +84,14 @@ uint32_t GDScriptByteCodeGenerator::add_temporary(const GDScriptDataType &p_type case Variant::VECTOR3: case Variant::VECTOR3I: case Variant::TRANSFORM2D: + case Variant::VECTOR4: + case Variant::VECTOR4I: case Variant::PLANE: case Variant::QUATERNION: case Variant::AABB: case Variant::BASIS: case Variant::TRANSFORM3D: + case Variant::PROJECTION: case Variant::COLOR: case Variant::STRING_NAME: case Variant::NODE_PATH: @@ -155,7 +158,7 @@ void GDScriptByteCodeGenerator::end_parameters() { function->default_arguments.reverse(); } -void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) { +void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) { function = memnew(GDScriptFunction); debug_stack = EngineDebugger::is_active(); @@ -453,6 +456,12 @@ void GDScriptByteCodeGenerator::write_type_adjust(const Address &p_target, Varia case Variant::TRANSFORM2D: append(GDScriptFunction::OPCODE_TYPE_ADJUST_TRANSFORM2D, 1); break; + case Variant::VECTOR4: + append(GDScriptFunction::OPCODE_TYPE_ADJUST_VECTOR3, 1); + break; + case Variant::VECTOR4I: + append(GDScriptFunction::OPCODE_TYPE_ADJUST_VECTOR3I, 1); + break; case Variant::PLANE: append(GDScriptFunction::OPCODE_TYPE_ADJUST_PLANE, 1); break; @@ -468,6 +477,9 @@ void GDScriptByteCodeGenerator::write_type_adjust(const Address &p_target, Varia case Variant::TRANSFORM3D: append(GDScriptFunction::OPCODE_TYPE_ADJUST_TRANSFORM3D, 1); break; + case Variant::PROJECTION: + append(GDScriptFunction::OPCODE_TYPE_ADJUST_PROJECTION, 1); + break; case Variant::COLOR: append(GDScriptFunction::OPCODE_TYPE_ADJUST_COLOR, 1); break; @@ -1596,7 +1608,7 @@ void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) { // Typed array. const GDScriptDataType &element_type = function->return_type.get_container_element_type(); - Variant script = function->return_type.script_type; + Variant script = element_type.script_type; int script_idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS); append(GDScriptFunction::OPCODE_RETURN_TYPED_ARRAY, 2); diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index f4b402fc96..7dd51845df 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GDSCRIPT_BYTE_CODEGEN -#define GDSCRIPT_BYTE_CODEGEN +#ifndef GDSCRIPT_BYTE_CODEGEN_H +#define GDSCRIPT_BYTE_CODEGEN_H #include "gdscript_codegen.h" @@ -419,7 +419,7 @@ public: virtual void start_block() override; virtual void end_block() override; - virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) override; + virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) override; virtual GDScriptFunction *write_end() override; #ifdef DEBUG_ENABLED @@ -502,4 +502,4 @@ public: virtual ~GDScriptByteCodeGenerator(); }; -#endif // GDSCRIPT_BYTE_CODEGEN +#endif // GDSCRIPT_BYTE_CODEGEN_H diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index 81fa265aca..5972481c3a 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -28,10 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GDSCRIPT_CODEGEN -#define GDSCRIPT_CODEGEN +#ifndef GDSCRIPT_CODEGEN_H +#define GDSCRIPT_CODEGEN_H -#include "core/multiplayer/multiplayer.h" #include "core/string/string_name.h" #include "core/variant/variant.h" #include "gdscript_function.h" @@ -80,7 +79,7 @@ public: virtual void start_block() = 0; virtual void end_block() = 0; - virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Multiplayer::RPCConfig p_rpc_config, const GDScriptDataType &p_return_type) = 0; + virtual void write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, Variant p_rpc_config, const GDScriptDataType &p_return_type) = 0; virtual GDScriptFunction *write_end() = 0; #ifdef DEBUG_ENABLED @@ -163,4 +162,4 @@ public: virtual ~GDScriptCodeGenerator() {} }; -#endif // GDSCRIPT_CODEGEN +#endif // GDSCRIPT_CODEGEN_H diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index e36252ada5..00e8223b9a 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1975,7 +1975,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ StringName func_name; bool is_static = false; - Multiplayer::RPCConfig rpc_config; + Variant rpc_config; GDScriptDataType return_type; return_type.has_type = true; return_type.kind = GDScriptDataType::BUILTIN; diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp index 726f0efe2b..b38c7c6699 100644 --- a/modules/gdscript/gdscript_disassembler.cpp +++ b/modules/gdscript/gdscript_disassembler.cpp @@ -639,10 +639,13 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { DISASSEMBLE_PTRCALL(VECTOR3); DISASSEMBLE_PTRCALL(VECTOR3I); DISASSEMBLE_PTRCALL(TRANSFORM2D); + DISASSEMBLE_PTRCALL(VECTOR4); + DISASSEMBLE_PTRCALL(VECTOR4I); DISASSEMBLE_PTRCALL(PLANE); DISASSEMBLE_PTRCALL(AABB); DISASSEMBLE_PTRCALL(BASIS); DISASSEMBLE_PTRCALL(TRANSFORM3D); + DISASSEMBLE_PTRCALL(PROJECTION); DISASSEMBLE_PTRCALL(COLOR); DISASSEMBLE_PTRCALL(STRING_NAME); DISASSEMBLE_PTRCALL(NODE_PATH); @@ -1013,11 +1016,14 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { DISASSEMBLE_TYPE_ADJUST(VECTOR3); DISASSEMBLE_TYPE_ADJUST(VECTOR3I); DISASSEMBLE_TYPE_ADJUST(TRANSFORM2D); + DISASSEMBLE_TYPE_ADJUST(VECTOR4); + DISASSEMBLE_TYPE_ADJUST(VECTOR4I); DISASSEMBLE_TYPE_ADJUST(PLANE); DISASSEMBLE_TYPE_ADJUST(QUATERNION); DISASSEMBLE_TYPE_ADJUST(AABB); DISASSEMBLE_TYPE_ADJUST(BASIS); DISASSEMBLE_TYPE_ADJUST(TRANSFORM3D); + DISASSEMBLE_TYPE_ADJUST(PROJECTION); DISASSEMBLE_TYPE_ADJUST(COLOR); DISASSEMBLE_TYPE_ADJUST(STRING_NAME); DISASSEMBLE_TYPE_ADJUST(NODE_PATH); diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 3f1265679b..e44038d6da 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -273,11 +273,14 @@ public: OPCODE_CALL_PTRCALL_VECTOR3, OPCODE_CALL_PTRCALL_VECTOR3I, OPCODE_CALL_PTRCALL_TRANSFORM2D, + OPCODE_CALL_PTRCALL_VECTOR4, + OPCODE_CALL_PTRCALL_VECTOR4I, OPCODE_CALL_PTRCALL_PLANE, OPCODE_CALL_PTRCALL_QUATERNION, OPCODE_CALL_PTRCALL_AABB, OPCODE_CALL_PTRCALL_BASIS, OPCODE_CALL_PTRCALL_TRANSFORM3D, + OPCODE_CALL_PTRCALL_PROJECTION, OPCODE_CALL_PTRCALL_COLOR, OPCODE_CALL_PTRCALL_STRING_NAME, OPCODE_CALL_PTRCALL_NODE_PATH, @@ -363,11 +366,14 @@ public: OPCODE_TYPE_ADJUST_VECTOR3, OPCODE_TYPE_ADJUST_VECTOR3I, OPCODE_TYPE_ADJUST_TRANSFORM2D, + OPCODE_TYPE_ADJUST_VECTOR4, + OPCODE_TYPE_ADJUST_VECTOR4I, OPCODE_TYPE_ADJUST_PLANE, OPCODE_TYPE_ADJUST_QUATERNION, OPCODE_TYPE_ADJUST_AABB, OPCODE_TYPE_ADJUST_BASIS, OPCODE_TYPE_ADJUST_TRANSFORM3D, + OPCODE_TYPE_ADJUST_PROJECTION, OPCODE_TYPE_ADJUST_COLOR, OPCODE_TYPE_ADJUST_STRING_NAME, OPCODE_TYPE_ADJUST_NODE_PATH, @@ -471,7 +477,7 @@ private: int _initial_line = 0; bool _static = false; - Multiplayer::RPCConfig rpc_config; + Variant rpc_config; GDScript *_script = nullptr; @@ -593,7 +599,7 @@ public: void disassemble(const Vector<String> &p_code_lines) const; #endif - _FORCE_INLINE_ Multiplayer::RPCConfig get_rpc_config() const { return rpc_config; } + _FORCE_INLINE_ const Variant get_rpc_config() const { return rpc_config; } GDScriptFunction(); ~GDScriptFunction(); }; diff --git a/modules/gdscript/gdscript_lambda_callable.h b/modules/gdscript/gdscript_lambda_callable.h index 248176e32c..1954089983 100644 --- a/modules/gdscript/gdscript_lambda_callable.h +++ b/modules/gdscript/gdscript_lambda_callable.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GDSCRIPT_LAMBDA_CALLABLE -#define GDSCRIPT_LAMBDA_CALLABLE +#ifndef GDSCRIPT_LAMBDA_CALLABLE_H +#define GDSCRIPT_LAMBDA_CALLABLE_H #include "core/object/ref_counted.h" #include "core/templates/vector.h" @@ -87,4 +87,4 @@ public: virtual ~GDScriptLambdaSelfCallable() = default; }; -#endif // GDSCRIPT_LAMBDA_CALLABLE +#endif // GDSCRIPT_LAMBDA_CALLABLE_H diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 01a672c330..6f5397e1a3 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -35,6 +35,7 @@ #include "core/io/resource_loader.h" #include "core/math/math_defs.h" #include "gdscript.h" +#include "scene/main/multiplayer_api.h" #ifdef DEBUG_ENABLED #include "core/os/os.h" @@ -60,11 +61,14 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) { builtin_types["Transform2D"] = Variant::TRANSFORM2D; builtin_types["Vector3"] = Variant::VECTOR3; builtin_types["Vector3i"] = Variant::VECTOR3I; + builtin_types["Vector4"] = Variant::VECTOR4; + builtin_types["Vector4i"] = Variant::VECTOR4I; builtin_types["AABB"] = Variant::AABB; builtin_types["Plane"] = Variant::PLANE; builtin_types["Quaternion"] = Variant::QUATERNION; builtin_types["Basis"] = Variant::BASIS; builtin_types["Transform3D"] = Variant::TRANSFORM3D; + builtin_types["Projection"] = Variant::PROJECTION; builtin_types["Color"] = Variant::COLOR; builtin_types["RID"] = Variant::RID; builtin_types["Object"] = Variant::OBJECT; @@ -142,7 +146,7 @@ GDScriptParser::GDScriptParser() { // Warning annotations. register_annotation(MethodInfo("@warning_ignore", PropertyInfo(Variant::STRING, "warning")), AnnotationInfo::CLASS | AnnotationInfo::VARIABLE | AnnotationInfo::SIGNAL | AnnotationInfo::CONSTANT | AnnotationInfo::FUNCTION | AnnotationInfo::STATEMENT, &GDScriptParser::warning_annotations, varray(), true); // Networking. - register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::network_annotations<Multiplayer::RPC_MODE_AUTHORITY>, varray("", "", "", 0), true); + register_annotation(MethodInfo("@rpc", PropertyInfo(Variant::STRING, "mode"), PropertyInfo(Variant::STRING, "sync"), PropertyInfo(Variant::STRING, "transfer_mode"), PropertyInfo(Variant::INT, "transfer_channel")), AnnotationInfo::FUNCTION, &GDScriptParser::rpc_annotation, varray("", "", "", 0), true); } GDScriptParser::~GDScriptParser() { @@ -3864,16 +3868,21 @@ bool GDScriptParser::warning_annotations(const AnnotationNode *p_annotation, Nod #endif // DEBUG_ENABLED } -template <Multiplayer::RPCMode t_mode> -bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Node *p_node) { - ERR_FAIL_COND_V_MSG(p_node->type != Node::VARIABLE && p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to variables and functions.)", p_annotation->name)); +bool GDScriptParser::rpc_annotation(const AnnotationNode *p_annotation, Node *p_node) { + ERR_FAIL_COND_V_MSG(p_node->type != Node::FUNCTION, false, vformat(R"("%s" annotation can only be applied to functions.)", p_annotation->name)); - Multiplayer::RPCConfig rpc_config; - rpc_config.rpc_mode = t_mode; + FunctionNode *function = static_cast<FunctionNode *>(p_node); + if (function->rpc_config.get_type() != Variant::NIL) { + push_error(R"(RPC annotations can only be used once per function.)", p_annotation); + return false; + } + + Dictionary rpc_config; + rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY; if (p_annotation->resolved_arguments.size()) { int last = p_annotation->resolved_arguments.size() - 1; if (p_annotation->resolved_arguments[last].get_type() == Variant::INT) { - rpc_config.channel = p_annotation->resolved_arguments[last].operator int(); + rpc_config["channel"] = p_annotation->resolved_arguments[last].operator int(); last -= 1; } if (last > 3) { @@ -3883,37 +3892,25 @@ bool GDScriptParser::network_annotations(const AnnotationNode *p_annotation, Nod for (int i = last; i >= 0; i--) { String mode = p_annotation->resolved_arguments[i].operator String(); if (mode == "any_peer") { - rpc_config.rpc_mode = Multiplayer::RPC_MODE_ANY_PEER; + rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_ANY_PEER; } else if (mode == "authority") { - rpc_config.rpc_mode = Multiplayer::RPC_MODE_AUTHORITY; + rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY; } else if (mode == "call_local") { - rpc_config.call_local = true; + rpc_config["call_local"] = true; } else if (mode == "call_remote") { - rpc_config.call_local = false; + rpc_config["call_local"] = false; } else if (mode == "reliable") { - rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; + rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE; } else if (mode == "unreliable") { - rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE; + rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE; } else if (mode == "unreliable_ordered") { - rpc_config.transfer_mode = Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED; + rpc_config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_UNRELIABLE_ORDERED; } else { push_error(R"(Invalid RPC argument. Must be one of: 'call_local'/'call_remote' (local calls), 'any_peer'/'authority' (permission), 'reliable'/'unreliable'/'unreliable_ordered' (transfer mode).)", p_annotation); } } } - switch (p_node->type) { - case Node::FUNCTION: { - FunctionNode *function = static_cast<FunctionNode *>(p_node); - if (function->rpc_config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) { - push_error(R"(RPC annotations can only be used once per function.)", p_annotation); - return false; - } - function->rpc_config = rpc_config; - break; - } - default: - return false; // Unreachable. - } + function->rpc_config = rpc_config; return true; } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 9c97f98fbc..d4efab173b 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -32,7 +32,6 @@ #define GDSCRIPT_PARSER_H #include "core/io/resource.h" -#include "core/multiplayer/multiplayer.h" #include "core/object/ref_counted.h" #include "core/object/script_language.h" #include "core/string/string_name.h" @@ -750,7 +749,7 @@ public: SuiteNode *body = nullptr; bool is_static = false; bool is_coroutine = false; - Multiplayer::RPCConfig rpc_config; + Variant rpc_config; MethodInfo info; LambdaNode *source_lambda = nullptr; #ifdef TOOLS_ENABLED @@ -1371,8 +1370,7 @@ private: template <PropertyUsageFlags t_usage> bool export_group_annotations(const AnnotationNode *p_annotation, Node *p_target); bool warning_annotations(const AnnotationNode *p_annotation, Node *p_target); - template <Multiplayer::RPCMode t_mode> - bool network_annotations(const AnnotationNode *p_annotation, Node *p_target); + bool rpc_annotation(const AnnotationNode *p_annotation, Node *p_target); // Statements. Node *parse_statement(); VariableNode *parse_variable(); diff --git a/modules/gdscript/gdscript_rpc_callable.cpp b/modules/gdscript/gdscript_rpc_callable.cpp index 63ebd8acf5..4e12419357 100644 --- a/modules/gdscript/gdscript_rpc_callable.cpp +++ b/modules/gdscript/gdscript_rpc_callable.cpp @@ -76,11 +76,11 @@ GDScriptRPCCallable::GDScriptRPCCallable(Object *p_object, const StringName &p_m ERR_FAIL_COND_MSG(!node, "RPC can only be defined on class that extends Node."); } -void GDScriptRPCCallable::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { +Error GDScriptRPCCallable::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { if (unlikely(!node)) { r_call_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; - return; + return ERR_UNCONFIGURED; } r_call_error.error = Callable::CallError::CALL_OK; - node->rpcp(p_peer_id, method, p_arguments, p_argcount); + return node->rpcp(p_peer_id, method, p_arguments, p_argcount); } diff --git a/modules/gdscript/gdscript_rpc_callable.h b/modules/gdscript/gdscript_rpc_callable.h index 2c8734a74b..83b9c7e2df 100644 --- a/modules/gdscript/gdscript_rpc_callable.h +++ b/modules/gdscript/gdscript_rpc_callable.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GDSCRIPT_RPC_CALLABLE -#define GDSCRIPT_RPC_CALLABLE +#ifndef GDSCRIPT_RPC_CALLABLE_H +#define GDSCRIPT_RPC_CALLABLE_H #include "core/variant/callable.h" #include "core/variant/variant.h" @@ -52,10 +52,10 @@ public: CompareLessFunc get_compare_less_func() const override; ObjectID get_object() const override; void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; - void rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; + Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; GDScriptRPCCallable(Object *p_object, const StringName &p_method); virtual ~GDScriptRPCCallable() = default; }; -#endif // GDSCRIPT_RPC_CALLABLE +#endif // GDSCRIPT_RPC_CALLABLE_H diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 7fb715f2c8..68b2c6eb1c 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -273,4 +273,4 @@ public: GDScriptTokenizer(); }; -#endif +#endif // GDSCRIPT_TOKENIZER_H diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp index a914374985..4b97486cb3 100644 --- a/modules/gdscript/gdscript_utility_functions.cpp +++ b/modules/gdscript/gdscript_utility_functions.cpp @@ -115,6 +115,7 @@ struct GDScriptUtilityFunctionsDefinitions { if (p_arg_count < 1) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; + r_error.expected = 1; *r_ret = Variant(); return; } diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index e0beed367a..36ccb3d696 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -199,11 +199,14 @@ void (*type_init_function_table[])(Variant *) = { &VariantInitializer<Vector3>::init, // VECTOR3. &VariantInitializer<Vector3i>::init, // VECTOR3I. &VariantInitializer<Transform2D>::init, // TRANSFORM2D. + &VariantInitializer<Vector4>::init, // VECTOR4. + &VariantInitializer<Vector4i>::init, // VECTOR4I. &VariantInitializer<Plane>::init, // PLANE. &VariantInitializer<Quaternion>::init, // QUATERNION. &VariantInitializer<AABB>::init, // AABB. &VariantInitializer<Basis>::init, // BASIS. &VariantInitializer<Transform3D>::init, // TRANSFORM3D. + &VariantInitializer<Projection>::init, // PROJECTION. &VariantInitializer<Color>::init, // COLOR. &VariantInitializer<StringName>::init, // STRING_NAME. &VariantInitializer<NodePath>::init, // NODE_PATH. @@ -282,11 +285,14 @@ void (*type_init_function_table[])(Variant *) = { &&OPCODE_CALL_PTRCALL_VECTOR3, \ &&OPCODE_CALL_PTRCALL_VECTOR3I, \ &&OPCODE_CALL_PTRCALL_TRANSFORM2D, \ + &&OPCODE_CALL_PTRCALL_VECTOR4, \ + &&OPCODE_CALL_PTRCALL_VECTOR4I, \ &&OPCODE_CALL_PTRCALL_PLANE, \ &&OPCODE_CALL_PTRCALL_QUATERNION, \ &&OPCODE_CALL_PTRCALL_AABB, \ &&OPCODE_CALL_PTRCALL_BASIS, \ &&OPCODE_CALL_PTRCALL_TRANSFORM3D, \ + &&OPCODE_CALL_PTRCALL_PROJECTION, \ &&OPCODE_CALL_PTRCALL_COLOR, \ &&OPCODE_CALL_PTRCALL_STRING_NAME, \ &&OPCODE_CALL_PTRCALL_NODE_PATH, \ @@ -372,11 +378,14 @@ void (*type_init_function_table[])(Variant *) = { &&OPCODE_TYPE_ADJUST_VECTOR3, \ &&OPCODE_TYPE_ADJUST_VECTOR3I, \ &&OPCODE_TYPE_ADJUST_TRANSFORM2D, \ + &&OPCODE_TYPE_ADJUST_VECTOR4, \ + &&OPCODE_TYPE_ADJUST_VECTOR4I, \ &&OPCODE_TYPE_ADJUST_PLANE, \ &&OPCODE_TYPE_ADJUST_QUATERNION, \ &&OPCODE_TYPE_ADJUST_AABB, \ &&OPCODE_TYPE_ADJUST_BASIS, \ &&OPCODE_TYPE_ADJUST_TRANSFORM3D, \ + &&OPCODE_TYPE_ADJUST_PROJECTION, \ &&OPCODE_TYPE_ADJUST_COLOR, \ &&OPCODE_TYPE_ADJUST_STRING_NAME, \ &&OPCODE_TYPE_ADJUST_NODE_PATH, \ @@ -435,6 +444,8 @@ void (*type_init_function_table[])(Variant *) = { #define OP_GET_VECTOR3 get_vector3 #define OP_GET_VECTOR3I get_vector3i #define OP_GET_RECT2 get_rect2 +#define OP_GET_VECTOR4 get_vector4 +#define OP_GET_VECTOR4I get_vector4i #define OP_GET_RECT2I get_rect2i #define OP_GET_QUATERNION get_quaternion #define OP_GET_COLOR get_color @@ -456,6 +467,7 @@ void (*type_init_function_table[])(Variant *) = { #define OP_GET_PACKED_COLOR_ARRAY get_color_array #define OP_GET_TRANSFORM3D get_transform #define OP_GET_TRANSFORM2D get_transform2d +#define OP_GET_PROJECTION get_projection #define OP_GET_PLANE get_plane #define OP_GET_AABB get_aabb #define OP_GET_BASIS get_basis @@ -1827,11 +1839,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_CALL_PTR(VECTOR3); OPCODE_CALL_PTR(VECTOR3I); OPCODE_CALL_PTR(TRANSFORM2D); + OPCODE_CALL_PTR(VECTOR4); + OPCODE_CALL_PTR(VECTOR4I); OPCODE_CALL_PTR(PLANE); OPCODE_CALL_PTR(QUATERNION); OPCODE_CALL_PTR(AABB); OPCODE_CALL_PTR(BASIS); OPCODE_CALL_PTR(TRANSFORM3D); + OPCODE_CALL_PTR(PROJECTION); OPCODE_CALL_PTR(COLOR); OPCODE_CALL_PTR(STRING_NAME); OPCODE_CALL_PTR(NODE_PATH); @@ -3280,6 +3295,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a int globalname_idx = _code_ptr[ip + 2]; GD_ERR_BREAK(globalname_idx < 0 || globalname_idx >= _global_names_count); const StringName *globalname = &_global_names_ptr[globalname_idx]; + GD_ERR_BREAK(!GDScriptLanguage::get_singleton()->get_named_globals_map().has(*globalname)); GET_INSTRUCTION_ARG(dst, 0); *dst = GDScriptLanguage::get_singleton()->get_named_globals_map()[*globalname]; @@ -3308,11 +3324,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_TYPE_ADJUST(VECTOR3, Vector3); OPCODE_TYPE_ADJUST(VECTOR3I, Vector3i); OPCODE_TYPE_ADJUST(TRANSFORM2D, Transform2D); + OPCODE_TYPE_ADJUST(VECTOR4, Vector4); + OPCODE_TYPE_ADJUST(VECTOR4I, Vector4i); OPCODE_TYPE_ADJUST(PLANE, Plane); OPCODE_TYPE_ADJUST(QUATERNION, Quaternion); OPCODE_TYPE_ADJUST(AABB, AABB); OPCODE_TYPE_ADJUST(BASIS, Basis); OPCODE_TYPE_ADJUST(TRANSFORM3D, Transform3D); + OPCODE_TYPE_ADJUST(PROJECTION, Projection); OPCODE_TYPE_ADJUST(COLOR, Color); OPCODE_TYPE_ADJUST(STRING_NAME, StringName); OPCODE_TYPE_ADJUST(NODE_PATH, NodePath); diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h index f47f31aedf..a639e7b44e 100644 --- a/modules/gdscript/gdscript_warning.h +++ b/modules/gdscript/gdscript_warning.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GDSCRIPT_WARNINGS -#define GDSCRIPT_WARNINGS +#ifndef GDSCRIPT_WARNING_H +#define GDSCRIPT_WARNING_H #ifdef DEBUG_ENABLED @@ -97,4 +97,4 @@ public: #endif // DEBUG_ENABLED -#endif // GDSCRIPT_WARNINGS +#endif // GDSCRIPT_WARNING_H diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index 03e93821c7..46a9b33eb0 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -690,9 +690,7 @@ Dictionary ExtendGDScriptParser::dump_function_api(const GDScriptParser::Functio ERR_FAIL_NULL_V(p_func, func); func["name"] = p_func->identifier->name; func["return_type"] = p_func->get_datatype().to_string(); - func["rpc_mode"] = p_func->rpc_config.rpc_mode; - func["rpc_transfer_mode"] = p_func->rpc_config.transfer_mode; - func["rpc_transfer_channel"] = p_func->rpc_config.channel; + func["rpc_config"] = p_func->rpc_config; Array parameters; for (int i = 0; i < p_func->parameters.size(); i++) { Dictionary arg; diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h index 99b0bf45d0..08bba4a2d4 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.h +++ b/modules/gdscript/language_server/gdscript_extend_parser.h @@ -33,7 +33,7 @@ #include "../gdscript_parser.h" #include "core/variant/variant.h" -#include "lsp.hpp" +#include "godot_lsp.h" #ifndef LINE_NUMBER_TO_INDEX #define LINE_NUMBER_TO_INDEX(p_line) ((p_line)-1) @@ -99,4 +99,4 @@ public: Error parse(const String &p_code, const String &p_path); }; -#endif +#endif // GDSCRIPT_EXTEND_PARSER_H diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h index 0fed8597f9..3c9cfe512f 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.h +++ b/modules/gdscript/language_server/gdscript_language_protocol.h @@ -36,7 +36,7 @@ #include "core/io/tcp_server.h" #include "gdscript_text_document.h" #include "gdscript_workspace.h" -#include "lsp.hpp" +#include "godot_lsp.h" #include "modules/modules_enabled.gen.h" // For jsonrpc. #ifdef MODULE_JSONRPC_ENABLED diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h index 9732765f34..87bc08a34e 100644 --- a/modules/gdscript/language_server/gdscript_text_document.h +++ b/modules/gdscript/language_server/gdscript_text_document.h @@ -33,7 +33,7 @@ #include "core/io/file_access.h" #include "core/object/ref_counted.h" -#include "lsp.hpp" +#include "godot_lsp.h" class GDScriptTextDocument : public RefCounted { GDCLASS(GDScriptTextDocument, RefCounted) @@ -77,4 +77,4 @@ public: GDScriptTextDocument(); }; -#endif +#endif // GDSCRIPT_TEXT_DOCUMENT_H diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 8d484a43b3..959651c024 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -499,7 +499,9 @@ Error GDScriptWorkspace::parse_local_script(const String &p_path) { String GDScriptWorkspace::get_file_path(const String &p_uri) const { String path = p_uri; - path = path.replace(root_uri + "/", "res://"); + path = path.replace("///", "//"); + path = path.replace("%3A", ":"); + path = path.replacen(root_uri + "/", "res://"); path = path.uri_decode(); return path; } diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index 7bff5db81f..88f3aaf957 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -35,7 +35,7 @@ #include "core/variant/variant.h" #include "editor/editor_file_system.h" #include "gdscript_extend_parser.h" -#include "lsp.hpp" +#include "godot_lsp.h" class GDScriptWorkspace : public RefCounted { GDCLASS(GDScriptWorkspace, RefCounted); @@ -100,4 +100,4 @@ public: ~GDScriptWorkspace(); }; -#endif +#endif // GDSCRIPT_WORKSPACE_H diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/godot_lsp.h index 1c9349097f..fbd40796c4 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/godot_lsp.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* lsp.hpp */ +/* godot_lsp.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -1975,4 +1975,4 @@ static String marked_documentation(const String &p_bbcode) { } } // namespace lsp -#endif +#endif // GODOT_LSP_H diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index b230c6ba36..059ca703ab 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -52,10 +52,10 @@ GDScriptCache *gdscript_cache = nullptr; #ifdef TOOLS_ENABLED -#include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_translation_parser.h" +#include "editor/export/editor_export.h" #include "editor/gdscript_highlighter.h" #include "editor/gdscript_translation_parser_plugin.h" diff --git a/modules/gdscript/tests/gdscript_test_runner.h b/modules/gdscript/tests/gdscript_test_runner.h index ee21afd9c9..033d2fcad1 100644 --- a/modules/gdscript/tests/gdscript_test_runner.h +++ b/modules/gdscript/tests/gdscript_test_runner.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GDSCRIPT_TEST_H -#define GDSCRIPT_TEST_H +#ifndef GDSCRIPT_TEST_RUNNER_H +#define GDSCRIPT_TEST_RUNNER_H #include "../gdscript.h" #include "core/error/error_macros.h" @@ -123,4 +123,4 @@ public: } // namespace GDScriptTests -#endif // GDSCRIPT_TEST_H +#endif // GDSCRIPT_TEST_RUNNER_H diff --git a/modules/gltf/README.md b/modules/gltf/README.md new file mode 100644 index 0000000000..5d8966b201 --- /dev/null +++ b/modules/gltf/README.md @@ -0,0 +1,11 @@ +# Godot GLTF import and export module + +In a nutshell, the GLTF module works like this: + +* The [`structures/`](structures/) folder contains GLTF structures, the + small pieces that make up a GLTF file, represented as C++ classes. +* The [`extensions/`](extensions/) folder contains GLTF extensions, which + are optional features that build on top of the base GLTF spec. +* [`GLTFState`](gltf_state.h) holds collections of structures and extensions. +* [`GLTFDocument`](gltf_document.h) operates on GLTFState and its elements. +* The [`editor/`](editor/) folder uses GLTFDocument to import and export 3D models. diff --git a/modules/gltf/SCsub b/modules/gltf/SCsub index 3379404a00..6634d5df7b 100644 --- a/modules/gltf/SCsub +++ b/modules/gltf/SCsub @@ -7,5 +7,7 @@ env_gltf = env_modules.Clone() # Godot's own source files env_gltf.add_source_files(env.modules_sources, "*.cpp") +env_gltf.add_source_files(env.modules_sources, "extensions/*.cpp") +env_gltf.add_source_files(env.modules_sources, "structures/*.cpp") if env["tools"]: env_gltf.add_source_files(env.modules_sources, "editor/*.cpp") diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index 033591a0b9..8002c185c7 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -292,7 +292,7 @@ static bool _test_blender_path(const String &p_path, String *r_err = nullptr) { path = path.plus_file("blender"); #endif -#if defined(OSX_ENABLED) +#if defined(MACOS_ENABLED) if (!FileAccess::exists(path)) { path = path.plus_file("Blender"); } @@ -468,7 +468,7 @@ bool EditorFileSystemImportFormatSupportQueryBlend::query() { // Autodetect auto_detected_path = ""; -#if defined(OSX_ENABLED) +#if defined(MACOS_ENABLED) { Vector<String> mdfind_paths; diff --git a/modules/gltf/gltf_light.cpp b/modules/gltf/extensions/gltf_light.cpp index af21a4e804..af21a4e804 100644 --- a/modules/gltf/gltf_light.cpp +++ b/modules/gltf/extensions/gltf_light.cpp diff --git a/modules/gltf/gltf_light.h b/modules/gltf/extensions/gltf_light.h index 25e0835a33..58fa299dfd 100644 --- a/modules/gltf/gltf_light.h +++ b/modules/gltf/extensions/gltf_light.h @@ -33,6 +33,7 @@ #include "core/config/engine.h" #include "core/io/resource.h" +#include "scene/3d/light_3d.h" class GLTFLight : public Resource { GDCLASS(GLTFLight, Resource) diff --git a/modules/gltf/gltf_spec_gloss.cpp b/modules/gltf/extensions/gltf_spec_gloss.cpp index 83af91bfcc..83af91bfcc 100644 --- a/modules/gltf/gltf_spec_gloss.cpp +++ b/modules/gltf/extensions/gltf_spec_gloss.cpp diff --git a/modules/gltf/gltf_spec_gloss.h b/modules/gltf/extensions/gltf_spec_gloss.h index f8a431bdce..a45fa4296c 100644 --- a/modules/gltf/gltf_spec_gloss.h +++ b/modules/gltf/extensions/gltf_spec_gloss.h @@ -64,4 +64,5 @@ public: Ref<Image> get_spec_gloss_img(); void set_spec_gloss_img(Ref<Image> p_spec_gloss_img); }; + #endif // GLTF_SPEC_GLOSS_H diff --git a/modules/gltf/gltf_defines.h b/modules/gltf/gltf_defines.h new file mode 100644 index 0000000000..c20c87f798 --- /dev/null +++ b/modules/gltf/gltf_defines.h @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* gltf_defines.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 GLTF_DEFINES_H +#define GLTF_DEFINES_H + +// This file should only be included by other headers. + +// Godot classes used by GLTF headers. +class BoneAttachment3D; +class CSGShape3D; +class DirectionalLight3D; +class GridMap; +class Light3D; +class MultiMeshInstance3D; +class Skeleton3D; +class Skin; + +// GLTF classes. +struct GLTFAccessor; +class GLTFAnimation; +class GLTFBufferView; +class GLTFCamera; +class GLTFDocument; +class GLTFDocumentExtension; +class GLTFLight; +class GLTFMesh; +class GLTFNode; +class GLTFSkeleton; +class GLTFSkin; +class GLTFSpecGloss; +class GLTFState; +class GLTFTexture; + +// GLTF index aliases. +using GLTFAccessorIndex = int; +using GLTFAnimationIndex = int; +using GLTFBufferIndex = int; +using GLTFBufferViewIndex = int; +using GLTFCameraIndex = int; +using GLTFImageIndex = int; +using GLTFMaterialIndex = int; +using GLTFMeshIndex = int; +using GLTFLightIndex = int; +using GLTFNodeIndex = int; +using GLTFSkeletonIndex = int; +using GLTFSkinIndex = int; +using GLTFTextureIndex = int; + +enum GLTFType { + TYPE_SCALAR, + TYPE_VEC2, + TYPE_VEC3, + TYPE_VEC4, + TYPE_MAT2, + TYPE_MAT3, + TYPE_MAT4, +}; + +#endif // GLTF_DEFINES_H diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index babdc9f33b..4ca8482ba3 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -30,19 +30,10 @@ #include "gltf_document.h" -#include "gltf_accessor.h" -#include "gltf_animation.h" -#include "gltf_camera.h" +#include "extensions/gltf_spec_gloss.h" #include "gltf_document_extension.h" #include "gltf_document_extension_convert_importer_mesh.h" -#include "gltf_light.h" -#include "gltf_mesh.h" -#include "gltf_node.h" -#include "gltf_skeleton.h" -#include "gltf_skin.h" -#include "gltf_spec_gloss.h" #include "gltf_state.h" -#include "gltf_texture.h" #include "core/crypto/crypto_core.h" #include "core/error/error_macros.h" @@ -230,15 +221,21 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) { } Error GLTFDocument::_serialize_extensions(Ref<GLTFState> state) const { - const String texture_transform = "KHR_texture_transform"; - const String punctual_lights = "KHR_lights_punctual"; Array extensions_used; - extensions_used.push_back(punctual_lights); - extensions_used.push_back(texture_transform); - state->json["extensionsUsed"] = extensions_used; Array extensions_required; - extensions_required.push_back(texture_transform); - state->json["extensionsRequired"] = extensions_required; + if (!state->lights.is_empty()) { + extensions_used.push_back("KHR_lights_punctual"); + } + if (state->use_khr_texture_transform) { + extensions_used.push_back("KHR_texture_transform"); + extensions_required.push_back("KHR_texture_transform"); + } + if (!extensions_used.is_empty()) { + state->json["extensionsUsed"] = extensions_used; + } + if (!extensions_required.is_empty()) { + state->json["extensionsRequired"] = extensions_required; + } return OK; } @@ -934,58 +931,58 @@ Error GLTFDocument::_encode_accessors(Ref<GLTFState> state) { return OK; } -String GLTFDocument::_get_accessor_type_name(const GLTFDocument::GLTFType p_type) { - if (p_type == GLTFDocument::TYPE_SCALAR) { +String GLTFDocument::_get_accessor_type_name(const GLTFType p_type) { + if (p_type == GLTFType::TYPE_SCALAR) { return "SCALAR"; } - if (p_type == GLTFDocument::TYPE_VEC2) { + if (p_type == GLTFType::TYPE_VEC2) { return "VEC2"; } - if (p_type == GLTFDocument::TYPE_VEC3) { + if (p_type == GLTFType::TYPE_VEC3) { return "VEC3"; } - if (p_type == GLTFDocument::TYPE_VEC4) { + if (p_type == GLTFType::TYPE_VEC4) { return "VEC4"; } - if (p_type == GLTFDocument::TYPE_MAT2) { + if (p_type == GLTFType::TYPE_MAT2) { return "MAT2"; } - if (p_type == GLTFDocument::TYPE_MAT3) { + if (p_type == GLTFType::TYPE_MAT3) { return "MAT3"; } - if (p_type == GLTFDocument::TYPE_MAT4) { + if (p_type == GLTFType::TYPE_MAT4) { return "MAT4"; } ERR_FAIL_V("SCALAR"); } -GLTFDocument::GLTFType GLTFDocument::_get_type_from_str(const String &p_string) { +GLTFType GLTFDocument::_get_type_from_str(const String &p_string) { if (p_string == "SCALAR") { - return GLTFDocument::TYPE_SCALAR; + return GLTFType::TYPE_SCALAR; } if (p_string == "VEC2") { - return GLTFDocument::TYPE_VEC2; + return GLTFType::TYPE_VEC2; } if (p_string == "VEC3") { - return GLTFDocument::TYPE_VEC3; + return GLTFType::TYPE_VEC3; } if (p_string == "VEC4") { - return GLTFDocument::TYPE_VEC4; + return GLTFType::TYPE_VEC4; } if (p_string == "MAT2") { - return GLTFDocument::TYPE_MAT2; + return GLTFType::TYPE_MAT2; } if (p_string == "MAT3") { - return GLTFDocument::TYPE_MAT3; + return GLTFType::TYPE_MAT3; } if (p_string == "MAT4") { - return GLTFDocument::TYPE_MAT4; + return GLTFType::TYPE_MAT4; } - ERR_FAIL_V(GLTFDocument::TYPE_SCALAR); + ERR_FAIL_V(GLTFType::TYPE_SCALAR); } Error GLTFDocument::_parse_accessors(Ref<GLTFState> state) { @@ -1536,7 +1533,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> state, c accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_SCALAR; + const GLTFType type = GLTFType::TYPE_SCALAR; const int component_type = GLTFDocument::COMPONENT_TYPE_INT; accessor->max = type_max; @@ -1620,7 +1617,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> state, c accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC2; + const GLTFType type = GLTFType::TYPE_VEC2; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1669,7 +1666,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> state, accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC4; + const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1734,7 +1731,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> state accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC4; + const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1781,7 +1778,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> state, accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC4; + const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; accessor->max = type_max; @@ -1830,7 +1827,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> s accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC4; + const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1895,7 +1892,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> state, accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_SCALAR; + const GLTFType type = GLTFType::TYPE_SCALAR; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1941,7 +1938,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> state, c accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC3; + const GLTFType type = GLTFType::TYPE_VEC3; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -2009,7 +2006,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> state, accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_MAT4; + const GLTFType type = GLTFType::TYPE_MAT4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -3305,7 +3302,11 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { } if (gltf_texture_index != -1) { bct["index"] = gltf_texture_index; - bct["extensions"] = _serialize_texture_transform_uv1(material); + Dictionary extensions = _serialize_texture_transform_uv1(material); + if (!extensions.is_empty()) { + bct["extensions"] = extensions; + state->use_khr_texture_transform = true; + } mr["baseColorTexture"] = bct; } } @@ -3436,7 +3437,11 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { } if (has_roughness || has_metalness) { mrt["index"] = orm_texture_index; - mrt["extensions"] = _serialize_texture_transform_uv1(material); + Dictionary extensions = _serialize_texture_transform_uv1(material); + if (!extensions.is_empty()) { + mrt["extensions"] = extensions; + state->use_khr_texture_transform = true; + } mr["metallicRoughnessTexture"] = mrt; } } @@ -4525,6 +4530,9 @@ void GLTFDocument::_remove_duplicate_skins(Ref<GLTFState> state) { } Error GLTFDocument::_serialize_lights(Ref<GLTFState> state) { + if (state->lights.is_empty()) { + return OK; + } Array lights; for (GLTFLightIndex i = 0; i < state->lights.size(); i++) { Dictionary d; @@ -4551,10 +4559,6 @@ Error GLTFDocument::_serialize_lights(Ref<GLTFState> state) { lights.push_back(d); } - if (!state->lights.size()) { - return OK; - } - Dictionary extensions; if (state->json.has("extensions")) { extensions = state->json["extensions"]; @@ -5214,7 +5218,7 @@ GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> state, Camera3D *p_ Ref<GLTFCamera> c; c.instantiate(); - if (p_camera->get_projection() == Camera3D::Projection::PROJECTION_PERSPECTIVE) { + if (p_camera->get_projection() == Camera3D::ProjectionType::PROJECTION_PERSPECTIVE) { c->set_perspective(true); } c->set_fov_size(p_camera->get_fov()); @@ -6651,45 +6655,48 @@ Error GLTFDocument::_parse(Ref<GLTFState> state, String p_path, Ref<FileAccess> return OK; } -Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) { - Dictionary extension; - Ref<BaseMaterial3D> mat = p_material; - if (mat.is_valid()) { - Dictionary texture_transform; +Dictionary _serialize_texture_transform_uv(Vector2 p_offset, Vector2 p_scale) { + Dictionary texture_transform; + bool is_offset = p_offset != Vector2(0.0, 0.0); + if (is_offset) { Array offset; offset.resize(2); - offset[0] = mat->get_uv2_offset().x; - offset[1] = mat->get_uv2_offset().y; + offset[0] = p_offset.x; + offset[1] = p_offset.y; texture_transform["offset"] = offset; + } + bool is_scaled = p_scale != Vector2(1.0, 1.0); + if (is_scaled) { Array scale; scale.resize(2); - scale[0] = mat->get_uv2_scale().x; - scale[1] = mat->get_uv2_scale().y; + scale[0] = p_scale.x; + scale[1] = p_scale.y; texture_transform["scale"] = scale; - // Godot doesn't support texture rotation + } + Dictionary extension; + // Note: Godot doesn't support texture rotation. + if (is_offset || is_scaled) { extension["KHR_texture_transform"] = texture_transform; } return extension; } Dictionary GLTFDocument::_serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material) { - Dictionary extension; if (p_material.is_valid()) { - Dictionary texture_transform; - Array offset; - offset.resize(2); - offset[0] = p_material->get_uv1_offset().x; - offset[1] = p_material->get_uv1_offset().y; - texture_transform["offset"] = offset; - Array scale; - scale.resize(2); - scale[0] = p_material->get_uv1_scale().x; - scale[1] = p_material->get_uv1_scale().y; - texture_transform["scale"] = scale; - // Godot doesn't support texture rotation - extension["KHR_texture_transform"] = texture_transform; + Vector3 offset = p_material->get_uv1_offset(); + Vector3 scale = p_material->get_uv1_scale(); + return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y)); } - return extension; + return Dictionary(); +} + +Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) { + if (p_material.is_valid()) { + Vector3 offset = p_material->get_uv2_offset(); + Vector3 scale = p_material->get_uv2_scale(); + return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y)); + } + return Dictionary(); } Error GLTFDocument::_serialize_version(Ref<GLTFState> state) { @@ -6929,15 +6936,6 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> state, uint32 state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS; state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS; - _convert_scene_node(state, p_node, -1, -1); - if (!state->buffers.size()) { - state->buffers.push_back(Vector<uint8_t>()); - } - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; - ERR_CONTINUE(ext.is_null()); - } - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; ERR_CONTINUE(ext.is_null()); @@ -6948,7 +6946,6 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> state, uint32 if (!state->buffers.size()) { state->buffers.push_back(Vector<uint8_t>()); } - return OK; } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 2f61210ff9..36a2f94a4e 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -31,48 +31,19 @@ #ifndef GLTF_DOCUMENT_H #define GLTF_DOCUMENT_H -#include "gltf_animation.h" +#include "gltf_defines.h" +#include "structures/gltf_animation.h" #include "scene/3d/bone_attachment_3d.h" #include "scene/3d/importer_mesh_instance_3d.h" -#include "scene/3d/light_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/animation/animation_player.h" #include "scene/resources/material.h" #include "modules/modules_enabled.gen.h" // For csg, gridmap. -#include <cstdint> - -class GLTFState; -class GLTFSkin; -class GLTFNode; -class GLTFSpecGloss; -class GLTFSkeleton; -class CSGShape3D; -class GridMap; -class MultiMeshInstance3D; -class GLTFDocumentExtension; - -using GLTFAccessorIndex = int; -using GLTFAnimationIndex = int; -using GLTFBufferIndex = int; -using GLTFBufferViewIndex = int; -using GLTFCameraIndex = int; -using GLTFImageIndex = int; -using GLTFMaterialIndex = int; -using GLTFMeshIndex = int; -using GLTFLightIndex = int; -using GLTFNodeIndex = int; -using GLTFSkeletonIndex = int; -using GLTFSkinIndex = int; -using GLTFTextureIndex = int; - class GLTFDocument : public Resource { GDCLASS(GLTFDocument, Resource); - friend class GLTFState; - friend class GLTFSkin; - friend class GLTFSkeleton; TypedArray<GLTFDocumentExtension> document_extensions; private: @@ -81,15 +52,6 @@ private: public: GLTFDocument(); const int32_t JOINT_GROUP_SIZE = 4; - enum GLTFType { - TYPE_SCALAR, - TYPE_VEC2, - TYPE_VEC3, - TYPE_VEC4, - TYPE_MAT2, - TYPE_MAT3, - TYPE_MAT4, - }; enum { ARRAY_BUFFER = 34962, @@ -118,58 +80,6 @@ public: TypedArray<GLTFDocumentExtension> get_extensions() const; private: - template <class T> - static Array to_array(const Vector<T> &p_inp) { - Array ret; - for (int i = 0; i < p_inp.size(); i++) { - ret.push_back(p_inp[i]); - } - return ret; - } - - template <class T> - static Array to_array(const HashSet<T> &p_inp) { - Array ret; - typename HashSet<T>::Iterator elem = p_inp.begin(); - while (elem) { - ret.push_back(*elem); - ++elem; - } - return ret; - } - - template <class T> - static void set_from_array(Vector<T> &r_out, const Array &p_inp) { - r_out.clear(); - for (int i = 0; i < p_inp.size(); i++) { - r_out.push_back(p_inp[i]); - } - } - - template <class T> - static void set_from_array(HashSet<T> &r_out, const Array &p_inp) { - r_out.clear(); - for (int i = 0; i < p_inp.size(); i++) { - r_out.insert(p_inp[i]); - } - } - template <class K, class V> - static Dictionary to_dict(const HashMap<K, V> &p_inp) { - Dictionary ret; - for (const KeyValue<K, V> &E : p_inp) { - ret[E.key] = E.value; - } - return ret; - } - - template <class K, class V> - static void set_from_dict(HashMap<K, V> &r_out, const Dictionary &p_inp) { - r_out.clear(); - Array keys = p_inp.keys(); - for (int i = 0; i < keys.size(); i++) { - r_out[keys[i]] = p_inp[keys[i]]; - } - } void _build_parent_hierachy(Ref<GLTFState> state); double _filter_number(double p_float); String _get_component_type_name(const uint32_t p_component); @@ -177,7 +87,7 @@ private: Error _parse_scenes(Ref<GLTFState> state); Error _parse_nodes(Ref<GLTFState> state); String _get_type_name(const GLTFType p_component); - String _get_accessor_type_name(const GLTFDocument::GLTFType p_type); + String _get_accessor_type_name(const GLTFType p_type); String _gen_unique_name(Ref<GLTFState> state, const String &p_name); String _sanitize_animation_name(const String &name); String _gen_unique_animation_name(Ref<GLTFState> state, const String &p_name); diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/gltf_document_extension.h index 556f79e887..0ef9109584 100644 --- a/modules/gltf/gltf_document_extension.h +++ b/modules/gltf/gltf_document_extension.h @@ -31,9 +31,8 @@ #ifndef GLTF_DOCUMENT_EXTENSION_H #define GLTF_DOCUMENT_EXTENSION_H -#include "gltf_accessor.h" -#include "gltf_node.h" #include "gltf_state.h" +#include "structures/gltf_node.h" class GLTFDocumentExtension : public Resource { GDCLASS(GLTFDocumentExtension, Resource); diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.h b/modules/gltf/gltf_document_extension_convert_importer_mesh.h index 4c9e42a00f..00e664e73f 100644 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.h +++ b/modules/gltf/gltf_document_extension_convert_importer_mesh.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GLTF_EXTENSION_EDITOR_H -#define GLTF_EXTENSION_EDITOR_H +#ifndef GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H +#define GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H #include "gltf_document_extension.h" @@ -37,8 +37,6 @@ #include "scene/3d/mesh_instance_3d.h" #include "scene/resources/importer_mesh.h" -class GLTFDocumentExtension; -class GLTFDocument; class GLTFDocumentExtensionConvertImporterMesh : public GLTFDocumentExtension { GDCLASS(GLTFDocumentExtensionConvertImporterMesh, GLTFDocumentExtension); @@ -48,4 +46,5 @@ protected: public: Error import_post(Ref<GLTFState> p_state, Node *p_root) override; }; -#endif // GLTF_EXTENSION_EDITOR_H + +#endif // GLTF_DOCUMENT_EXTENSION_CONVERT_IMPORTER_MESH_H diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index 989fa476c2..a5f7bcf9d6 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -150,51 +150,51 @@ void GLTFState::set_use_named_skin_binds(bool p_use_named_skin_binds) { } Array GLTFState::get_nodes() { - return GLTFDocument::to_array(nodes); + return GLTFTemplateConvert::to_array(nodes); } void GLTFState::set_nodes(Array p_nodes) { - GLTFDocument::set_from_array(nodes, p_nodes); + GLTFTemplateConvert::set_from_array(nodes, p_nodes); } Array GLTFState::get_buffers() { - return GLTFDocument::to_array(buffers); + return GLTFTemplateConvert::to_array(buffers); } void GLTFState::set_buffers(Array p_buffers) { - GLTFDocument::set_from_array(buffers, p_buffers); + GLTFTemplateConvert::set_from_array(buffers, p_buffers); } Array GLTFState::get_buffer_views() { - return GLTFDocument::to_array(buffer_views); + return GLTFTemplateConvert::to_array(buffer_views); } void GLTFState::set_buffer_views(Array p_buffer_views) { - GLTFDocument::set_from_array(buffer_views, p_buffer_views); + GLTFTemplateConvert::set_from_array(buffer_views, p_buffer_views); } Array GLTFState::get_accessors() { - return GLTFDocument::to_array(accessors); + return GLTFTemplateConvert::to_array(accessors); } void GLTFState::set_accessors(Array p_accessors) { - GLTFDocument::set_from_array(accessors, p_accessors); + GLTFTemplateConvert::set_from_array(accessors, p_accessors); } Array GLTFState::get_meshes() { - return GLTFDocument::to_array(meshes); + return GLTFTemplateConvert::to_array(meshes); } void GLTFState::set_meshes(Array p_meshes) { - GLTFDocument::set_from_array(meshes, p_meshes); + GLTFTemplateConvert::set_from_array(meshes, p_meshes); } Array GLTFState::get_materials() { - return GLTFDocument::to_array(materials); + return GLTFTemplateConvert::to_array(materials); } void GLTFState::set_materials(Array p_materials) { - GLTFDocument::set_from_array(materials, p_materials); + GLTFTemplateConvert::set_from_array(materials, p_materials); } String GLTFState::get_scene_name() { @@ -206,91 +206,91 @@ void GLTFState::set_scene_name(String p_scene_name) { } Array GLTFState::get_root_nodes() { - return GLTFDocument::to_array(root_nodes); + return GLTFTemplateConvert::to_array(root_nodes); } void GLTFState::set_root_nodes(Array p_root_nodes) { - GLTFDocument::set_from_array(root_nodes, p_root_nodes); + GLTFTemplateConvert::set_from_array(root_nodes, p_root_nodes); } Array GLTFState::get_textures() { - return GLTFDocument::to_array(textures); + return GLTFTemplateConvert::to_array(textures); } void GLTFState::set_textures(Array p_textures) { - GLTFDocument::set_from_array(textures, p_textures); + GLTFTemplateConvert::set_from_array(textures, p_textures); } Array GLTFState::get_images() { - return GLTFDocument::to_array(images); + return GLTFTemplateConvert::to_array(images); } void GLTFState::set_images(Array p_images) { - GLTFDocument::set_from_array(images, p_images); + GLTFTemplateConvert::set_from_array(images, p_images); } Array GLTFState::get_skins() { - return GLTFDocument::to_array(skins); + return GLTFTemplateConvert::to_array(skins); } void GLTFState::set_skins(Array p_skins) { - GLTFDocument::set_from_array(skins, p_skins); + GLTFTemplateConvert::set_from_array(skins, p_skins); } Array GLTFState::get_cameras() { - return GLTFDocument::to_array(cameras); + return GLTFTemplateConvert::to_array(cameras); } void GLTFState::set_cameras(Array p_cameras) { - GLTFDocument::set_from_array(cameras, p_cameras); + GLTFTemplateConvert::set_from_array(cameras, p_cameras); } Array GLTFState::get_lights() { - return GLTFDocument::to_array(lights); + return GLTFTemplateConvert::to_array(lights); } void GLTFState::set_lights(Array p_lights) { - GLTFDocument::set_from_array(lights, p_lights); + GLTFTemplateConvert::set_from_array(lights, p_lights); } Array GLTFState::get_unique_names() { - return GLTFDocument::to_array(unique_names); + return GLTFTemplateConvert::to_array(unique_names); } void GLTFState::set_unique_names(Array p_unique_names) { - GLTFDocument::set_from_array(unique_names, p_unique_names); + GLTFTemplateConvert::set_from_array(unique_names, p_unique_names); } Array GLTFState::get_unique_animation_names() { - return GLTFDocument::to_array(unique_animation_names); + return GLTFTemplateConvert::to_array(unique_animation_names); } void GLTFState::set_unique_animation_names(Array p_unique_animation_names) { - GLTFDocument::set_from_array(unique_animation_names, p_unique_animation_names); + GLTFTemplateConvert::set_from_array(unique_animation_names, p_unique_animation_names); } Array GLTFState::get_skeletons() { - return GLTFDocument::to_array(skeletons); + return GLTFTemplateConvert::to_array(skeletons); } void GLTFState::set_skeletons(Array p_skeletons) { - GLTFDocument::set_from_array(skeletons, p_skeletons); + GLTFTemplateConvert::set_from_array(skeletons, p_skeletons); } Dictionary GLTFState::get_skeleton_to_node() { - return GLTFDocument::to_dict(skeleton_to_node); + return GLTFTemplateConvert::to_dict(skeleton_to_node); } void GLTFState::set_skeleton_to_node(Dictionary p_skeleton_to_node) { - GLTFDocument::set_from_dict(skeleton_to_node, p_skeleton_to_node); + GLTFTemplateConvert::set_from_dict(skeleton_to_node, p_skeleton_to_node); } Array GLTFState::get_animations() { - return GLTFDocument::to_array(animations); + return GLTFTemplateConvert::to_array(animations); } void GLTFState::set_animations(Array p_animations) { - GLTFDocument::set_from_array(animations, p_animations); + GLTFTemplateConvert::set_from_array(animations, p_animations); } Node *GLTFState::get_scene_node(GLTFNodeIndex idx) { diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 2fdef19038..d2a4948f06 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -31,18 +31,17 @@ #ifndef GLTF_STATE_H #define GLTF_STATE_H -#include "gltf_accessor.h" -#include "gltf_animation.h" -#include "gltf_buffer_view.h" -#include "gltf_camera.h" -#include "gltf_document.h" -#include "gltf_document_extension.h" -#include "gltf_light.h" -#include "gltf_mesh.h" -#include "gltf_node.h" -#include "gltf_skeleton.h" -#include "gltf_skin.h" -#include "gltf_texture.h" +#include "extensions/gltf_light.h" +#include "gltf_template_convert.h" +#include "structures/gltf_accessor.h" +#include "structures/gltf_animation.h" +#include "structures/gltf_buffer_view.h" +#include "structures/gltf_camera.h" +#include "structures/gltf_mesh.h" +#include "structures/gltf_node.h" +#include "structures/gltf_skeleton.h" +#include "structures/gltf_skin.h" +#include "structures/gltf_texture.h" #include "core/templates/rb_map.h" #include "scene/animation/animation_player.h" @@ -60,6 +59,7 @@ class GLTFState : public Resource { Vector<uint8_t> glb_data; bool use_named_skin_binds = false; + bool use_khr_texture_transform = false; bool discard_meshes_and_materials = false; Vector<Ref<GLTFNode>> nodes; @@ -192,4 +192,5 @@ public: // this->material_cache = p_material_cache; //} }; + #endif // GLTF_STATE_H diff --git a/modules/gltf/gltf_template_convert.h b/modules/gltf/gltf_template_convert.h new file mode 100644 index 0000000000..c915d3deb0 --- /dev/null +++ b/modules/gltf/gltf_template_convert.h @@ -0,0 +1,94 @@ +/*************************************************************************/ +/* gltf_template_convert.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 GLTF_TEMPLATE_CONVERT_H +#define GLTF_TEMPLATE_CONVERT_H + +#include "core/templates/hash_set.h" +#include "core/variant/array.h" +#include "core/variant/dictionary.h" + +namespace GLTFTemplateConvert { +template <class T> +static Array to_array(const Vector<T> &p_inp) { + Array ret; + for (int i = 0; i < p_inp.size(); i++) { + ret.push_back(p_inp[i]); + } + return ret; +} + +template <class T> +static Array to_array(const HashSet<T> &p_inp) { + Array ret; + typename HashSet<T>::Iterator elem = p_inp.begin(); + while (elem) { + ret.push_back(*elem); + ++elem; + } + return ret; +} + +template <class T> +static void set_from_array(Vector<T> &r_out, const Array &p_inp) { + r_out.clear(); + for (int i = 0; i < p_inp.size(); i++) { + r_out.push_back(p_inp[i]); + } +} + +template <class T> +static void set_from_array(HashSet<T> &r_out, const Array &p_inp) { + r_out.clear(); + for (int i = 0; i < p_inp.size(); i++) { + r_out.insert(p_inp[i]); + } +} + +template <class K, class V> +static Dictionary to_dict(const HashMap<K, V> &p_inp) { + Dictionary ret; + for (const KeyValue<K, V> &E : p_inp) { + ret[E.key] = E.value; + } + return ret; +} + +template <class K, class V> +static void set_from_dict(HashMap<K, V> &r_out, const Dictionary &p_inp) { + r_out.clear(); + Array keys = p_inp.keys(); + for (int i = 0; i < keys.size(); i++) { + r_out[keys[i]] = p_inp[keys[i]]; + } +} +} //namespace GLTFTemplateConvert + +#endif // GLTF_TEMPLATE_CONVERT_H diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index b8bac79584..1e1204aa57 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -32,21 +32,21 @@ #ifndef _3D_DISABLED -#include "gltf_accessor.h" -#include "gltf_animation.h" -#include "gltf_buffer_view.h" -#include "gltf_camera.h" +#include "extensions/gltf_light.h" +#include "extensions/gltf_spec_gloss.h" #include "gltf_document.h" #include "gltf_document_extension.h" #include "gltf_document_extension_convert_importer_mesh.h" -#include "gltf_light.h" -#include "gltf_mesh.h" -#include "gltf_node.h" -#include "gltf_skeleton.h" -#include "gltf_skin.h" -#include "gltf_spec_gloss.h" #include "gltf_state.h" -#include "gltf_texture.h" +#include "structures/gltf_accessor.h" +#include "structures/gltf_animation.h" +#include "structures/gltf_buffer_view.h" +#include "structures/gltf_camera.h" +#include "structures/gltf_mesh.h" +#include "structures/gltf_node.h" +#include "structures/gltf_skeleton.h" +#include "structures/gltf_skin.h" +#include "structures/gltf_texture.h" #ifdef TOOLS_ENABLED #include "core/config/project_settings.h" diff --git a/modules/gltf/gltf_accessor.cpp b/modules/gltf/structures/gltf_accessor.cpp index 1daf2f90a7..1b8911fe72 100644 --- a/modules/gltf/gltf_accessor.cpp +++ b/modules/gltf/structures/gltf_accessor.cpp @@ -30,8 +30,6 @@ #include "gltf_accessor.h" -#include "gltf_document_extension.h" - void GLTFAccessor::_bind_methods() { ClassDB::bind_method(D_METHOD("get_buffer_view"), &GLTFAccessor::get_buffer_view); ClassDB::bind_method(D_METHOD("set_buffer_view", "buffer_view"), &GLTFAccessor::set_buffer_view); @@ -67,7 +65,7 @@ void GLTFAccessor::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "component_type"), "set_component_type", "get_component_type"); // int ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalized"), "set_normalized", "get_normalized"); // bool ADD_PROPERTY(PropertyInfo(Variant::INT, "count"), "set_count", "get_count"); // int - ADD_PROPERTY(PropertyInfo(Variant::INT, "type"), "set_type", "get_type"); // GLTFDocument::GLTFType + ADD_PROPERTY(PropertyInfo(Variant::INT, "type"), "set_type", "get_type"); // GLTFType ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT64_ARRAY, "min"), "set_min", "get_min"); // Vector<real_t> ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT64_ARRAY, "max"), "set_max", "get_max"); // Vector<real_t> ADD_PROPERTY(PropertyInfo(Variant::INT, "sparse_count"), "set_sparse_count", "get_sparse_count"); // int @@ -123,7 +121,7 @@ int GLTFAccessor::get_type() { } void GLTFAccessor::set_type(int p_type) { - type = (GLTFDocument::GLTFType)p_type; // TODO: Register enum + type = (GLTFType)p_type; // TODO: Register enum } Vector<double> GLTFAccessor::get_min() { diff --git a/modules/gltf/gltf_accessor.h b/modules/gltf/structures/gltf_accessor.h index f412dc2c7f..bfb71d57fe 100644 --- a/modules/gltf/gltf_accessor.h +++ b/modules/gltf/structures/gltf_accessor.h @@ -33,7 +33,7 @@ #include "core/io/resource.h" -#include "gltf_document.h" +#include "../gltf_defines.h" struct GLTFAccessor : public Resource { GDCLASS(GLTFAccessor, Resource); @@ -45,7 +45,7 @@ private: int component_type = 0; bool normalized = false; int count = 0; - GLTFDocument::GLTFType type = GLTFDocument::TYPE_SCALAR; + GLTFType type = GLTFType::TYPE_SCALAR; Vector<double> min; Vector<double> max; int sparse_count = 0; @@ -101,4 +101,5 @@ public: int get_sparse_values_byte_offset(); void set_sparse_values_byte_offset(int p_sparse_values_byte_offset); }; + #endif // GLTF_ACCESSOR_H diff --git a/modules/gltf/gltf_animation.cpp b/modules/gltf/structures/gltf_animation.cpp index e598c870ab..e598c870ab 100644 --- a/modules/gltf/gltf_animation.cpp +++ b/modules/gltf/structures/gltf_animation.cpp diff --git a/modules/gltf/gltf_animation.h b/modules/gltf/structures/gltf_animation.h index 8688ddb937..3777f579f6 100644 --- a/modules/gltf/gltf_animation.h +++ b/modules/gltf/structures/gltf_animation.h @@ -71,4 +71,5 @@ private: bool loop = false; HashMap<int, Track> tracks; }; + #endif // GLTF_ANIMATION_H diff --git a/modules/gltf/gltf_buffer_view.cpp b/modules/gltf/structures/gltf_buffer_view.cpp index fc467367c6..ba19ed8628 100644 --- a/modules/gltf/gltf_buffer_view.cpp +++ b/modules/gltf/structures/gltf_buffer_view.cpp @@ -30,7 +30,7 @@ #include "gltf_buffer_view.h" -#include "gltf_document_extension.h" +#include "../gltf_document_extension.h" void GLTFBufferView::_bind_methods() { ClassDB::bind_method(D_METHOD("get_buffer"), &GLTFBufferView::get_buffer); diff --git a/modules/gltf/gltf_buffer_view.h b/modules/gltf/structures/gltf_buffer_view.h index 560d56f35c..b1f500de25 100644 --- a/modules/gltf/gltf_buffer_view.h +++ b/modules/gltf/structures/gltf_buffer_view.h @@ -31,8 +31,8 @@ #ifndef GLTF_BUFFER_VIEW_H #define GLTF_BUFFER_VIEW_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFBufferView : public Resource { GDCLASS(GLTFBufferView, Resource); @@ -65,4 +65,5 @@ public: void set_indices(bool p_indices); // matrices need to be transformed to this }; + #endif // GLTF_BUFFER_VIEW_H diff --git a/modules/gltf/gltf_camera.cpp b/modules/gltf/structures/gltf_camera.cpp index f3ea6a1c4c..f3ea6a1c4c 100644 --- a/modules/gltf/gltf_camera.cpp +++ b/modules/gltf/structures/gltf_camera.cpp diff --git a/modules/gltf/gltf_camera.h b/modules/gltf/structures/gltf_camera.h index c696d4cc6b..b7df741825 100644 --- a/modules/gltf/gltf_camera.h +++ b/modules/gltf/structures/gltf_camera.h @@ -55,4 +55,5 @@ public: float get_depth_near() const { return depth_near; } void set_depth_near(float p_val) { depth_near = p_val; } }; + #endif // GLTF_CAMERA_H diff --git a/modules/gltf/gltf_mesh.cpp b/modules/gltf/structures/gltf_mesh.cpp index 3add8304b1..3add8304b1 100644 --- a/modules/gltf/gltf_mesh.cpp +++ b/modules/gltf/structures/gltf_mesh.cpp diff --git a/modules/gltf/gltf_mesh.h b/modules/gltf/structures/gltf_mesh.h index dc26120b48..dc26120b48 100644 --- a/modules/gltf/gltf_mesh.h +++ b/modules/gltf/structures/gltf_mesh.h diff --git a/modules/gltf/gltf_node.cpp b/modules/gltf/structures/gltf_node.cpp index 86280603fa..86280603fa 100644 --- a/modules/gltf/gltf_node.cpp +++ b/modules/gltf/structures/gltf_node.cpp diff --git a/modules/gltf/gltf_node.h b/modules/gltf/structures/gltf_node.h index 929ad3eca0..1a57ea32e2 100644 --- a/modules/gltf/gltf_node.h +++ b/modules/gltf/structures/gltf_node.h @@ -31,8 +31,8 @@ #ifndef GLTF_NODE_H #define GLTF_NODE_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFNode : public Resource { GDCLASS(GLTFNode, Resource); @@ -97,4 +97,5 @@ public: GLTFLightIndex get_light(); void set_light(GLTFLightIndex p_light); }; + #endif // GLTF_NODE_H diff --git a/modules/gltf/gltf_skeleton.cpp b/modules/gltf/structures/gltf_skeleton.cpp index b813f39a27..90a6b0f50f 100644 --- a/modules/gltf/gltf_skeleton.cpp +++ b/modules/gltf/structures/gltf_skeleton.cpp @@ -30,6 +30,9 @@ #include "gltf_skeleton.h" +#include "../gltf_template_convert.h" +#include "scene/3d/bone_attachment_3d.h" + void GLTFSkeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_joints"), &GLTFSkeleton::get_joints); ClassDB::bind_method(D_METHOD("set_joints", "joints"), &GLTFSkeleton::set_joints); @@ -70,19 +73,19 @@ Skeleton3D *GLTFSkeleton::get_godot_skeleton() { } Array GLTFSkeleton::get_unique_names() { - return GLTFDocument::to_array(unique_names); + return GLTFTemplateConvert::to_array(unique_names); } void GLTFSkeleton::set_unique_names(Array p_unique_names) { - GLTFDocument::set_from_array(unique_names, p_unique_names); + GLTFTemplateConvert::set_from_array(unique_names, p_unique_names); } Dictionary GLTFSkeleton::get_godot_bone_node() { - return GLTFDocument::to_dict(godot_bone_node); + return GLTFTemplateConvert::to_dict(godot_bone_node); } void GLTFSkeleton::set_godot_bone_node(Dictionary p_indict) { - GLTFDocument::set_from_dict(godot_bone_node, p_indict); + GLTFTemplateConvert::set_from_dict(godot_bone_node, p_indict); } BoneAttachment3D *GLTFSkeleton::get_bone_attachment(int idx) { diff --git a/modules/gltf/gltf_skeleton.h b/modules/gltf/structures/gltf_skeleton.h index 92ee6e6234..db88623213 100644 --- a/modules/gltf/gltf_skeleton.h +++ b/modules/gltf/structures/gltf_skeleton.h @@ -31,8 +31,8 @@ #ifndef GLTF_SKELETON_H #define GLTF_SKELETON_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFSkeleton : public Resource { GDCLASS(GLTFSkeleton, Resource); @@ -98,4 +98,5 @@ public: int32_t get_bone_attachment_count(); }; + #endif // GLTF_SKELETON_H diff --git a/modules/gltf/gltf_skin.cpp b/modules/gltf/structures/gltf_skin.cpp index e8005aa0c1..2e46ee3be2 100644 --- a/modules/gltf/gltf_skin.cpp +++ b/modules/gltf/structures/gltf_skin.cpp @@ -30,6 +30,9 @@ #include "gltf_skin.h" +#include "../gltf_template_convert.h" +#include "scene/resources/skin.h" + void GLTFSkin::_bind_methods() { ClassDB::bind_method(D_METHOD("get_skin_root"), &GLTFSkin::get_skin_root); ClassDB::bind_method(D_METHOD("set_skin_root", "skin_root"), &GLTFSkin::set_skin_root); @@ -81,11 +84,11 @@ void GLTFSkin::set_joints_original(Vector<GLTFNodeIndex> p_joints_original) { } Array GLTFSkin::get_inverse_binds() { - return GLTFDocument::to_array(inverse_binds); + return GLTFTemplateConvert::to_array(inverse_binds); } void GLTFSkin::set_inverse_binds(Array p_inverse_binds) { - GLTFDocument::set_from_array(inverse_binds, p_inverse_binds); + GLTFTemplateConvert::set_from_array(inverse_binds, p_inverse_binds); } Vector<GLTFNodeIndex> GLTFSkin::get_joints() { @@ -121,11 +124,11 @@ void GLTFSkin::set_skeleton(int p_skeleton) { } Dictionary GLTFSkin::get_joint_i_to_bone_i() { - return GLTFDocument::to_dict(joint_i_to_bone_i); + return GLTFTemplateConvert::to_dict(joint_i_to_bone_i); } void GLTFSkin::set_joint_i_to_bone_i(Dictionary p_joint_i_to_bone_i) { - GLTFDocument::set_from_dict(joint_i_to_bone_i, p_joint_i_to_bone_i); + GLTFTemplateConvert::set_from_dict(joint_i_to_bone_i, p_joint_i_to_bone_i); } Dictionary GLTFSkin::get_joint_i_to_name() { diff --git a/modules/gltf/gltf_skin.h b/modules/gltf/structures/gltf_skin.h index d946324756..59b6a300ac 100644 --- a/modules/gltf/gltf_skin.h +++ b/modules/gltf/structures/gltf_skin.h @@ -31,8 +31,8 @@ #ifndef GLTF_SKIN_H #define GLTF_SKIN_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFSkin : public Resource { GDCLASS(GLTFSkin, Resource); @@ -106,4 +106,5 @@ public: Ref<Skin> get_godot_skin(); void set_godot_skin(Ref<Skin> p_godot_skin); }; + #endif // GLTF_SKIN_H diff --git a/modules/gltf/gltf_texture.cpp b/modules/gltf/structures/gltf_texture.cpp index 2a21cb3df8..2a21cb3df8 100644 --- a/modules/gltf/gltf_texture.cpp +++ b/modules/gltf/structures/gltf_texture.cpp diff --git a/modules/gltf/gltf_texture.h b/modules/gltf/structures/gltf_texture.h index 54dd61f9a5..b1d12dddfa 100644 --- a/modules/gltf/gltf_texture.h +++ b/modules/gltf/structures/gltf_texture.h @@ -31,8 +31,8 @@ #ifndef GLTF_TEXTURE_H #define GLTF_TEXTURE_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFTexture : public Resource { GDCLASS(GLTFTexture, Resource); diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index f975d95079..fe4edf112b 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -545,7 +545,7 @@ void GridMapEditor::_update_paste_indicator() { Basis rot; rot.set_orthogonal_index(paste_indicator.orientation); xf.basis = rot * xf.basis; - xf.translate((-center * node->get_cell_size()) / scale); + xf.translate_local((-center * node->get_cell_size()) / scale); RenderingServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf); @@ -553,7 +553,7 @@ void GridMapEditor::_update_paste_indicator() { xf = Transform3D(); xf.origin = (paste_indicator.begin + (paste_indicator.current - paste_indicator.click) + center) * node->get_cell_size(); xf.basis = rot * xf.basis; - xf.translate(item.grid_offset * node->get_cell_size()); + xf.translate_local(item.grid_offset * node->get_cell_size()); Basis item_rot; item_rot.set_orthogonal_index(item.orientation); diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h index f2d53cc206..16c0816562 100644 --- a/modules/hdr/image_loader_hdr.h +++ b/modules/hdr/image_loader_hdr.h @@ -40,4 +40,4 @@ public: ImageLoaderHDR(); }; -#endif +#endif // IMAGE_LOADER_HDR_H diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h index de9700faec..6d631446e7 100644 --- a/modules/jpg/image_loader_jpegd.h +++ b/modules/jpg/image_loader_jpegd.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef IMAGE_LOADER_JPG_H -#define IMAGE_LOADER_JPG_H +#ifndef IMAGE_LOADER_JPEGD_H +#define IMAGE_LOADER_JPEGD_H #include "core/io/image_loader.h" @@ -40,4 +40,4 @@ public: ImageLoaderJPG(); }; -#endif +#endif // IMAGE_LOADER_JPEGD_H diff --git a/modules/jsonrpc/jsonrpc.h b/modules/jsonrpc/jsonrpc.h index f57d6aef42..1d9f2771b2 100644 --- a/modules/jsonrpc/jsonrpc.h +++ b/modules/jsonrpc/jsonrpc.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_JSON_RPC_H -#define GODOT_JSON_RPC_H +#ifndef JSONRPC_H +#define JSONRPC_H #include "core/object/class_db.h" #include "core/variant/variant.h" @@ -67,4 +67,4 @@ public: VARIANT_ENUM_CAST(JSONRPC::ErrorCode); -#endif +#endif // JSONRPC_H diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index 8cb4b58a18..88860ad0d4 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -256,4 +256,4 @@ public: LightmapperRD(); }; -#endif // LIGHTMAPPER_H +#endif // LIGHTMAPPER_RD_H diff --git a/modules/lightmapper_rd/register_types.h b/modules/lightmapper_rd/register_types.h index 42e0ebbf77..9b72ff45d7 100644 --- a/modules/lightmapper_rd/register_types.h +++ b/modules/lightmapper_rd/register_types.h @@ -36,4 +36,4 @@ void initialize_lightmapper_rd_module(ModuleInitializationLevel p_level); void uninitialize_lightmapper_rd_module(ModuleInitializationLevel p_level); -#endif // XATLAS_UNWRAP_REGISTER_TYPES_H +#endif // LIGHTMAPPER_RD_REGISTER_TYPES_H diff --git a/modules/mbedtls/dtls_server_mbedtls.h b/modules/mbedtls/dtls_server_mbedtls.h index 29370062c4..a6626c9f65 100644 --- a/modules/mbedtls/dtls_server_mbedtls.h +++ b/modules/mbedtls/dtls_server_mbedtls.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef MBED_DTLS_SERVER_H -#define MBED_DTLS_SERVER_H +#ifndef DTLS_SERVER_MBEDTLS_H +#define DTLS_SERVER_MBEDTLS_H #include "core/io/dtls_server.h" #include "ssl_context_mbedtls.h" @@ -54,4 +54,4 @@ public: ~DTLSServerMbedTLS(); }; -#endif // MBED_DTLS_SERVER_H +#endif // DTLS_SERVER_MBEDTLS_H diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h index dd49792abd..5883388311 100644 --- a/modules/mbedtls/ssl_context_mbedtls.h +++ b/modules/mbedtls/ssl_context_mbedtls.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SSL_CONTEXT_MBED_TLS_H -#define SSL_CONTEXT_MBED_TLS_H +#ifndef SSL_CONTEXT_MBEDTLS_H +#define SSL_CONTEXT_MBEDTLS_H #include "crypto_mbedtls.h" @@ -90,4 +90,4 @@ public: ~SSLContextMbedTLS(); }; -#endif // SSL_CONTEXT_MBED_TLS_H +#endif // SSL_CONTEXT_MBEDTLS_H diff --git a/modules/mbedtls/stream_peer_mbedtls.h b/modules/mbedtls/stream_peer_mbedtls.h index 7660410e04..68b07feea9 100644 --- a/modules/mbedtls/stream_peer_mbedtls.h +++ b/modules/mbedtls/stream_peer_mbedtls.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef STREAM_PEER_OPEN_SSL_H -#define STREAM_PEER_OPEN_SSL_H +#ifndef STREAM_PEER_MBEDTLS_H +#define STREAM_PEER_MBEDTLS_H #include "core/io/stream_peer_ssl.h" #include "ssl_context_mbedtls.h" @@ -76,4 +76,4 @@ public: ~StreamPeerMbedTLS(); }; -#endif // STREAM_PEER_SSL_H +#endif // STREAM_PEER_MBEDTLS_H diff --git a/modules/meshoptimizer/register_types.h b/modules/meshoptimizer/register_types.h index 99c71efceb..3a84aab7bc 100644 --- a/modules/meshoptimizer/register_types.h +++ b/modules/meshoptimizer/register_types.h @@ -36,4 +36,4 @@ void initialize_meshoptimizer_module(ModuleInitializationLevel p_level); void uninitialize_meshoptimizer_module(ModuleInitializationLevel p_level); -#endif // PVR_REGISTER_TYPES_H +#endif // MESHOPTIMIZER_REGISTER_TYPES_H diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp index c37bea519f..98bcdea8f4 100644 --- a/modules/minimp3/audio_stream_mp3.cpp +++ b/modules/minimp3/audio_stream_mp3.cpp @@ -46,6 +46,12 @@ int AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) { int frames_mixed_this_step = p_frames; + int beat_length_frames = -1; + bool beat_loop = mp3_stream->has_loop() && mp3_stream->get_bpm() > 0 && mp3_stream->get_beat_count() > 0; + if (beat_loop) { + beat_length_frames = mp3_stream->get_beat_count() * mp3_stream->sample_rate * 60 / mp3_stream->get_bpm(); + } + while (todo && active) { mp3dec_frame_info_t frame_info; mp3d_sample_t *buf_frame = nullptr; @@ -54,8 +60,25 @@ int AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) { if (samples_mixed) { p_buffer[p_frames - todo] = AudioFrame(buf_frame[0], buf_frame[samples_mixed - 1]); + if (loop_fade_remaining < FADE_SIZE) { + p_buffer[p_frames - todo] += loop_fade[loop_fade_remaining] * (float(FADE_SIZE - loop_fade_remaining) / float(FADE_SIZE)); + loop_fade_remaining++; + } --todo; ++frames_mixed; + + if (beat_loop && (int)frames_mixed >= beat_length_frames) { + for (int i = 0; i < FADE_SIZE; i++) { + samples_mixed = mp3dec_ex_read_frame(mp3d, &buf_frame, &frame_info, mp3_stream->channels); + loop_fade[i] = AudioFrame(buf_frame[0], buf_frame[samples_mixed - 1]); + if (!samples_mixed) { + break; + } + } + loop_fade_remaining = 0; + seek(mp3_stream->loop_offset); + loops++; + } } else { @@ -117,6 +140,10 @@ void AudioStreamPlaybackMP3::seek(float p_time) { mp3dec_ex_seek(mp3d, (uint64_t)frames_mixed * mp3_stream->channels); } +void AudioStreamPlaybackMP3::tag_used_streams() { + mp3_stream->tag_used(get_playback_position()); +} + AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() { if (mp3d) { mp3dec_ex_close(mp3d); @@ -124,7 +151,7 @@ AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() { } } -Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() { +Ref<AudioStreamPlayback> AudioStreamMP3::instantiate_playback() { Ref<AudioStreamPlaybackMP3> mp3s; ERR_FAIL_COND_V_MSG(data.is_empty(), mp3s, @@ -206,6 +233,36 @@ bool AudioStreamMP3::is_monophonic() const { return false; } +void AudioStreamMP3::set_bpm(double p_bpm) { + ERR_FAIL_COND(p_bpm < 0); + bpm = p_bpm; + emit_changed(); +} + +double AudioStreamMP3::get_bpm() const { + return bpm; +} + +void AudioStreamMP3::set_beat_count(int p_beat_count) { + ERR_FAIL_COND(p_beat_count < 0); + beat_count = p_beat_count; + emit_changed(); +} + +int AudioStreamMP3::get_beat_count() const { + return beat_count; +} + +void AudioStreamMP3::set_bar_beats(int p_bar_beats) { + ERR_FAIL_COND(p_bar_beats < 0); + bar_beats = p_bar_beats; + emit_changed(); +} + +int AudioStreamMP3::get_bar_beats() const { + return bar_beats; +} + void AudioStreamMP3::_bind_methods() { ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamMP3::set_data); ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamMP3::get_data); @@ -216,7 +273,19 @@ void AudioStreamMP3::_bind_methods() { ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamMP3::set_loop_offset); ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamMP3::get_loop_offset); + ClassDB::bind_method(D_METHOD("set_bpm", "bpm"), &AudioStreamMP3::set_bpm); + ClassDB::bind_method(D_METHOD("get_bpm"), &AudioStreamMP3::get_bpm); + + ClassDB::bind_method(D_METHOD("set_beat_count", "count"), &AudioStreamMP3::set_beat_count); + ClassDB::bind_method(D_METHOD("get_beat_count"), &AudioStreamMP3::get_beat_count); + + ClassDB::bind_method(D_METHOD("set_bar_beats", "count"), &AudioStreamMP3::set_bar_beats); + ClassDB::bind_method(D_METHOD("get_bar_beats"), &AudioStreamMP3::get_bar_beats); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_data", "get_data"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bpm", PROPERTY_HINT_RANGE, "0,400,0.01,or_greater"), "set_bpm", "get_bpm"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "beat_count", PROPERTY_HINT_RANGE, "0,512,1,or_greater"), "set_beat_count", "get_beat_count"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "bar_beats", PROPERTY_HINT_RANGE, "2,32,1,or_greater"), "set_bar_beats", "get_bar_beats"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset"); } diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h index c1a60ddccb..428ac1240e 100644 --- a/modules/minimp3/audio_stream_mp3.h +++ b/modules/minimp3/audio_stream_mp3.h @@ -41,6 +41,12 @@ class AudioStreamMP3; class AudioStreamPlaybackMP3 : public AudioStreamPlaybackResampled { GDCLASS(AudioStreamPlaybackMP3, AudioStreamPlaybackResampled); + enum { + FADE_SIZE = 256 + }; + AudioFrame loop_fade[FADE_SIZE]; + int loop_fade_remaining = FADE_SIZE; + mp3dec_ex_t *mp3d = nullptr; uint32_t frames_mixed = 0; bool active = false; @@ -64,6 +70,8 @@ public: virtual float get_playback_position() const override; virtual void seek(float p_time) override; + virtual void tag_used_streams() override; + AudioStreamPlaybackMP3() {} ~AudioStreamPlaybackMP3(); }; @@ -85,17 +93,30 @@ class AudioStreamMP3 : public AudioStream { float loop_offset = 0.0; void clear_data(); + double bpm = 0; + int beat_count = 0; + int bar_beats = 4; + protected: static void _bind_methods(); public: void set_loop(bool p_enable); - bool has_loop() const; + virtual bool has_loop() const override; void set_loop_offset(float p_seconds); float get_loop_offset() const; - virtual Ref<AudioStreamPlayback> instance_playback() override; + void set_bpm(double p_bpm); + virtual double get_bpm() const override; + + void set_beat_count(int p_beat_count); + virtual int get_beat_count() const override; + + void set_bar_beats(int p_bar_beats); + virtual int get_bar_beats() const override; + + virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; void set_data(const Vector<uint8_t> &p_data); diff --git a/modules/minimp3/doc_classes/AudioStreamMP3.xml b/modules/minimp3/doc_classes/AudioStreamMP3.xml index f5f7d3ef17..8f03681c06 100644 --- a/modules/minimp3/doc_classes/AudioStreamMP3.xml +++ b/modules/minimp3/doc_classes/AudioStreamMP3.xml @@ -4,13 +4,42 @@ MP3 audio stream driver. </brief_description> <description> - MP3 audio stream driver. + MP3 audio stream driver. See [member data] if you want to load an MP3 file at run-time. </description> <tutorials> </tutorials> <members> + <member name="bar_beats" type="int" setter="set_bar_beats" getter="get_bar_beats" default="4"> + </member> + <member name="beat_count" type="int" setter="set_beat_count" getter="get_beat_count" default="0"> + </member> + <member name="bpm" type="float" setter="set_bpm" getter="get_bpm" default="0.0"> + </member> <member name="data" type="PackedByteArray" setter="set_data" getter="get_data" default="PackedByteArray()"> Contains the audio data in bytes. + You can load a file without having to import it beforehand using the code snippet below. Keep in mind that this snippet loads the whole file into memory and may not be ideal for huge files (hundreds of megabytes or more). + [codeblocks] + [gdscript] + func load_mp3(path): + var file = File.new() + file.open(path, File.READ) + var sound = AudioStreamMP3.new() + sound.data = file.get_buffer(file.get_length()) + file.close() + return sound + [/gdscript] + [csharp] + public AudioStreamMP3 LoadMP3(string path) + { + var file = new File(); + file.Open(path, File.READ); + var sound = new AudioStreamMP3(); + sound.Data = file.GetBuffer(file.GetLength()); + file.Close(); + return sound; + } + [/csharp] + [/codeblocks] </member> <member name="loop" type="bool" setter="set_loop" getter="has_loop" default="false"> If [code]true[/code], the stream will automatically loop when it reaches the end. diff --git a/modules/minimp3/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp index e03940f963..8526aeef38 100644 --- a/modules/minimp3/resource_importer_mp3.cpp +++ b/modules/minimp3/resource_importer_mp3.cpp @@ -34,6 +34,10 @@ #include "core/io/resource_saver.h" #include "scene/resources/texture.h" +#ifdef TOOLS_ENABLED +#include "editor/import/audio_stream_import_settings.h" +#endif + String ResourceImporterMP3::get_importer_name() const { return "mp3"; } @@ -69,14 +73,26 @@ String ResourceImporterMP3::get_preset_name(int p_idx) const { void ResourceImporterMP3::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "loop_offset"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "bpm", PROPERTY_HINT_RANGE, "0,400,0.01,or_greater"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "beat_count", PROPERTY_HINT_RANGE, "0,512,or_greater"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "bar_beats", PROPERTY_HINT_RANGE, "2,32,or_greater"), 4)); } -Error ResourceImporterMP3::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { - bool loop = p_options["loop"]; - float loop_offset = p_options["loop_offset"]; +#ifdef TOOLS_ENABLED +bool ResourceImporterMP3::has_advanced_options() const { + return true; +} +void ResourceImporterMP3::show_advanced_options(const String &p_path) { + Ref<AudioStreamMP3> mp3_stream = import_mp3(p_path); + if (mp3_stream.is_valid()) { + AudioStreamImportSettings::get_singleton()->edit(p_path, "mp3", mp3_stream); + } +} +#endif - Ref<FileAccess> f = FileAccess::open(p_source_file, FileAccess::READ); - ERR_FAIL_COND_V(f.is_null(), ERR_CANT_OPEN); +Ref<AudioStreamMP3> ResourceImporterMP3::import_mp3(const String &p_path) { + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V(f.is_null(), Ref<AudioStreamMP3>()); uint64_t len = f->get_length(); @@ -90,9 +106,27 @@ Error ResourceImporterMP3::import(const String &p_source_file, const String &p_s mp3_stream.instantiate(); mp3_stream->set_data(data); - ERR_FAIL_COND_V(!mp3_stream->get_data().size(), ERR_FILE_CORRUPT); + ERR_FAIL_COND_V(!mp3_stream->get_data().size(), Ref<AudioStreamMP3>()); + + return mp3_stream; +} + +Error ResourceImporterMP3::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { + bool loop = p_options["loop"]; + float loop_offset = p_options["loop_offset"]; + double bpm = p_options["bpm"]; + float beat_count = p_options["beat_count"]; + float bar_beats = p_options["bar_beats"]; + + Ref<AudioStreamMP3> mp3_stream = import_mp3(p_source_file); + if (mp3_stream.is_null()) { + return ERR_CANT_OPEN; + } mp3_stream->set_loop(loop); mp3_stream->set_loop_offset(loop_offset); + mp3_stream->set_bpm(bpm); + mp3_stream->set_beat_count(beat_count); + mp3_stream->set_bar_beats(bar_beats); return ResourceSaver::save(p_save_path + ".mp3str", mp3_stream); } diff --git a/modules/minimp3/resource_importer_mp3.h b/modules/minimp3/resource_importer_mp3.h index 678a3773bb..38729d68f8 100644 --- a/modules/minimp3/resource_importer_mp3.h +++ b/modules/minimp3/resource_importer_mp3.h @@ -50,6 +50,12 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; +#ifdef TOOLS_ENABLED + virtual bool has_advanced_options() const override; + virtual void show_advanced_options(const String &p_path) override; +#endif + static Ref<AudioStreamMP3> import_mp3(const String &p_path); + virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; ResourceImporterMP3(); diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 5876b6cbf3..b14f5f469c 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -45,7 +45,7 @@ uint32_t MobileVRInterface::get_capabilities() const { Vector3 MobileVRInterface::scale_magneto(const Vector3 &p_magnetometer) { // Our magnetometer doesn't give us nice clean data. - // Well it may on Mac OS X because we're getting a calibrated value in the current implementation but Android we're getting raw data. + // Well it may on macOS because we're getting a calibrated value in the current implementation but Android we're getting raw data. // This is a fairly simple adjustment we can do to correct for the magnetometer data being elliptical Vector3 mag_raw = p_magnetometer; @@ -452,10 +452,10 @@ Transform3D MobileVRInterface::get_transform_for_view(uint32_t p_view, const Tra return transform_for_eye; }; -CameraMatrix MobileVRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { +Projection MobileVRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { _THREAD_SAFE_METHOD_ - CameraMatrix eye; + Projection eye; aspect = p_aspect; eye.set_for_hmd(p_view + 1, p_aspect, intraocular_dist, display_width, display_to_lens, oversample, p_z_near, p_z_far); diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index 8ecca3a2ae..b934a09dd3 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -150,7 +150,7 @@ public: virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override; virtual void process() override; diff --git a/modules/mono/SCsub b/modules/mono/SCsub index 3bafa351a9..d10ebc7b47 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -55,7 +55,7 @@ env_mono.add_source_files(env.modules_sources, "utils/*.cpp") env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.cpp") -if env["platform"] in ["osx", "iphone"]: +if env["platform"] in ["macos", "ios"]: env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.mm") env_mono.add_source_files(env.modules_sources, "mono_gd/support/*.m") elif env["platform"] == "android": diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index 8e441e7e07..e69904c54b 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -63,15 +63,15 @@ def copy_file(src_dir, dst_dir, src_name, dst_name=""): def is_desktop(platform): - return platform in ["windows", "osx", "linuxbsd", "server", "uwp", "haiku"] + return platform in ["windows", "macos", "linuxbsd", "server", "uwp", "haiku"] def is_unix_like(platform): - return platform in ["osx", "linuxbsd", "server", "android", "haiku", "iphone"] + return platform in ["macos", "linuxbsd", "server", "android", "haiku", "ios"] def module_supports_tools_on(platform): - return platform not in ["android", "javascript", "iphone"] + return platform not in ["android", "javascript", "ios"] def find_wasm_src_dir(mono_root): @@ -89,7 +89,7 @@ def configure(env, env_mono): bits = env["bits"] is_android = env["platform"] == "android" is_javascript = env["platform"] == "javascript" - is_ios = env["platform"] == "iphone" + is_ios = env["platform"] == "ios" is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"] tools_enabled = env["tools"] @@ -206,7 +206,7 @@ def configure(env, env_mono): copy_file(mono_bin_path, "#bin", mono_dll_file) else: - is_apple = env["platform"] in ["osx", "iphone"] + is_apple = env["platform"] in ["macos", "ios"] is_macos = is_apple and not is_ios sharedlib_ext = ".dylib" if is_apple else ".so" @@ -221,7 +221,7 @@ def configure(env, env_mono): ) if not mono_root and is_macos: - # Try with some known directories under OSX + # Try with some known directories under macOS hint_dirs = ["/Library/Frameworks/Mono.framework/Versions/Current", "/usr/local/var/homebrew/linked/mono"] for hint_dir in hint_dirs: if os.path.isdir(hint_dir): @@ -270,7 +270,7 @@ def configure(env, env_mono): def copy_mono_lib(libname_wo_ext): copy_file( - mono_lib_path, "#bin", libname_wo_ext + ".a", "%s.iphone.%s.a" % (libname_wo_ext, arch) + mono_lib_path, "#bin", libname_wo_ext + ".a", "%s.ios.%s.a" % (libname_wo_ext, arch) ) # Copy Mono libraries to the output folder. These are meant to be bundled with @@ -539,7 +539,7 @@ def copy_mono_shared_libs(env, mono_root, target_mono_root_dir): os.makedirs(target_mono_lib_dir) lib_file_names = [] - if platform == "osx": + if platform == "macos": lib_file_names = [ lib_name + ".dylib" for lib_name in ["libmono-btls-shared", "libmono-native-compat", "libMonoPosixHelper"] diff --git a/modules/mono/config.py b/modules/mono/config.py index df02d9a309..3e6584590c 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -1,4 +1,4 @@ -supported_platforms = ["windows", "osx", "linuxbsd", "server", "android", "haiku", "javascript", "iphone"] +supported_platforms = ["windows", "macos", "linuxbsd", "server", "android", "haiku", "javascript", "ios"] def can_build(env, platform): @@ -15,7 +15,7 @@ def configure(env): from SCons.Script import BoolVariable, PathVariable, Variables, Help - default_mono_static = platform in ["iphone", "javascript"] + default_mono_static = platform in ["ios", "javascript"] default_mono_bundles_zlib = platform in ["javascript"] envvars = Variables() diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 3dc26cfbe4..06793d25e0 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -481,11 +481,14 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { Variant::VECTOR3, Variant::VECTOR3I, Variant::TRANSFORM2D, + Variant::VECTOR4, + Variant::VECTOR4I, Variant::PLANE, Variant::QUATERNION, Variant::AABB, Variant::BASIS, Variant::TRANSFORM3D, + Variant::PROJECTION, Variant::COLOR, Variant::STRING_NAME, Variant::NODE_PATH, @@ -2138,8 +2141,8 @@ bool CSharpInstance::refcount_decremented() { return ref_dying; } -const Vector<Multiplayer::RPCConfig> CSharpInstance::get_rpc_methods() const { - return script->get_rpc_methods(); +const Variant CSharpInstance::get_rpc_config() const { + return script->get_rpc_config(); } void CSharpInstance::notification(int p_notification) { @@ -3057,7 +3060,7 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { p_script->script_class->fetch_methods_with_godot_api_checks(p_script->native); - p_script->rpc_functions.clear(); + p_script->rpc_config.clear(); GDMonoClass *top = p_script->script_class; while (top && top != p_script->native) { @@ -3069,12 +3072,9 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { Vector<GDMonoMethod *> methods = top->get_all_methods(); for (int i = 0; i < methods.size(); i++) { if (!methods[i]->is_static()) { - Multiplayer::RPCConfig rpc_config = p_script->_member_get_rpc_config(methods[i]); - if (rpc_config.rpc_mode != Multiplayer::RPC_MODE_DISABLED) { - // RPC annotations can only be used once per method - if (p_script->rpc_functions.find(rpc_config) == -1) { - p_script->rpc_functions.push_back(rpc_config); - } + const Variant rpc_config = p_script->_member_get_rpc_config(methods[i]); + if (rpc_config.get_type() != Variant::NIL) { + p_script->rpc_config[methods[i]->get_name()] = rpc_config; } } } @@ -3083,9 +3083,6 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { top = top->get_parent_class(); } - // Sort so we are 100% that they are always the same. - p_script->rpc_functions.sort_custom<Multiplayer::SortRPCConfig>(); - p_script->load_script_signals(p_script->script_class, p_script->native); } @@ -3508,23 +3505,24 @@ int CSharpScript::get_member_line(const StringName &p_member) const { return -1; } -Multiplayer::RPCConfig CSharpScript::_member_get_rpc_config(IMonoClassMember *p_member) const { - Multiplayer::RPCConfig rpc_config; +Variant CSharpScript::_member_get_rpc_config(IMonoClassMember *p_member) const { + Variant out; MonoObject *rpc_attribute = p_member->get_attribute(CACHED_CLASS(RPCAttribute)); if (rpc_attribute != nullptr) { - rpc_config.name = p_member->get_name(); - rpc_config.rpc_mode = (Multiplayer::RPCMode)CACHED_PROPERTY(RPCAttribute, Mode)->get_int_value(rpc_attribute); - rpc_config.call_local = CACHED_PROPERTY(RPCAttribute, CallLocal)->get_bool_value(rpc_attribute); - rpc_config.transfer_mode = (Multiplayer::TransferMode)CACHED_PROPERTY(RPCAttribute, TransferMode)->get_int_value(rpc_attribute); - rpc_config.channel = CACHED_PROPERTY(RPCAttribute, TransferChannel)->get_int_value(rpc_attribute); + Dictionary rpc_config; + rpc_config["rpc_mode"] = CACHED_PROPERTY(RPCAttribute, Mode)->get_int_value(rpc_attribute); + rpc_config["call_local"] = CACHED_PROPERTY(RPCAttribute, CallLocal)->get_bool_value(rpc_attribute); + rpc_config["transfer_mode"] = CACHED_PROPERTY(RPCAttribute, TransferMode)->get_int_value(rpc_attribute); + rpc_config["channel"] = CACHED_PROPERTY(RPCAttribute, TransferChannel)->get_int_value(rpc_attribute); + out = rpc_config; } - return rpc_config; + return out; } -const Vector<Multiplayer::RPCConfig> CSharpScript::get_rpc_methods() const { - return rpc_functions; +const Variant CSharpScript::get_rpc_config() const { + return rpc_config; } Error CSharpScript::load_source_code(const String &p_path) { diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index b17473470f..bd46a06a92 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -136,7 +136,7 @@ private: HashMap<StringName, EventSignal> event_signals; bool signals_invalidated = true; - Vector<Multiplayer::RPCConfig> rpc_functions; + Dictionary rpc_config; #ifdef TOOLS_ENABLED List<PropertyInfo> exported_members_cache; // members_cache @@ -179,7 +179,7 @@ private: static void update_script_class_info(Ref<CSharpScript> p_script); static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native); - Multiplayer::RPCConfig _member_get_rpc_config(IMonoClassMember *p_member) const; + Variant _member_get_rpc_config(IMonoClassMember *p_member) const; protected: static void _bind_methods(); @@ -234,7 +234,7 @@ public: int get_member_line(const StringName &p_member) const override; - const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override; + const Variant get_rpc_config() const override; #ifdef TOOLS_ENABLED bool is_placeholder_fallback_enabled() const override { return placeholder_fallback_enabled; } @@ -311,7 +311,7 @@ public: void refcount_incremented() override; bool refcount_decremented() override; - const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override; + const Variant get_rpc_config() const override; void notification(int p_notification) override; void _call_notification(int p_notification); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props index 0128f5c706..5a499742e9 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props @@ -57,7 +57,7 @@ <PropertyGroup Condition=" '$(GodotTargetPlatform)' == '' "> <GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(Linux))' ">linuxbsd</GodotTargetPlatform> <GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(FreeBSD))' ">linuxbsd</GodotTargetPlatform> - <GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(OSX))' ">osx</GodotTargetPlatform> + <GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(OSX))' ">macos</GodotTargetPlatform> <GodotTargetPlatform Condition=" '$([MSBuild]::IsOsPlatform(Windows))' ">windows</GodotTargetPlatform> </PropertyGroup> @@ -76,12 +76,12 @@ --> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'windows' ">GODOT_WINDOWS;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'linuxbsd' ">GODOT_LINUXBSD;GODOT_PC</GodotPlatformConstants> - <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'osx' ">GODOT_OSX;GODOT_MACOS;GODOT_PC</GodotPlatformConstants> + <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'macos' ">GODOT_OSX;GODOT_MACOS;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'server' ">GODOT_SERVER;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'uwp' ">GODOT_UWP;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'haiku' ">GODOT_HAIKU;GODOT_PC</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'android' ">GODOT_ANDROID;GODOT_MOBILE</GodotPlatformConstants> - <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'iphone' ">GODOT_IPHONE;GODOT_IOS;GODOT_MOBILE</GodotPlatformConstants> + <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'ios' ">GODOT_IPHONE;GODOT_IOS;GODOT_MOBILE</GodotPlatformConstants> <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'javascript' ">GODOT_JAVASCRIPT;GODOT_HTML5;GODOT_WASM;GODOT_WEB</GodotPlatformConstants> <GodotDefineConstants>$(GodotDefineConstants);$(GodotPlatformConstants)</GodotDefineConstants> diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs index e2f4d2f5fd..e9718cc82c 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs @@ -336,10 +336,10 @@ MONO_AOT_MODE_LAST = 1000, // Add the required Mono libraries to the Xcode project - string MonoLibFile(string libFileName) => libFileName + ".iphone.fat.a"; + string MonoLibFile(string libFileName) => libFileName + ".ios.fat.a"; string MonoLibFromTemplate(string libFileName) => - Path.Combine(Internal.FullTemplatesDir, "iphone-mono-libs", MonoLibFile(libFileName)); + Path.Combine(Internal.FullExportTemplatesDir, "ios-mono-libs", MonoLibFile(libFileName)); exporter.AddIosProjectStaticLib(MonoLibFromTemplate("libmonosgen-2.0")); diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 3e46a89b7c..cca18a2a1f 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -337,7 +337,7 @@ namespace GodotTools.Export string TemplateDirName() => $"data.mono.{platform}.{bits}.{target}"; - string templateDirPath = Path.Combine(Internal.FullTemplatesDir, TemplateDirName()); + string templateDirPath = Path.Combine(Internal.FullExportTemplatesDir, TemplateDirName()); bool validTemplatePathFound = true; if (!Directory.Exists(templateDirPath)) @@ -347,7 +347,7 @@ namespace GodotTools.Export if (isDebug) { target = "debug"; // Support both 'release_debug' and 'debug' for the template data directory name - templateDirPath = Path.Combine(Internal.FullTemplatesDir, TemplateDirName()); + templateDirPath = Path.Combine(Internal.FullExportTemplatesDir, TemplateDirName()); validTemplatePathFound = true; if (!Directory.Exists(templateDirPath)) @@ -380,7 +380,7 @@ namespace GodotTools.Export private static bool PlatformHasTemplateDir(string platform) { - // OSX export templates are contained in a zip, so we place our custom template inside it and let Godot do the rest. + // macOS export templates are contained in a zip, so we place our custom template inside it and let Godot do the rest. return !new[] { OS.Platforms.MacOS, OS.Platforms.Android, OS.Platforms.iOS, OS.Platforms.HTML5 }.Contains(platform); } @@ -398,13 +398,13 @@ namespace GodotTools.Export private static string GetBclProfileDir(string profile) { - string templatesDir = Internal.FullTemplatesDir; + string templatesDir = Internal.FullExportTemplatesDir; return Path.Combine(templatesDir, "bcl", profile); } private static string DeterminePlatformBclDir(string platform) { - string templatesDir = Internal.FullTemplatesDir; + string templatesDir = Internal.FullExportTemplatesDir; string platformBclDir = Path.Combine(templatesDir, "bcl", platform); if (!File.Exists(Path.Combine(platformBclDir, "mscorlib.dll"))) diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 69960bdbeb..b39c3d1c0d 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -263,16 +263,16 @@ namespace GodotTools var args = new List<string>(); - bool osxAppBundleInstalled = false; + bool macOSAppBundleInstalled = false; if (OS.IsMacOS) { // The package path is '/Applications/Visual Studio Code.app' const string vscodeBundleId = "com.microsoft.VSCode"; - osxAppBundleInstalled = Internal.IsOsxAppBundleInstalled(vscodeBundleId); + macOSAppBundleInstalled = Internal.IsMacOSAppBundleInstalled(vscodeBundleId); - if (osxAppBundleInstalled) + if (macOSAppBundleInstalled) { args.Add("-b"); args.Add(vscodeBundleId); @@ -307,13 +307,13 @@ namespace GodotTools if (OS.IsMacOS) { - if (!osxAppBundleInstalled && string.IsNullOrEmpty(_vsCodePath)) + if (!macOSAppBundleInstalled && string.IsNullOrEmpty(_vsCodePath)) { GD.PushError("Cannot find code editor: VSCode"); return Error.FileNotFound; } - command = osxAppBundleInstalled ? "/usr/bin/open" : _vsCodePath; + command = macOSAppBundleInstalled ? "/usr/bin/open" : _vsCodePath; } else { diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs index 3f1d5ac3ca..7a0983a8cb 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs @@ -30,7 +30,7 @@ namespace GodotTools.Ides.MonoDevelop { string bundleId = BundleIds[_editorId]; - if (Internal.IsOsxAppBundleInstalled(bundleId)) + if (Internal.IsMacOSAppBundleInstalled(bundleId)) { command = "open"; diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs index 77370090ec..12c90178c9 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs @@ -12,12 +12,12 @@ namespace GodotTools.Internals public static string UpdateApiAssembliesFromPrebuilt(string config) => internal_UpdateApiAssembliesFromPrebuilt(config); - public static string FullTemplatesDir => - internal_FullTemplatesDir(); + public static string FullExportTemplatesDir => + internal_FullExportTemplatesDir(); public static string SimplifyGodotPath(this string path) => internal_SimplifyGodotPath(path); - public static bool IsOsxAppBundleInstalled(string bundleId) => internal_IsOsxAppBundleInstalled(bundleId); + public static bool IsMacOSAppBundleInstalled(string bundleId) => internal_IsMacOSAppBundleInstalled(bundleId); public static bool GodotIs32Bits() => internal_GodotIs32Bits(); @@ -57,13 +57,13 @@ namespace GodotTools.Internals private static extern string internal_UpdateApiAssembliesFromPrebuilt(string config); [MethodImpl(MethodImplOptions.InternalCall)] - private static extern string internal_FullTemplatesDir(); + private static extern string internal_FullExportTemplatesDir(); [MethodImpl(MethodImplOptions.InternalCall)] private static extern string internal_SimplifyGodotPath(this string path); [MethodImpl(MethodImplOptions.InternalCall)] - private static extern bool internal_IsOsxAppBundleInstalled(string bundleId); + private static extern bool internal_IsMacOSAppBundleInstalled(string bundleId); [MethodImpl(MethodImplOptions.InternalCall)] private static extern bool internal_GodotIs32Bits(); diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs index 2db549c623..5cef6e5c3c 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -37,13 +37,13 @@ namespace GodotTools.Utils public static class Platforms { public const string Windows = "windows"; - public const string MacOS = "osx"; + public const string MacOS = "macos"; public const string LinuxBSD = "linuxbsd"; public const string Server = "server"; public const string UWP = "uwp"; public const string Haiku = "haiku"; public const string Android = "android"; - public const string iOS = "iphone"; + public const string iOS = "ios"; public const string HTML5 = "javascript"; } diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 7cc195201b..2e628cb576 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -917,6 +917,8 @@ void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) { ARRAY_ALL(Vector2i); ARRAY_ALL(Vector3); ARRAY_ALL(Vector3i); + ARRAY_ALL(Vector4); + ARRAY_ALL(Vector4i); #undef ARRAY_ALL #undef ARRAY_IS_EMPTY @@ -3222,6 +3224,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.default_argument = "new %s" + r_iarg.default_argument; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; + case Variant::VECTOR4: + case Variant::VECTOR4I: + r_iarg.default_argument = "new %s" + r_iarg.default_argument; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + break; case Variant::OBJECT: ERR_FAIL_COND_V_MSG(!p_val.is_zero(), false, "Parameter of type '" + String(r_iarg.type.cname) + "' can only have null/zero as the default value."); @@ -3276,6 +3283,15 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; + case Variant::PROJECTION: { + Projection transform = p_val.operator Projection(); + if (transform == Projection()) { + r_iarg.default_argument = "Projection.Identity"; + } else { + r_iarg.default_argument = "new Projection(new Vector4" + transform.matrix[0].operator String() + ", new Vector4" + transform.matrix[1].operator String() + ", new Vector4" + transform.matrix[2].operator String() + ", new Vector4" + transform.matrix[3].operator String() + ")"; + } + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + } break; case Variant::BASIS: { Basis basis = p_val.operator Basis(); if (basis == Basis()) { diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 1547d0ed2f..ee170e4558 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -590,6 +590,9 @@ class BindingsGenerator { StringName type_Vector2 = StaticCString::create("Vector2"); StringName type_Rect2 = StaticCString::create("Rect2"); StringName type_Vector3 = StaticCString::create("Vector3"); + StringName type_Vector3i = StaticCString::create("Vector3i"); + StringName type_Vector4 = StaticCString::create("Vector4"); + StringName type_Vector4i = StaticCString::create("Vector4i"); // Object not included as it must be checked for all derived classes static constexpr int nullable_types_count = 17; diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index f7f710f3f1..5e4fe90553 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -47,7 +47,7 @@ #include "../glue/cs_glue_version.gen.h" #include "../godotsharp_dirs.h" #include "../mono_gd/gd_mono_marshal.h" -#include "../utils/osx_utils.h" +#include "../utils/macos_utils.h" #include "code_completion.h" #include "godotsharp_export.h" @@ -188,8 +188,8 @@ MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_c return GDMonoMarshal::mono_string_from_godot(error_str); } -MonoString *godot_icall_Internal_FullTemplatesDir() { - String full_templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG); +MonoString *godot_icall_Internal_FullExportTemplatesDir() { + String full_templates_dir = EditorSettings::get_singleton()->get_export_templates_dir().plus_file(VERSION_FULL_CONFIG); return GDMonoMarshal::mono_string_from_godot(full_templates_dir); } @@ -198,10 +198,10 @@ MonoString *godot_icall_Internal_SimplifyGodotPath(MonoString *p_path) { return GDMonoMarshal::mono_string_from_godot(path.simplify_path()); } -MonoBoolean godot_icall_Internal_IsOsxAppBundleInstalled(MonoString *p_bundle_id) { -#ifdef OSX_ENABLED +MonoBoolean godot_icall_Internal_IsMacOSAppBundleInstalled(MonoString *p_bundle_id) { +#ifdef MACOS_ENABLED String bundle_id = GDMonoMarshal::mono_string_to_godot(p_bundle_id); - return (MonoBoolean)osx_is_app_bundle_installed(bundle_id); + return (MonoBoolean)macos_is_app_bundle_installed(bundle_id); #else (void)p_bundle_id; // UNUSED return (MonoBoolean) false; @@ -364,9 +364,9 @@ void register_editor_internal_calls() { // Internals GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_UpdateApiAssembliesFromPrebuilt", godot_icall_Internal_UpdateApiAssembliesFromPrebuilt); - GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_FullTemplatesDir", godot_icall_Internal_FullTemplatesDir); + GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_FullExportTemplatesDir", godot_icall_Internal_FullExportTemplatesDir); GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_SimplifyGodotPath", godot_icall_Internal_SimplifyGodotPath); - GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_IsOsxAppBundleInstalled", godot_icall_Internal_IsOsxAppBundleInstalled); + GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_IsMacOSAppBundleInstalled", godot_icall_Internal_IsMacOSAppBundleInstalled); GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotIs32Bits", godot_icall_Internal_GodotIs32Bits); GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotIsRealTDouble", godot_icall_Internal_GodotIsRealTDouble); GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotMainIteration", godot_icall_Internal_GodotMainIteration); diff --git a/modules/mono/editor/editor_internal_calls.h b/modules/mono/editor/editor_internal_calls.h index a899634d57..8262ac211a 100644 --- a/modules/mono/editor/editor_internal_calls.h +++ b/modules/mono/editor/editor_internal_calls.h @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EDITOR_INTERNAL_CALL_H -#define EDITOR_INTERNAL_CALL_H +#ifndef EDITOR_INTERNAL_CALLS_H +#define EDITOR_INTERNAL_CALLS_H void register_editor_internal_calls(); -#endif // EDITOR_INTERNAL_CALL_H +#endif // EDITOR_INTERNAL_CALLS_H diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs index 0a1c8322d7..fb37838ffa 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttribute.cs @@ -5,8 +5,8 @@ namespace Godot /// <summary> /// Attribute that changes the RPC mode for the annotated <c>method</c> to the given <see cref="Mode"/>, /// optionally specifying the <see cref="TransferMode"/> and <see cref="TransferChannel"/> (on supported peers). - /// See <see cref="RPCMode"/> and <see cref="TransferMode"/>. By default, methods are not exposed to networking - /// (and RPCs). + /// See <see cref="MultiplayerAPI.RPCMode"/> and <see cref="MultiplayerPeer.TransferModeEnum"/>. + /// By default, methods are not exposed to networking (and RPCs). /// </summary> [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class RPCAttribute : Attribute @@ -14,7 +14,7 @@ namespace Godot /// <summary> /// RPC mode for the annotated method. /// </summary> - public RPCMode Mode { get; } = RPCMode.Disabled; + public MultiplayerAPI.RPCMode Mode { get; } = MultiplayerAPI.RPCMode.Disabled; /// <summary> /// If the method will also be called locally; otherwise, it is only called remotely. @@ -24,7 +24,7 @@ namespace Godot /// <summary> /// Transfer mode for the annotated method. /// </summary> - public TransferMode TransferMode { get; set; } = TransferMode.Reliable; + public MultiplayerPeer.TransferModeEnum TransferMode { get; set; } = MultiplayerPeer.TransferModeEnum.Reliable; /// <summary> /// Transfer channel for the annotated mode. @@ -35,7 +35,7 @@ namespace Godot /// Constructs a <see cref="RPCAttribute"/> instance. /// </summary> /// <param name="mode">The RPC mode to use.</param> - public RPCAttribute(RPCMode mode = RPCMode.Authority) + public RPCAttribute(MultiplayerAPI.RPCMode mode = MultiplayerAPI.RPCMode.Authority) { Mode = mode; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs index 63af1c5892..fd97a71e47 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs @@ -118,15 +118,15 @@ namespace Godot /// <summary> /// Returns <see langword="true"/> if point is inside the plane. - /// Comparison uses a custom minimum epsilon threshold. + /// Comparison uses a custom minimum tolerance threshold. /// </summary> /// <param name="point">The point to check.</param> - /// <param name="epsilon">The tolerance threshold.</param> + /// <param name="tolerance">The tolerance threshold.</param> /// <returns>A <see langword="bool"/> for whether or not the plane has the point.</returns> - public bool HasPoint(Vector3 point, real_t epsilon = Mathf.Epsilon) + public bool HasPoint(Vector3 point, real_t tolerance = Mathf.Epsilon) { real_t dist = _normal.Dot(point) - D; - return Mathf.Abs(dist) <= epsilon; + return Mathf.Abs(dist) <= tolerance; } /// <summary> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index 89947899cb..e01db7b88c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -347,7 +347,7 @@ namespace Godot /// </summary> /// <param name="offset">The offset to translate by.</param> /// <returns>The translated matrix.</returns> - public Transform2D Translated(Vector2 offset) + public Transform2D TranslatedLocal(Vector2 offset) { Transform2D copy = this; copy.origin += copy.BasisXform(offset); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index 7b211b6577..41565bf680 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs @@ -239,7 +239,7 @@ namespace Godot /// </summary> /// <param name="offset">The offset to translate by.</param> /// <returns>The translated matrix.</returns> - public Transform3D Translated(Vector3 offset) + public Transform3D TranslatedLocal(Vector3 offset) { return new Transform3D(basis, new Vector3 ( diff --git a/modules/mono/glue/glue_header.h b/modules/mono/glue/glue_header.h index 9638b23410..f9ad1a9893 100644 --- a/modules/mono/glue/glue_header.h +++ b/modules/mono/glue/glue_header.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GLUE_HEADER_H +#define GLUE_HEADER_H + #ifdef MONO_GLUE_ENABLED #include "../mono_gd/gd_mono_marshal.h" @@ -84,3 +87,5 @@ void godot_register_glue_header_icalls() { #include "arguments_vector.h" #endif // MONO_GLUE_ENABLED + +#endif // GLUE_HEADER_H diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index cb2b60fcce..f17b24e399 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -184,7 +184,7 @@ private: data_mono_bin_dir = data_mono_root_dir.plus_file("bin"); #endif -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED if (!DirAccess::exists(data_editor_tools_dir)) { data_editor_tools_dir = exe_dir.plus_file("../Resources/GodotSharp/Tools"); } @@ -222,7 +222,7 @@ private: data_mono_bin_dir = data_mono_root_dir.plus_file("bin"); #endif -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED if (!DirAccess::exists(data_mono_root_dir)) { data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc"); data_mono_lib_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/lib"); diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h index ab9e508c99..e2aff1d19d 100644 --- a/modules/mono/mono_gc_handle.h +++ b/modules/mono/mono_gc_handle.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CSHARP_GC_HANDLE_H -#define CSHARP_GC_HANDLE_H +#ifndef MONO_GC_HANDLE_H +#define MONO_GC_HANDLE_H #include <mono/jit/jit.h> @@ -104,4 +104,4 @@ public: ~MonoGCHandleRef() { release(); } }; -#endif // CSHARP_GC_HANDLE_H +#endif // MONO_GC_HANDLE_H diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 39a8ef22b7..d3d3bb2bef 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -55,7 +55,7 @@ #ifdef ANDROID_ENABLED #include "android_mono_config.h" #include "support/android_support.h" -#elif defined(IPHONE_ENABLED) +#elif defined(IOS_ENABLED) #include "support/ios_support.h" #endif @@ -188,7 +188,7 @@ MonoDomain *gd_initialize_mono_runtime() { MonoDomain *gd_initialize_mono_runtime() { gd_mono_debug_init(); -#if defined(IPHONE_ENABLED) || defined(ANDROID_ENABLED) +#if defined(IOS_ENABLED) || defined(ANDROID_ENABLED) // I don't know whether this actually matters or not const char *runtime_version = "mobile"; #else @@ -263,7 +263,7 @@ void GDMono::determine_mono_dirs(String &r_assembly_rootdir, String &r_config_di if (mono_reg_info.config_dir.length() && DirAccess::exists(mono_reg_info.config_dir)) { r_config_dir = mono_reg_info.config_dir; } -#elif defined(OSX_ENABLED) +#elif defined(MACOS_ENABLED) const char *c_assembly_rootdir = mono_assembly_getrootdir(); const char *c_config_dir = mono_get_config_dir(); @@ -343,7 +343,7 @@ void GDMono::initialize() { #if defined(ANDROID_ENABLED) gdmono::android::support::initialize(); -#elif defined(IPHONE_ENABLED) +#elif defined(IOS_ENABLED) gdmono::ios::support::initialize(); #endif diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index fd78fae4ad..69d8c7edc9 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -108,9 +108,12 @@ void CachedData::clear_godot_api_cache() { class_Transform2D = nullptr; class_Vector3 = nullptr; class_Vector3i = nullptr; + class_Vector4 = nullptr; + class_Vector4i = nullptr; class_Basis = nullptr; class_Quaternion = nullptr; class_Transform3D = nullptr; + class_Projection = nullptr; class_AABB = nullptr; class_Color = nullptr; class_Plane = nullptr; @@ -239,9 +242,12 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Transform2D, GODOT_API_CLASS(Transform2D)); CACHE_CLASS_AND_CHECK(Vector3, GODOT_API_CLASS(Vector3)); CACHE_CLASS_AND_CHECK(Vector3i, GODOT_API_CLASS(Vector3i)); + CACHE_CLASS_AND_CHECK(Vector4, GODOT_API_CLASS(Vector4)); + CACHE_CLASS_AND_CHECK(Vector4i, GODOT_API_CLASS(Vector4i)); CACHE_CLASS_AND_CHECK(Basis, GODOT_API_CLASS(Basis)); CACHE_CLASS_AND_CHECK(Quaternion, GODOT_API_CLASS(Quaternion)); CACHE_CLASS_AND_CHECK(Transform3D, GODOT_API_CLASS(Transform3D)); + CACHE_CLASS_AND_CHECK(Projection, GODOT_API_CLASS(Projection)); CACHE_CLASS_AND_CHECK(AABB, GODOT_API_CLASS(AABB)); CACHE_CLASS_AND_CHECK(Color, GODOT_API_CLASS(Color)); CACHE_CLASS_AND_CHECK(Plane, GODOT_API_CLASS(Plane)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index b3b0865608..e9cc26899e 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -79,9 +79,12 @@ struct CachedData { GDMonoClass *class_Transform2D = nullptr; GDMonoClass *class_Vector3 = nullptr; GDMonoClass *class_Vector3i = nullptr; + GDMonoClass *class_Vector4 = nullptr; + GDMonoClass *class_Vector4i = nullptr; GDMonoClass *class_Basis = nullptr; GDMonoClass *class_Quaternion = nullptr; GDMonoClass *class_Transform3D = nullptr; + GDMonoClass *class_Projection = nullptr; GDMonoClass *class_AABB = nullptr; GDMonoClass *class_Color = nullptr; GDMonoClass *class_Plane = nullptr; diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 333a06c94a..cb025fc67a 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -140,6 +140,18 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Vector4)) { + GDMonoMarshal::M_Vector4 from = MARSHALLED_OUT(Vector4, p_value.operator ::Vector4()); + mono_field_set_value(p_object, mono_field, &from); + break; + } + + if (tclass == CACHED_CLASS(Vector4i)) { + GDMonoMarshal::M_Vector4i from = MARSHALLED_OUT(Vector4i, p_value.operator ::Vector4i()); + mono_field_set_value(p_object, mono_field, &from); + break; + } + if (tclass == CACHED_CLASS(Basis)) { GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_value.operator ::Basis()); mono_field_set_value(p_object, mono_field, &from); @@ -158,6 +170,12 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Projection)) { + GDMonoMarshal::M_Projection from = MARSHALLED_OUT(Projection, p_value.operator ::Projection()); + mono_field_set_value(p_object, mono_field, &from); + break; + } + if (tclass == CACHED_CLASS(AABB)) { GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_value.operator ::AABB()); mono_field_set_value(p_object, mono_field, &from); @@ -328,6 +346,14 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_value.operator ::Vector3i()); mono_field_set_value(p_object, mono_field, &from); } break; + case Variant::VECTOR4: { + GDMonoMarshal::M_Vector4 from = MARSHALLED_OUT(Vector4, p_value.operator ::Vector4()); + mono_field_set_value(p_object, mono_field, &from); + } break; + case Variant::VECTOR4I: { + GDMonoMarshal::M_Vector4i from = MARSHALLED_OUT(Vector4i, p_value.operator ::Vector4i()); + mono_field_set_value(p_object, mono_field, &from); + } break; case Variant::TRANSFORM2D: { GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_value.operator ::Transform2D()); mono_field_set_value(p_object, mono_field, &from); @@ -352,6 +378,10 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ GDMonoMarshal::M_Transform3D from = MARSHALLED_OUT(Transform3D, p_value.operator ::Transform3D()); mono_field_set_value(p_object, mono_field, &from); } break; + case Variant::PROJECTION: { + GDMonoMarshal::M_Projection from = MARSHALLED_OUT(Projection, p_value.operator ::Projection()); + mono_field_set_value(p_object, mono_field, &from); + } break; case Variant::COLOR: { GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_value.operator ::Color()); mono_field_set_value(p_object, mono_field, &from); diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h index 87ef245f3f..1d30f7a369 100644 --- a/modules/mono/mono_gd/gd_mono_field.h +++ b/modules/mono/mono_gd/gd_mono_field.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GDMONOFIELD_H -#define GDMONOFIELD_H +#ifndef GD_MONO_FIELD_H +#define GD_MONO_FIELD_H #include "gd_mono.h" #include "gd_mono_header.h" @@ -75,4 +75,4 @@ public: ~GDMonoField(); }; -#endif // GDMONOFIELD_H +#endif // GD_MONO_FIELD_H diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h index 9fc35f8e31..93ba6a410e 100644 --- a/modules/mono/mono_gd/gd_mono_log.h +++ b/modules/mono/mono_gd/gd_mono_log.h @@ -35,7 +35,7 @@ #include "core/typedefs.h" -#if !defined(JAVASCRIPT_ENABLED) && !defined(IPHONE_ENABLED) +#if !defined(JAVASCRIPT_ENABLED) && !defined(IOS_ENABLED) // We have custom mono log callbacks for WASM and iOS #define GD_MONO_LOG_ENABLED #endif diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 957abca37b..a860442764 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -99,6 +99,13 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (vtclass == CACHED_CLASS(Vector3i)) { return Variant::VECTOR3I; } + if (vtclass == CACHED_CLASS(Vector4)) { + return Variant::VECTOR4; + } + + if (vtclass == CACHED_CLASS(Vector4i)) { + return Variant::VECTOR4I; + } if (vtclass == CACHED_CLASS(Basis)) { return Variant::BASIS; @@ -111,7 +118,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (vtclass == CACHED_CLASS(Transform3D)) { return Variant::TRANSFORM3D; } - + if (vtclass == CACHED_CLASS(Projection)) { + return Variant::PROJECTION; + } if (vtclass == CACHED_CLASS(AABB)) { return Variant::AABB; } @@ -539,6 +548,14 @@ MonoObject *variant_to_mono_object(const Variant &p_var) { GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var.operator ::Transform2D()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from); } + case Variant::VECTOR4: { + GDMonoMarshal::M_Vector4 from = MARSHALLED_OUT(Vector4, p_var.operator ::Vector4()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector4), &from); + } + case Variant::VECTOR4I: { + GDMonoMarshal::M_Vector4i from = MARSHALLED_OUT(Vector4i, p_var.operator ::Vector4i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector4i), &from); + } case Variant::PLANE: { GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_var.operator ::Plane()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from); @@ -559,6 +576,10 @@ MonoObject *variant_to_mono_object(const Variant &p_var) { GDMonoMarshal::M_Transform3D from = MARSHALLED_OUT(Transform3D, p_var.operator ::Transform3D()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform3D), &from); } + case Variant::PROJECTION: { + GDMonoMarshal::M_Projection from = MARSHALLED_OUT(Projection, p_var.operator ::Projection()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Projection), &from); + } case Variant::COLOR: { GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var.operator ::Color()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from); diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 778e52b6cb..3b6fd25d71 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GDMONOMARSHAL_H -#define GDMONOMARSHAL_H +#ifndef GD_MONO_MARSHAL_H +#define GD_MONO_MARSHAL_H #include "core/variant/variant.h" @@ -256,6 +256,18 @@ enum { offsetof(Vector3, y) == (sizeof(real_t) * 1) && offsetof(Vector3, z) == (sizeof(real_t) * 2)), + MATCHES_Vector4 = (MATCHES_real_t && (sizeof(Vector4) == (sizeof(real_t) * 4)) && + offsetof(Vector4, x) == (sizeof(real_t) * 0) && + offsetof(Vector4, y) == (sizeof(real_t) * 1) && + offsetof(Vector4, z) == (sizeof(real_t) * 2) && + offsetof(Vector4, w) == (sizeof(real_t) * 3)), + + MATCHES_Vector4i = (MATCHES_int && (sizeof(Vector4i) == (sizeof(int32_t) * 4i)) && + offsetof(Vector4i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector4i, y) == (sizeof(int32_t) * 1) && + offsetof(Vector4i, z) == (sizeof(int32_t) * 2) && + offsetof(Vector4i, w) == (sizeof(int32_t) * 3)), + MATCHES_Vector3i = (MATCHES_int && (sizeof(Vector3i) == (sizeof(int32_t) * 3)) && offsetof(Vector3i, x) == (sizeof(int32_t) * 0) && offsetof(Vector3i, y) == (sizeof(int32_t) * 1) && @@ -273,6 +285,8 @@ enum { offsetof(Transform3D, basis) == 0 && offsetof(Transform3D, origin) == sizeof(Basis)), + MATCHES_Projection = (MATCHES_Vector4 && (sizeof(Projection) == (sizeof(Vector4) * 4))), + MATCHES_AABB = (MATCHES_Vector3 && (sizeof(AABB) == (sizeof(Vector3) * 2)) && offsetof(AABB, position) == (sizeof(Vector3) * 0) && offsetof(AABB, size) == (sizeof(Vector3) * 1)), @@ -291,9 +305,9 @@ enum { // In the future we may force this if we want to ref return these structs #ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY /* clang-format off */ -static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && - MATCHES_Basis && MATCHES_Quaternion && MATCHES_Transform3D && MATCHES_AABB && MATCHES_Color && - MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i); +static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && MATCHES_Vector4 && + MATCHES_Basis && MATCHES_Quaternion && MATCHES_Transform3D && MATCHES_Projection && MATCHES_AABB && MATCHES_Color && + MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i && MATCHES_Vector4i); /* clang-format on */ #endif } // namespace InteropLayout @@ -401,6 +415,32 @@ struct M_Vector3i { } }; +struct M_Vector4 { + real_t x, y, z, w; + + static _FORCE_INLINE_ Vector4 convert_to(const M_Vector4 &p_from) { + return Vector4(p_from.x, p_from.y, p_from.z, p_from.w); + } + + static _FORCE_INLINE_ M_Vector4 convert_from(const Vector4 &p_from) { + M_Vector4 ret = { p_from.x, p_from.y, p_from.z, p_from.w }; + return ret; + } +}; + +struct M_Vector4i { + int32_t x, y, z, w; + + static _FORCE_INLINE_ Vector4i convert_to(const M_Vector4i &p_from) { + return Vector4i(p_from.x, p_from.y, p_from.z, p_from.w); + } + + static _FORCE_INLINE_ M_Vector4i convert_from(const Vector4i &p_from) { + M_Vector4i ret = { p_from.x, p_from.y, p_from.z, p_from.w }; + return ret; + } +}; + struct M_Basis { M_Vector3 elements[3]; @@ -447,6 +487,22 @@ struct M_Transform3D { } }; +struct M_Projection { + M_Vector4 vec1; + M_Vector4 vec2; + M_Vector4 vec3; + M_Vector4 vec4; + + static _FORCE_INLINE_ Projection convert_to(const M_Projection &p_from) { + return Projection(M_Vector4::convert_to(p_from.vec1), M_Vector4::convert_to(p_from.vec2), M_Vector4::convert_to(p_from.vec3), M_Vector4::convert_to(p_from.vec4)); + } + + static _FORCE_INLINE_ M_Projection convert_from(const Projection &p_from) { + M_Projection ret = { M_Vector4::convert_from(p_from.matrix[0]), M_Vector4::convert_from(p_from.matrix[1]), M_Vector4::convert_from(p_from.matrix[2]), M_Vector4::convert_from(p_from.matrix[3]) }; + return ret; + } +}; + struct M_AABB { M_Vector3 position; M_Vector3 size; @@ -533,8 +589,11 @@ DECL_TYPE_MARSHAL_TEMPLATES(Transform2D) DECL_TYPE_MARSHAL_TEMPLATES(Vector3) DECL_TYPE_MARSHAL_TEMPLATES(Vector3i) DECL_TYPE_MARSHAL_TEMPLATES(Basis) +DECL_TYPE_MARSHAL_TEMPLATES(Vector4) +DECL_TYPE_MARSHAL_TEMPLATES(Vector4i) DECL_TYPE_MARSHAL_TEMPLATES(Quaternion) DECL_TYPE_MARSHAL_TEMPLATES(Transform3D) +DECL_TYPE_MARSHAL_TEMPLATES(Projection) DECL_TYPE_MARSHAL_TEMPLATES(AABB) DECL_TYPE_MARSHAL_TEMPLATES(Color) DECL_TYPE_MARSHAL_TEMPLATES(Plane) @@ -543,4 +602,4 @@ DECL_TYPE_MARSHAL_TEMPLATES(Plane) #define MARSHALLED_OUT(m_type, m_from) (GDMonoMarshal::marshalled_out_##m_type(m_from)) } // namespace GDMonoMarshal -#endif // GDMONOMARSHAL_H +#endif // GD_MONO_MARSHAL_H diff --git a/modules/mono/mono_gd/gd_mono_method_thunk.h b/modules/mono/mono_gd/gd_mono_method_thunk.h index bb163b89bc..0180dee3ea 100644 --- a/modules/mono/mono_gd/gd_mono_method_thunk.h +++ b/modules/mono/mono_gd/gd_mono_method_thunk.h @@ -39,7 +39,7 @@ #include "gd_mono_method.h" #include "gd_mono_utils.h" -#if !defined(JAVASCRIPT_ENABLED) && !defined(IPHONE_ENABLED) +#if !defined(JAVASCRIPT_ENABLED) && !defined(IOS_ENABLED) #define HAVE_METHOD_THUNKS #endif diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 246a1cd31e..300cacfa4b 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GD_MONOUTILS_H -#define GD_MONOUTILS_H +#ifndef GD_MONO_UTILS_H +#define GD_MONO_UTILS_H #include <mono/metadata/threads.h> @@ -202,4 +202,4 @@ void add_internal_call(const char *p_name, R (*p_func)(P...)) { #define GD_MONO_ASSERT_THREAD_ATTACHED ((void)0) #endif -#endif // GD_MONOUTILS_H +#endif // GD_MONO_UTILS_H diff --git a/modules/mono/mono_gd/support/ios_support.h b/modules/mono/mono_gd/support/ios_support.h index 2f444d5089..03e86df698 100644 --- a/modules/mono/mono_gd/support/ios_support.h +++ b/modules/mono/mono_gd/support/ios_support.h @@ -31,7 +31,7 @@ #ifndef IOS_SUPPORT_H #define IOS_SUPPORT_H -#if defined(IPHONE_ENABLED) +#if defined(IOS_ENABLED) #include "core/string/ustring.h" @@ -45,6 +45,6 @@ void cleanup(); } // namespace ios } // namespace gdmono -#endif // IPHONE_ENABLED +#endif // IOS_ENABLED #endif // IOS_SUPPORT_H diff --git a/modules/mono/mono_gd/support/ios_support.mm b/modules/mono/mono_gd/support/ios_support.mm index df97dfba49..7c941b9d1e 100644 --- a/modules/mono/mono_gd/support/ios_support.mm +++ b/modules/mono/mono_gd/support/ios_support.mm @@ -30,7 +30,7 @@ #include "ios_support.h" -#if defined(IPHONE_ENABLED) +#if defined(IOS_ENABLED) #import <Foundation/Foundation.h> #include <os/log.h> @@ -147,4 +147,4 @@ GD_PINVOKE_EXPORT void xamarin_start_wwan(const char *p_uri) { os_log_error(OS_LOG_DEFAULT, "Not implemented: 'xamarin_start_wwan'"); } -#endif // IPHONE_ENABLED +#endif // IOS_ENABLED diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/macos_utils.cpp index abb59420eb..cd4f7a827e 100644 --- a/modules/mono/utils/osx_utils.cpp +++ b/modules/mono/utils/macos_utils.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* osx_utils.cpp */ +/* macos_utils.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,16 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "osx_utils.h" +#include "macos_utils.h" -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED #include "core/string/print_string.h" #import <CoreFoundation/CoreFoundation.h> #import <CoreServices/CoreServices.h> -bool osx_is_app_bundle_installed(const String &p_bundle_id) { +bool macos_is_app_bundle_installed(const String &p_bundle_id) { CFStringRef bundle_id = CFStringCreateWithCString(nullptr, p_bundle_id.utf8(), kCFStringEncodingUTF8); CFArrayRef result = LSCopyApplicationURLsForBundleIdentifier(bundle_id, nullptr); CFRelease(bundle_id); diff --git a/modules/mono/utils/osx_utils.h b/modules/mono/utils/macos_utils.h index 2f6c6dad51..ca4957f5a7 100644 --- a/modules/mono/utils/osx_utils.h +++ b/modules/mono/utils/macos_utils.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* osx_utils.h */ +/* macos_utils.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -30,13 +30,13 @@ #include "core/string/ustring.h" -#ifndef OSX_UTILS_H -#define OSX_UTILS_H +#ifndef MONO_MACOS_UTILS_H +#define MONO_MACOS_UTILS_H -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED -bool osx_is_app_bundle_installed(const String &p_bundle_id); +bool macos_is_app_bundle_installed(const String &p_bundle_id); #endif -#endif // OSX_UTILS_H +#endif // MONO_MACOS_UTILS_H diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h index 2ca1a4cbf1..b7bd9a2495 100644 --- a/modules/mono/utils/macros.h +++ b/modules/mono/utils/macros.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef UTIL_MACROS_H -#define UTIL_MACROS_H +#ifndef MONO_MACROS_H +#define MONO_MACROS_H #define _GD_VARNAME_CONCAT_B_(m_ignore, m_name) m_name #define _GD_VARNAME_CONCAT_A_(m_a, m_b, m_c) _GD_VARNAME_CONCAT_B_(hello there, m_a##m_b##m_c) @@ -69,4 +69,4 @@ public: #define SCOPE_EXIT \ auto GD_UNIQUE_NAME(gd_scope_exit) = gdmono::ScopeExitAux() + [=]() -> void -#endif // UTIL_MACROS_H +#endif // MONO_MACROS_H diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h index a8cd8daf04..9a2c757361 100644 --- a/modules/mono/utils/path_utils.h +++ b/modules/mono/utils/path_utils.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PATH_UTILS_H -#define PATH_UTILS_H +#ifndef MONO_PATH_UTILS_H +#define MONO_PATH_UTILS_H #include "core/string/string_builder.h" #include "core/string/ustring.h" @@ -58,4 +58,4 @@ String realpath(const String &p_path); String relative_to(const String &p_path, const String &p_relative_to); } // namespace path -#endif // PATH_UTILS_H +#endif // MONO_PATH_UTILS_H diff --git a/modules/mono/utils/string_utils.h b/modules/mono/utils/string_utils.h index d79888716a..fa4c5e89f4 100644 --- a/modules/mono/utils/string_utils.h +++ b/modules/mono/utils/string_utils.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef STRING_FORMAT_H -#define STRING_FORMAT_H +#ifndef MONO_STRING_UTILS_H +#define MONO_STRING_UTILS_H #include "core/string/ustring.h" #include "core/variant/variant.h" @@ -59,4 +59,4 @@ String str_format(const char *p_format, va_list p_list) _PRINTF_FORMAT_ATTRIBUTE char *str_format_new(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_1_2; char *str_format_new(const char *p_format, va_list p_list) _PRINTF_FORMAT_ATTRIBUTE_1_0; -#endif // STRING_FORMAT_H +#endif // MONO_STRING_UTILS_H diff --git a/modules/multiplayer/SCsub b/modules/multiplayer/SCsub new file mode 100644 index 0000000000..ff33655537 --- /dev/null +++ b/modules/multiplayer/SCsub @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +Import("env") +Import("env_modules") + +env_mp = env_modules.Clone() + +module_obj = [] +env_mp.add_source_files(module_obj, "*.cpp") + +if env["tools"]: + env_mp.add_source_files(module_obj, "editor/*.cpp") + +env.modules_sources += module_obj diff --git a/modules/multiplayer/config.py b/modules/multiplayer/config.py new file mode 100644 index 0000000000..414bf0afcf --- /dev/null +++ b/modules/multiplayer/config.py @@ -0,0 +1,19 @@ +def can_build(env, platform): + return True + + +def configure(env): + pass + + +def get_doc_classes(): + return [ + "SceneReplicationConfig", + "SceneMultiplayer", + "MultiplayerSpawner", + "MultiplayerSynchronizer", + ] + + +def get_doc_path(): + return "doc_classes" diff --git a/doc/classes/MultiplayerSpawner.xml b/modules/multiplayer/doc_classes/MultiplayerSpawner.xml index 4ca92728ff..44ab34f52c 100644 --- a/doc/classes/MultiplayerSpawner.xml +++ b/modules/multiplayer/doc_classes/MultiplayerSpawner.xml @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="MultiplayerSpawner" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="MultiplayerSpawner" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> </brief_description> <description> + This node uses [method MultiplayerAPI.object_configuration_add] to notify spawns passing the spawned node as the [code]object[/code] and itself as the [code]configuration[/code], and [method MultiplayerAPI.object_configuration_remove] to notify despawns in a similar way. </description> <tutorials> </tutorials> @@ -43,8 +44,6 @@ </method> </methods> <members> - <member name="auto_spawn" type="bool" setter="set_auto_spawning" getter="is_auto_spawning" default="false"> - </member> <member name="spawn_limit" type="int" setter="set_spawn_limit" getter="get_spawn_limit" default="0"> </member> <member name="spawn_path" type="NodePath" setter="set_spawn_path" getter="get_spawn_path" default="NodePath("")"> diff --git a/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml b/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml new file mode 100644 index 0000000000..ebd1b50201 --- /dev/null +++ b/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="MultiplayerSynchronizer" inherits="Node" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> + <brief_description> + </brief_description> + <description> + The [MultiplayerSynchronizer] uses [method MultiplayerAPI.object_configuration_add] to notify synchronization start passing the [Node] at [member root_path] as the [code]object[/code] and itself as the [code]configuration[/code], and uses [method MultiplayerAPI.object_configuration_remove] to notify synchronization end in a similar way. + </description> + <tutorials> + </tutorials> + <methods> + <method name="add_visibility_filter"> + <return type="void" /> + <argument index="0" name="filter" type="Callable" /> + <description> + </description> + </method> + <method name="get_visibility_for" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="peer" type="int" /> + <description> + </description> + </method> + <method name="remove_visibility_filter"> + <return type="void" /> + <argument index="0" name="filter" type="Callable" /> + <description> + </description> + </method> + <method name="set_visibility_for"> + <return type="void" /> + <argument index="0" name="peer" type="int" /> + <argument index="1" name="visible" type="bool" /> + <description> + </description> + </method> + <method name="update_visibility"> + <return type="void" /> + <argument index="0" name="for_peer" type="int" default="0" /> + <description> + </description> + </method> + </methods> + <members> + <member name="public_visibility" type="bool" setter="set_visibility_public" getter="is_visibility_public" default="true"> + </member> + <member name="replication_config" type="SceneReplicationConfig" setter="set_replication_config" getter="get_replication_config"> + </member> + <member name="replication_interval" type="float" setter="set_replication_interval" getter="get_replication_interval" default="0.0"> + </member> + <member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath("..")"> + </member> + <member name="visibility_update_mode" type="int" setter="set_visibility_update_mode" getter="get_visibility_update_mode" enum="MultiplayerSynchronizer.VisibilityUpdateMode" default="0"> + </member> + </members> + <signals> + <signal name="visibility_changed"> + <argument index="0" name="for_peer" type="int" /> + <description> + </description> + </signal> + </signals> + <constants> + <constant name="VISIBILITY_PROCESS_IDLE" value="0" enum="VisibilityUpdateMode"> + </constant> + <constant name="VISIBILITY_PROCESS_PHYSICS" value="1" enum="VisibilityUpdateMode"> + </constant> + <constant name="VISIBILITY_PROCESS_NONE" value="2" enum="VisibilityUpdateMode"> + </constant> + </constants> +</class> diff --git a/modules/multiplayer/doc_classes/SceneMultiplayer.xml b/modules/multiplayer/doc_classes/SceneMultiplayer.xml new file mode 100644 index 0000000000..0c3ed2d784 --- /dev/null +++ b/modules/multiplayer/doc_classes/SceneMultiplayer.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="SceneMultiplayer" inherits="MultiplayerAPI" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> + <brief_description> + High-level multiplayer API implementation. + </brief_description> + <description> + This class is the default implementation of [MultiplayerAPI], used to provide multiplayer functionalities in Godot Engine. + This implementation supports RPCs via [method Node.rpc] and [method Node.rpc_id] and requires [method MultiplayerAPI.rpc] to be passed a [Node] (it will fail for other object types). + This implementation additionally provide [SceneTree] replication via the [MultiplayerSpawner] and [MultiplayerSynchronizer] nodes, and the [SceneReplicationConfig] resource. + [b]Note:[/b] The high-level multiplayer API protocol is an implementation detail and isn't meant to be used by non-Godot servers. It may change without notice. + [b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android. + </description> + <tutorials> + </tutorials> + <methods> + <method name="clear"> + <return type="void" /> + <description> + Clears the current SceneMultiplayer network state (you shouldn't call this unless you know what you are doing). + </description> + </method> + <method name="send_bytes"> + <return type="int" enum="Error" /> + <argument index="0" name="bytes" type="PackedByteArray" /> + <argument index="1" name="id" type="int" default="0" /> + <argument index="2" name="mode" type="int" enum="MultiplayerPeer.TransferMode" default="2" /> + <argument index="3" name="channel" type="int" default="0" /> + <description> + Sends the given raw [code]bytes[/code] to a specific peer identified by [code]id[/code] (see [method MultiplayerPeer.set_target_peer]). Default ID is [code]0[/code], i.e. broadcast to all peers. + </description> + </method> + </methods> + <members> + <member name="allow_object_decoding" type="bool" setter="set_allow_object_decoding" getter="is_object_decoding_allowed" default="false"> + If [code]true[/code], the MultiplayerAPI will allow encoding and decoding of object during RPCs. + [b]Warning:[/b] Deserialized objects can contain code which gets executed. Do not use this option if the serialized object comes from untrusted sources to avoid potential security threat such as remote code execution. + </member> + <member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections" default="false"> + If [code]true[/code], the MultiplayerAPI's [member MultiplayerAPI.multiplayer_peer] refuses new incoming connections. + </member> + <member name="root_path" type="NodePath" setter="set_root_path" getter="get_root_path" default="NodePath("")"> + The root path to use for RPCs and replication. Instead of an absolute path, a relative path will be used to find the node upon which the RPC should be executed. + This effectively allows to have different branches of the scene tree to be managed by different MultiplayerAPI, allowing for example to run both client and server in the same scene. + </member> + </members> + <signals> + <signal name="peer_packet"> + <argument index="0" name="id" type="int" /> + <argument index="1" name="packet" type="PackedByteArray" /> + <description> + Emitted when this MultiplayerAPI's [member MultiplayerAPI.multiplayer_peer] receives a [code]packet[/code] with custom data (see [method send_bytes]). ID is the peer ID of the peer that sent the packet. + </description> + </signal> + </signals> +</class> diff --git a/doc/classes/SceneReplicationConfig.xml b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml index 62c108a477..1d6dec2f92 100644 --- a/doc/classes/SceneReplicationConfig.xml +++ b/modules/multiplayer/doc_classes/SceneReplicationConfig.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="SceneReplicationConfig" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="SceneReplicationConfig" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> </brief_description> <description> diff --git a/editor/plugins/replication_editor_plugin.cpp b/modules/multiplayer/editor/replication_editor_plugin.cpp index 3e06a6739f..5891327db4 100644 --- a/editor/plugins/replication_editor_plugin.cpp +++ b/modules/multiplayer/editor/replication_editor_plugin.cpp @@ -33,9 +33,9 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/inspector_dock.h" +#include "modules/multiplayer/multiplayer_synchronizer.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" -#include "scene/multiplayer/multiplayer_synchronizer.h" void ReplicationEditor::_pick_node_filter_text_changed(const String &p_newtext) { TreeItem *root_item = pick_node->get_scene_tree()->get_scene_tree()->get_root(); diff --git a/editor/plugins/replication_editor_plugin.h b/modules/multiplayer/editor/replication_editor_plugin.h index df3d97f884..57fa4c82fa 100644 --- a/editor/plugins/replication_editor_plugin.h +++ b/modules/multiplayer/editor/replication_editor_plugin.h @@ -32,12 +32,13 @@ #define REPLICATION_EDITOR_PLUGIN_H #include "editor/editor_plugin.h" -#include "scene/resources/scene_replication_config.h" #include "editor/editor_spin_slider.h" #include "editor/property_editor.h" #include "editor/property_selector.h" +#include "../scene_replication_config.h" + class ConfirmationDialog; class MultiplayerSynchronizer; class Tree; @@ -131,5 +132,17 @@ public: ReplicationEditorPlugin(); ~ReplicationEditorPlugin(); }; +#else +class ReplicationEditorPlugin : public EditorPlugin { + GDCLASS(ReplicationEditorPlugin, EditorPlugin); + +public: + virtual void edit(Object *p_object) override {} + virtual bool handles(Object *p_object) const override { return false; } + virtual void make_visible(bool p_visible) override {} + + ReplicationEditorPlugin() {} + ~ReplicationEditorPlugin() {} +}; #endif // REPLICATION_EDITOR_PLUGIN_H diff --git a/scene/multiplayer/multiplayer_spawner.cpp b/modules/multiplayer/multiplayer_spawner.cpp index ddd01d0a43..ca2fd1c023 100644 --- a/scene/multiplayer/multiplayer_spawner.cpp +++ b/modules/multiplayer/multiplayer_spawner.cpp @@ -31,7 +31,7 @@ #include "multiplayer_spawner.h" #include "core/io/marshalls.h" -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" @@ -71,7 +71,7 @@ bool MultiplayerSpawner::_get(const StringName &p_name, Variant &r_ret) const { } void MultiplayerSpawner::_get_property_list(List<PropertyInfo> *p_list) const { - p_list->push_back(PropertyInfo(Variant::INT, "_spawnable_scene_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Scenes,scenes/")); + p_list->push_back(PropertyInfo(Variant::INT, "_spawnable_scene_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, "Auto Spawn List,scenes/")); List<String> exts; ResourceLoader::get_recognized_extensions_for_type("PackedScene", &exts); String ext_hint; @@ -144,10 +144,6 @@ void MultiplayerSpawner::_bind_methods() { ClassDB::bind_method(D_METHOD("set_spawn_limit", "limit"), &MultiplayerSpawner::set_spawn_limit); ADD_PROPERTY(PropertyInfo(Variant::INT, "spawn_limit", PROPERTY_HINT_RANGE, "0,1024,1,or_greater"), "set_spawn_limit", "get_spawn_limit"); - ClassDB::bind_method(D_METHOD("set_auto_spawning", "enabled"), &MultiplayerSpawner::set_auto_spawning); - ClassDB::bind_method(D_METHOD("is_auto_spawning"), &MultiplayerSpawner::is_auto_spawning); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_spawn"), "set_auto_spawning", "is_auto_spawning"); - GDVIRTUAL_BIND(_spawn_custom, "data"); ADD_SIGNAL(MethodInfo("despawned", PropertyInfo(Variant::INT, "scene_id"), PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); @@ -169,7 +165,7 @@ void MultiplayerSpawner::_update_spawn_node() { Node *node = spawn_path.is_empty() && is_inside_tree() ? nullptr : get_node_or_null(spawn_path); if (node) { spawn_node = node->get_instance_id(); - if (auto_spawn) { + if (get_spawnable_scene_count() && !GDVIRTUAL_IS_OVERRIDDEN(_spawn_custom)) { node->connect("child_entered_tree", callable_mp(this, &MultiplayerSpawner::_node_added)); } } else { @@ -194,7 +190,7 @@ void MultiplayerSpawner::_notification(int p_what) { if (node->is_connected(SceneStringNames::get_singleton()->ready, callable_mp(this, &MultiplayerSpawner::_node_ready))) { node->disconnect(SceneStringNames::get_singleton()->ready, callable_mp(this, &MultiplayerSpawner::_node_ready)); } - get_multiplayer()->despawn(node, this); + get_multiplayer()->object_configuration_remove(node, this); } tracked_nodes.clear(); } break; @@ -221,15 +217,6 @@ void MultiplayerSpawner::_node_added(Node *p_node) { _track(p_node, Variant(), id); } -void MultiplayerSpawner::set_auto_spawning(bool p_enabled) { - auto_spawn = p_enabled; - _update_spawn_node(); -} - -bool MultiplayerSpawner::is_auto_spawning() const { - return auto_spawn; -} - NodePath MultiplayerSpawner::get_spawn_path() const { return spawn_path; } @@ -249,7 +236,7 @@ void MultiplayerSpawner::_track(Node *p_node, const Variant &p_argument, int p_s } void MultiplayerSpawner::_node_ready(ObjectID p_id) { - get_multiplayer()->spawn(ObjectDB::get_instance(p_id), this); + get_multiplayer()->object_configuration_add(ObjectDB::get_instance(p_id), this); } void MultiplayerSpawner::_node_exit(ObjectID p_id) { @@ -257,7 +244,7 @@ void MultiplayerSpawner::_node_exit(ObjectID p_id) { ERR_FAIL_COND(!node); if (tracked_nodes.has(p_id)) { tracked_nodes.erase(p_id); - get_multiplayer()->despawn(node, this); + get_multiplayer()->object_configuration_remove(node, this); } } diff --git a/scene/multiplayer/multiplayer_spawner.h b/modules/multiplayer/multiplayer_spawner.h index e8abe702a0..80bb878a74 100644 --- a/scene/multiplayer/multiplayer_spawner.h +++ b/modules/multiplayer/multiplayer_spawner.h @@ -36,7 +36,8 @@ #include "core/templates/local_vector.h" #include "core/variant/typed_array.h" #include "scene/resources/packed_scene.h" -#include "scene/resources/scene_replication_config.h" + +#include "scene_replication_config.h" class MultiplayerSpawner : public Node { GDCLASS(MultiplayerSpawner, Node); @@ -69,7 +70,6 @@ private: ObjectID spawn_node; HashMap<ObjectID, SpawnInfo> tracked_nodes; - bool auto_spawn = false; uint32_t spawn_limit = 0; void _update_spawn_node(); @@ -102,8 +102,6 @@ public: void set_spawn_path(const NodePath &p_path); uint32_t get_spawn_limit() const { return spawn_limit; } void set_spawn_limit(uint32_t p_limit) { spawn_limit = p_limit; } - bool is_auto_spawning() const; - void set_auto_spawning(bool p_enabled); const Variant get_spawn_argument(const ObjectID &p_id) const; int find_spawnable_scene_index_from_object(const ObjectID &p_id) const; diff --git a/scene/multiplayer/multiplayer_synchronizer.cpp b/modules/multiplayer/multiplayer_synchronizer.cpp index 68f6e54fa8..621d62c4c7 100644 --- a/scene/multiplayer/multiplayer_synchronizer.cpp +++ b/modules/multiplayer/multiplayer_synchronizer.cpp @@ -31,7 +31,7 @@ #include "multiplayer_synchronizer.h" #include "core/config/engine.h" -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" Object *MultiplayerSynchronizer::_get_prop_target(Object *p_obj, const NodePath &p_path) { if (p_path.get_name_count() == 0) { @@ -43,16 +43,54 @@ Object *MultiplayerSynchronizer::_get_prop_target(Object *p_obj, const NodePath } void MultiplayerSynchronizer::_stop() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr; if (node) { - get_multiplayer()->replication_stop(node, this); + get_multiplayer()->object_configuration_remove(node, this); } } void MultiplayerSynchronizer::_start() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr; if (node) { - get_multiplayer()->replication_start(node, this); + get_multiplayer()->object_configuration_add(node, this); + _update_process(); + } +} + +void MultiplayerSynchronizer::_update_process() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr; + if (!node) { + return; + } + set_process_internal(false); + set_physics_process_internal(false); + if (!visibility_filters.size()) { + return; + } + switch (visibility_update_mode) { + case VISIBILITY_PROCESS_IDLE: + set_process_internal(true); + break; + case VISIBILITY_PROCESS_PHYSICS: + set_physics_process_internal(true); + break; + case VISIBILITY_PROCESS_NONE: + break; } } @@ -85,6 +123,66 @@ Error MultiplayerSynchronizer::set_state(const List<NodePath> &p_properties, Obj return OK; } +bool MultiplayerSynchronizer::is_visibility_public() const { + return peer_visibility.has(0); +} + +void MultiplayerSynchronizer::set_visibility_public(bool p_visible) { + set_visibility_for(0, p_visible); +} + +bool MultiplayerSynchronizer::is_visible_to(int p_peer) { + if (visibility_filters.size()) { + Variant arg = p_peer; + const Variant *argv[1] = { &arg }; + for (Callable filter : visibility_filters) { + Variant ret; + Callable::CallError err; + filter.call(argv, 1, ret, err); + ERR_FAIL_COND_V(err.error != Callable::CallError::CALL_OK || ret.get_type() != Variant::BOOL, false); + if (!ret.operator bool()) { + return false; + } + } + } + return peer_visibility.has(0) || peer_visibility.has(p_peer); +} + +void MultiplayerSynchronizer::add_visibility_filter(Callable p_callback) { + visibility_filters.insert(p_callback); + _update_process(); +} + +void MultiplayerSynchronizer::remove_visibility_filter(Callable p_callback) { + visibility_filters.erase(p_callback); + _update_process(); +} + +void MultiplayerSynchronizer::set_visibility_for(int p_peer, bool p_visible) { + if (peer_visibility.has(p_peer) == p_visible) { + return; + } + if (p_visible) { + peer_visibility.insert(p_peer); + } else { + peer_visibility.erase(p_peer); + } + update_visibility(p_peer); +} + +bool MultiplayerSynchronizer::get_visibility_for(int p_peer) const { + return peer_visibility.has(p_peer); +} + +void MultiplayerSynchronizer::set_visibility_update_mode(VisibilityUpdateMode p_mode) { + visibility_update_mode = p_mode; + _update_process(); +} + +MultiplayerSynchronizer::VisibilityUpdateMode MultiplayerSynchronizer::get_visibility_update_mode() const { + return visibility_update_mode; +} + void MultiplayerSynchronizer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_root_path", "path"), &MultiplayerSynchronizer::set_root_path); ClassDB::bind_method(D_METHOD("get_root_path"), &MultiplayerSynchronizer::get_root_path); @@ -95,9 +193,29 @@ void MultiplayerSynchronizer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_replication_config", "config"), &MultiplayerSynchronizer::set_replication_config); ClassDB::bind_method(D_METHOD("get_replication_config"), &MultiplayerSynchronizer::get_replication_config); + ClassDB::bind_method(D_METHOD("set_visibility_update_mode", "mode"), &MultiplayerSynchronizer::set_visibility_update_mode); + ClassDB::bind_method(D_METHOD("get_visibility_update_mode"), &MultiplayerSynchronizer::get_visibility_update_mode); + ClassDB::bind_method(D_METHOD("update_visibility", "for_peer"), &MultiplayerSynchronizer::update_visibility, DEFVAL(0)); + + ClassDB::bind_method(D_METHOD("set_visibility_public", "visible"), &MultiplayerSynchronizer::set_visibility_public); + ClassDB::bind_method(D_METHOD("is_visibility_public"), &MultiplayerSynchronizer::is_visibility_public); + + ClassDB::bind_method(D_METHOD("add_visibility_filter", "filter"), &MultiplayerSynchronizer::add_visibility_filter); + ClassDB::bind_method(D_METHOD("remove_visibility_filter", "filter"), &MultiplayerSynchronizer::remove_visibility_filter); + ClassDB::bind_method(D_METHOD("set_visibility_for", "peer", "visible"), &MultiplayerSynchronizer::set_visibility_for); + ClassDB::bind_method(D_METHOD("get_visibility_for", "peer"), &MultiplayerSynchronizer::get_visibility_for); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_path"), "set_root_path", "get_root_path"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "replication_interval", PROPERTY_HINT_RANGE, "0,5,0.001,suffix:s"), "set_replication_interval", "get_replication_interval"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "replication_config", PROPERTY_HINT_RESOURCE_TYPE, "SceneReplicationConfig"), "set_replication_config", "get_replication_config"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "replication_config", PROPERTY_HINT_RESOURCE_TYPE, "SceneReplicationConfig", PROPERTY_USAGE_NO_EDITOR), "set_replication_config", "get_replication_config"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_update_mode", PROPERTY_HINT_ENUM, "Idle,Physics,None"), "set_visibility_update_mode", "get_visibility_update_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "public_visibility"), "set_visibility_public", "is_visibility_public"); + + BIND_ENUM_CONSTANT(VISIBILITY_PROCESS_IDLE); + BIND_ENUM_CONSTANT(VISIBILITY_PROCESS_PHYSICS); + BIND_ENUM_CONSTANT(VISIBILITY_PROCESS_NONE); + + ADD_SIGNAL(MethodInfo("visibility_changed", PropertyInfo(Variant::INT, "for_peer"))); } void MultiplayerSynchronizer::_notification(int p_what) { @@ -118,6 +236,11 @@ void MultiplayerSynchronizer::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { _stop(); } break; + + case NOTIFICATION_INTERNAL_PROCESS: + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + update_visibility(0); + } break; } } @@ -142,6 +265,18 @@ Ref<SceneReplicationConfig> MultiplayerSynchronizer::get_replication_config() { return replication_config; } +void MultiplayerSynchronizer::update_visibility(int p_for_peer) { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + Node *node = is_inside_tree() ? get_node_or_null(root_path) : nullptr; + if (node && get_multiplayer()->has_multiplayer_peer() && is_multiplayer_authority()) { + emit_signal(SNAME("visibility_changed"), p_for_peer); + } +} + void MultiplayerSynchronizer::set_root_path(const NodePath &p_path) { _stop(); root_path = p_path; @@ -158,7 +293,12 @@ void MultiplayerSynchronizer::set_multiplayer_authority(int p_peer_id, bool p_re Node::set_multiplayer_authority(p_peer_id, p_recursive); return; } - get_multiplayer()->replication_stop(node, this); + get_multiplayer()->object_configuration_remove(node, this); Node::set_multiplayer_authority(p_peer_id, p_recursive); - get_multiplayer()->replication_start(node, this); + get_multiplayer()->object_configuration_add(node, this); +} + +MultiplayerSynchronizer::MultiplayerSynchronizer() { + // Publicly visible by default. + peer_visibility.insert(0); } diff --git a/scene/multiplayer/multiplayer_synchronizer.h b/modules/multiplayer/multiplayer_synchronizer.h index f61ef459da..e84d41db86 100644 --- a/scene/multiplayer/multiplayer_synchronizer.h +++ b/modules/multiplayer/multiplayer_synchronizer.h @@ -33,19 +33,30 @@ #include "scene/main/node.h" -#include "scene/resources/scene_replication_config.h" +#include "scene_replication_config.h" class MultiplayerSynchronizer : public Node { GDCLASS(MultiplayerSynchronizer, Node); +public: + enum VisibilityUpdateMode { + VISIBILITY_PROCESS_IDLE, + VISIBILITY_PROCESS_PHYSICS, + VISIBILITY_PROCESS_NONE, + }; + private: Ref<SceneReplicationConfig> replication_config; NodePath root_path = NodePath(".."); // Start with parent, like with AnimationPlayer. uint64_t interval_msec = 0; + VisibilityUpdateMode visibility_update_mode = VISIBILITY_PROCESS_IDLE; + HashSet<Callable> visibility_filters; + HashSet<int> peer_visibility; static Object *_get_prop_target(Object *p_obj, const NodePath &p_prop); void _start(); void _stop(); + void _update_process(); protected: static void _bind_methods(); @@ -66,7 +77,20 @@ public: NodePath get_root_path() const; virtual void set_multiplayer_authority(int p_peer_id, bool p_recursive = true) override; - MultiplayerSynchronizer() {} + bool is_visibility_public() const; + void set_visibility_public(bool p_public); + bool is_visible_to(int p_peer); + void set_visibility_for(int p_peer, bool p_visible); + bool get_visibility_for(int p_peer) const; + void update_visibility(int p_for_peer); + void set_visibility_update_mode(VisibilityUpdateMode p_mode); + void add_visibility_filter(Callable p_callback); + void remove_visibility_filter(Callable p_callback); + VisibilityUpdateMode get_visibility_update_mode() const; + + MultiplayerSynchronizer(); }; +VARIANT_ENUM_CAST(MultiplayerSynchronizer::VisibilityUpdateMode); + #endif // MULTIPLAYER_SYNCHRONIZER_H diff --git a/modules/multiplayer/register_types.cpp b/modules/multiplayer/register_types.cpp new file mode 100644 index 0000000000..a2c524da80 --- /dev/null +++ b/modules/multiplayer/register_types.cpp @@ -0,0 +1,60 @@ +/*************************************************************************/ +/* register_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "register_types.h" + +#include "multiplayer_spawner.h" +#include "multiplayer_synchronizer.h" +#include "scene_multiplayer.h" +#include "scene_replication_interface.h" +#include "scene_rpc_interface.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_plugin.h" +#include "editor/replication_editor_plugin.h" +#endif + +void initialize_multiplayer_module(ModuleInitializationLevel p_level) { + if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) { + GDREGISTER_CLASS(SceneReplicationConfig); + GDREGISTER_CLASS(MultiplayerSpawner); + GDREGISTER_CLASS(MultiplayerSynchronizer); + GDREGISTER_CLASS(SceneMultiplayer); + MultiplayerAPI::set_default_interface("SceneMultiplayer"); + } +#ifdef TOOLS_ENABLED + if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) { + EditorPlugins::add_by_type<ReplicationEditorPlugin>(); + } +#endif +} + +void uninitialize_multiplayer_module(ModuleInitializationLevel p_level) { +} diff --git a/modules/multiplayer/register_types.h b/modules/multiplayer/register_types.h new file mode 100644 index 0000000000..aca6cf46ed --- /dev/null +++ b/modules/multiplayer/register_types.h @@ -0,0 +1,39 @@ +/*************************************************************************/ +/* register_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 MULTIPLAYER_REGISTER_TYPES_H +#define MULTIPLAYER_REGISTER_TYPES_H + +#include "modules/register_module_types.h" + +void initialize_multiplayer_module(ModuleInitializationLevel p_level); +void uninitialize_multiplayer_module(ModuleInitializationLevel p_level); + +#endif // MULTIPLAYER_REGISTER_TYPES_H diff --git a/scene/multiplayer/scene_cache_interface.cpp b/modules/multiplayer/scene_cache_interface.cpp index 7c271341db..4dc01321b9 100644 --- a/scene/multiplayer/scene_cache_interface.cpp +++ b/modules/multiplayer/scene_cache_interface.cpp @@ -34,13 +34,7 @@ #include "scene/main/node.h" #include "scene/main/window.h" -MultiplayerCacheInterface *SceneCacheInterface::_create(MultiplayerAPI *p_multiplayer) { - return memnew(SceneCacheInterface(p_multiplayer)); -} - -void SceneCacheInterface::make_default() { - MultiplayerAPI::create_default_cache_interface = _create; -} +#include "scene_multiplayer.h" void SceneCacheInterface::on_peer_change(int p_id, bool p_connected) { if (p_connected) { @@ -98,7 +92,7 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac Vector<uint8_t> packet; packet.resize(1 + 1 + len); - packet.write[0] = MultiplayerAPI::NETWORK_COMMAND_CONFIRM_PATH; + packet.write[0] = SceneMultiplayer::NETWORK_COMMAND_CONFIRM_PATH; packet.write[1] = valid_rpc_checksum; encode_cstring(pname.get_data(), &packet.write[2]); @@ -110,7 +104,7 @@ void SceneCacheInterface::process_simplify_path(int p_from, const uint8_t *p_pac #endif multiplayer_peer->set_transfer_channel(0); - multiplayer_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE); + multiplayer_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE); multiplayer_peer->set_target_peer(p_from); multiplayer_peer->put_packet(packet.ptr(), packet.size()); } @@ -150,7 +144,7 @@ Error SceneCacheInterface::_send_confirm_path(Node *p_node, NodePath p_path, Pat packet.resize(1 + 4 + path_len + methods_md5_len); int ofs = 0; - packet.write[ofs] = MultiplayerAPI::NETWORK_COMMAND_SIMPLIFY_PATH; + packet.write[ofs] = SceneMultiplayer::NETWORK_COMMAND_SIMPLIFY_PATH; ofs += 1; ofs += encode_cstring(methods_md5.utf8().get_data(), &packet.write[ofs]); @@ -170,7 +164,7 @@ Error SceneCacheInterface::_send_confirm_path(Node *p_node, NodePath p_path, Pat for (int peer_id : p_peers) { multiplayer_peer->set_target_peer(peer_id); multiplayer_peer->set_transfer_channel(0); - multiplayer_peer->set_transfer_mode(Multiplayer::TRANSFER_MODE_RELIABLE); + multiplayer_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE); err = multiplayer_peer->put_packet(packet.ptr(), packet.size()); ERR_FAIL_COND_V(err != OK, err); // Insert into confirmed, but as false since it was not confirmed. @@ -187,18 +181,29 @@ bool SceneCacheInterface::is_cache_confirmed(NodePath p_path, int p_peer) { return F->value; } -bool SceneCacheInterface::send_object_cache(Object *p_obj, NodePath p_path, int p_peer_id, int &r_id) { +int SceneCacheInterface::make_object_cache(Object *p_obj) { Node *node = Object::cast_to<Node>(p_obj); - ERR_FAIL_COND_V(!node, false); + ERR_FAIL_COND_V(!node, -1); + NodePath for_path = multiplayer->get_root_path().rel_path_to(node->get_path()); // See if the path is cached. - PathSentCache *psc = path_send_cache.getptr(p_path); + PathSentCache *psc = path_send_cache.getptr(for_path); if (!psc) { // Path is not cached, create. - path_send_cache[p_path] = PathSentCache(); - psc = path_send_cache.getptr(p_path); + path_send_cache[for_path] = PathSentCache(); + psc = path_send_cache.getptr(for_path); psc->id = last_send_cache_id++; } - r_id = psc->id; + return psc->id; +} + +bool SceneCacheInterface::send_object_cache(Object *p_obj, int p_peer_id, int &r_id) { + Node *node = Object::cast_to<Node>(p_obj); + ERR_FAIL_COND_V(!node, false); + + r_id = make_object_cache(p_obj); + ERR_FAIL_COND_V(r_id < 0, false); + NodePath for_path = multiplayer->get_root_path().rel_path_to(node->get_path()); + PathSentCache *psc = path_send_cache.getptr(for_path); bool has_all_peers = true; List<int> peers_to_add; // If one is missing, take note to add it. @@ -233,7 +238,7 @@ bool SceneCacheInterface::send_object_cache(Object *p_obj, NodePath p_path, int } if (peers_to_add.size()) { - _send_confirm_path(node, p_path, psc, peers_to_add); + _send_confirm_path(node, for_path, psc, peers_to_add); } return has_all_peers; diff --git a/scene/multiplayer/scene_cache_interface.h b/modules/multiplayer/scene_cache_interface.h index 3116233b5b..1e80792fe7 100644 --- a/scene/multiplayer/scene_cache_interface.h +++ b/modules/multiplayer/scene_cache_interface.h @@ -31,13 +31,15 @@ #ifndef SCENE_CACHE_INTERFACE_H #define SCENE_CACHE_INTERFACE_H -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" -class SceneCacheInterface : public MultiplayerCacheInterface { - GDCLASS(SceneCacheInterface, MultiplayerCacheInterface); +class SceneMultiplayer; + +class SceneCacheInterface : public RefCounted { + GDCLASS(SceneCacheInterface, RefCounted); private: - MultiplayerAPI *multiplayer = nullptr; + SceneMultiplayer *multiplayer = nullptr; //path sent caches struct PathSentCache { @@ -61,22 +63,20 @@ private: protected: Error _send_confirm_path(Node *p_node, NodePath p_path, PathSentCache *psc, const List<int> &p_peers); - static MultiplayerCacheInterface *_create(MultiplayerAPI *p_multiplayer); public: - static void make_default(); - - virtual void clear() override; - virtual void on_peer_change(int p_id, bool p_connected) override; - virtual void process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) override; - virtual void process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) override; + void clear(); + void on_peer_change(int p_id, bool p_connected); + void process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len); + void process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len); // Returns true if all peers have cached path. - virtual bool send_object_cache(Object *p_obj, NodePath p_path, int p_target, int &p_id) override; - virtual Object *get_cached_object(int p_from, uint32_t p_cache_id) override; - virtual bool is_cache_confirmed(NodePath p_path, int p_peer) override; + bool send_object_cache(Object *p_obj, int p_target, int &p_id); + int make_object_cache(Object *p_obj); + Object *get_cached_object(int p_from, uint32_t p_cache_id); + bool is_cache_confirmed(NodePath p_path, int p_peer); - SceneCacheInterface(MultiplayerAPI *p_multiplayer) { multiplayer = p_multiplayer; } + SceneCacheInterface(SceneMultiplayer *p_multiplayer) { multiplayer = p_multiplayer; } }; #endif // SCENE_CACHE_INTERFACE_H diff --git a/modules/multiplayer/scene_multiplayer.cpp b/modules/multiplayer/scene_multiplayer.cpp new file mode 100644 index 0000000000..3fc1eef366 --- /dev/null +++ b/modules/multiplayer/scene_multiplayer.cpp @@ -0,0 +1,332 @@ +/*************************************************************************/ +/* scene_multiplayer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "scene_multiplayer.h" + +#include "core/debugger/engine_debugger.h" +#include "core/io/marshalls.h" + +#include <stdint.h> + +#ifdef DEBUG_ENABLED +#include "core/os/os.h" +#endif + +#ifdef DEBUG_ENABLED +void SceneMultiplayer::profile_bandwidth(const String &p_inout, int p_size) { + if (EngineDebugger::is_profiling("multiplayer")) { + Array values; + values.push_back(p_inout); + values.push_back(OS::get_singleton()->get_ticks_msec()); + values.push_back(p_size); + EngineDebugger::profiler_add_frame_data("multiplayer", values); + } +} +#endif + +Error SceneMultiplayer::poll() { + if (!multiplayer_peer.is_valid() || multiplayer_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED) { + return ERR_UNCONFIGURED; + } + + multiplayer_peer->poll(); + + if (!multiplayer_peer.is_valid()) { // It's possible that polling might have resulted in a disconnection, so check here. + return OK; + } + + while (multiplayer_peer->get_available_packet_count()) { + int sender = multiplayer_peer->get_packet_peer(); + const uint8_t *packet; + int len; + + Error err = multiplayer_peer->get_packet(&packet, len); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Error getting packet! %d", err)); + + remote_sender_id = sender; + _process_packet(sender, packet, len); + remote_sender_id = 0; + + if (!multiplayer_peer.is_valid()) { + return OK; // It's also possible that a packet or RPC caused a disconnection, so also check here. + } + } + replicator->on_network_process(); + return OK; +} + +void SceneMultiplayer::clear() { + connected_peers.clear(); + packet_cache.clear(); + cache->clear(); +} + +void SceneMultiplayer::set_root_path(const NodePath &p_path) { + ERR_FAIL_COND_MSG(!p_path.is_absolute() && !p_path.is_empty(), "SceneMultiplayer root path must be absolute."); + root_path = p_path; +} + +NodePath SceneMultiplayer::get_root_path() const { + return root_path; +} + +void SceneMultiplayer::set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) { + if (p_peer == multiplayer_peer) { + return; // Nothing to do + } + + ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == MultiplayerPeer::CONNECTION_DISCONNECTED, + "Supplied MultiplayerPeer must be connecting or connected."); + + if (multiplayer_peer.is_valid()) { + multiplayer_peer->disconnect("peer_connected", callable_mp(this, &SceneMultiplayer::_add_peer)); + multiplayer_peer->disconnect("peer_disconnected", callable_mp(this, &SceneMultiplayer::_del_peer)); + multiplayer_peer->disconnect("connection_succeeded", callable_mp(this, &SceneMultiplayer::_connected_to_server)); + multiplayer_peer->disconnect("connection_failed", callable_mp(this, &SceneMultiplayer::_connection_failed)); + multiplayer_peer->disconnect("server_disconnected", callable_mp(this, &SceneMultiplayer::_server_disconnected)); + clear(); + } + + multiplayer_peer = p_peer; + + if (multiplayer_peer.is_valid()) { + multiplayer_peer->connect("peer_connected", callable_mp(this, &SceneMultiplayer::_add_peer)); + multiplayer_peer->connect("peer_disconnected", callable_mp(this, &SceneMultiplayer::_del_peer)); + multiplayer_peer->connect("connection_succeeded", callable_mp(this, &SceneMultiplayer::_connected_to_server)); + multiplayer_peer->connect("connection_failed", callable_mp(this, &SceneMultiplayer::_connection_failed)); + multiplayer_peer->connect("server_disconnected", callable_mp(this, &SceneMultiplayer::_server_disconnected)); + } + replicator->on_reset(); +} + +Ref<MultiplayerPeer> SceneMultiplayer::get_multiplayer_peer() { + return multiplayer_peer; +} + +void SceneMultiplayer::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) { + ERR_FAIL_COND_MSG(root_path.is_empty(), "Multiplayer root was not initialized. If you are using custom multiplayer, remember to set the root path via SceneMultiplayer.set_root_path before using it."); + ERR_FAIL_COND_MSG(p_packet_len < 1, "Invalid packet received. Size too small."); + +#ifdef DEBUG_ENABLED + profile_bandwidth("in", p_packet_len); +#endif + + // Extract the `packet_type` from the LSB three bits: + uint8_t packet_type = p_packet[0] & CMD_MASK; + + switch (packet_type) { + case NETWORK_COMMAND_SIMPLIFY_PATH: { + cache->process_simplify_path(p_from, p_packet, p_packet_len); + } break; + + case NETWORK_COMMAND_CONFIRM_PATH: { + cache->process_confirm_path(p_from, p_packet, p_packet_len); + } break; + + case NETWORK_COMMAND_REMOTE_CALL: { + rpc->process_rpc(p_from, p_packet, p_packet_len); + } break; + + case NETWORK_COMMAND_RAW: { + _process_raw(p_from, p_packet, p_packet_len); + } break; + case NETWORK_COMMAND_SPAWN: { + replicator->on_spawn_receive(p_from, p_packet, p_packet_len); + } break; + case NETWORK_COMMAND_DESPAWN: { + replicator->on_despawn_receive(p_from, p_packet, p_packet_len); + } break; + case NETWORK_COMMAND_SYNC: { + replicator->on_sync_receive(p_from, p_packet, p_packet_len); + } break; + } +} + +void SceneMultiplayer::_add_peer(int p_id) { + connected_peers.insert(p_id); + cache->on_peer_change(p_id, true); + replicator->on_peer_change(p_id, true); + emit_signal(SNAME("peer_connected"), p_id); +} + +void SceneMultiplayer::_del_peer(int p_id) { + replicator->on_peer_change(p_id, false); + cache->on_peer_change(p_id, false); + connected_peers.erase(p_id); + emit_signal(SNAME("peer_disconnected"), p_id); +} + +void SceneMultiplayer::_connected_to_server() { + emit_signal(SNAME("connected_to_server")); +} + +void SceneMultiplayer::_connection_failed() { + emit_signal(SNAME("connection_failed")); +} + +void SceneMultiplayer::_server_disconnected() { + replicator->on_reset(); + emit_signal(SNAME("server_disconnected")); +} + +Error SceneMultiplayer::send_bytes(Vector<uint8_t> p_data, int p_to, MultiplayerPeer::TransferMode p_mode, int p_channel) { + ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet."); + ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no multiplayer peer is active."); + ERR_FAIL_COND_V_MSG(multiplayer_peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a multiplayer peer which is not connected."); + + if (packet_cache.size() < p_data.size() + 1) { + packet_cache.resize(p_data.size() + 1); + } + + const uint8_t *r = p_data.ptr(); + packet_cache.write[0] = NETWORK_COMMAND_RAW; + memcpy(&packet_cache.write[1], &r[0], p_data.size()); + + multiplayer_peer->set_target_peer(p_to); + multiplayer_peer->set_transfer_channel(p_channel); + multiplayer_peer->set_transfer_mode(p_mode); + + return multiplayer_peer->put_packet(packet_cache.ptr(), p_data.size() + 1); +} + +void SceneMultiplayer::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) { + ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small."); + + Vector<uint8_t> out; + int len = p_packet_len - 1; + out.resize(len); + { + uint8_t *w = out.ptrw(); + memcpy(&w[0], &p_packet[1], len); + } + emit_signal(SNAME("peer_packet"), p_from, out); +} + +int SceneMultiplayer::get_unique_id() { + ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), 0, "No multiplayer peer is assigned. Unable to get unique ID."); + return multiplayer_peer->get_unique_id(); +} + +void SceneMultiplayer::set_refuse_new_connections(bool p_refuse) { + ERR_FAIL_COND_MSG(!multiplayer_peer.is_valid(), "No multiplayer peer is assigned. Unable to set 'refuse_new_connections'."); + multiplayer_peer->set_refuse_new_connections(p_refuse); +} + +bool SceneMultiplayer::is_refusing_new_connections() const { + ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), false, "No multiplayer peer is assigned. Unable to get 'refuse_new_connections'."); + return multiplayer_peer->is_refusing_new_connections(); +} + +Vector<int> SceneMultiplayer::get_peer_ids() { + ERR_FAIL_COND_V_MSG(!multiplayer_peer.is_valid(), Vector<int>(), "No multiplayer peer is assigned. Assume no peers are connected."); + + Vector<int> ret; + for (const int &E : connected_peers) { + ret.push_back(E); + } + + return ret; +} + +void SceneMultiplayer::set_allow_object_decoding(bool p_enable) { + allow_object_decoding = p_enable; +} + +bool SceneMultiplayer::is_object_decoding_allowed() const { + return allow_object_decoding; +} + +String SceneMultiplayer::get_rpc_md5(const Object *p_obj) { + return rpc->get_rpc_md5(p_obj); +} + +Error SceneMultiplayer::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { + return rpc->rpcp(p_obj, p_peer_id, p_method, p_arg, p_argcount); +} + +Error SceneMultiplayer::object_configuration_add(Object *p_obj, Variant p_config) { + if (p_obj == nullptr && p_config.get_type() == Variant::NODE_PATH) { + set_root_path(p_config); + return OK; + } + MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(p_config.get_validated_object()); + MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object()); + if (spawner) { + return replicator->on_spawn(p_obj, p_config); + } else if (sync) { + return replicator->on_replication_start(p_obj, p_config); + } + return ERR_INVALID_PARAMETER; +} + +Error SceneMultiplayer::object_configuration_remove(Object *p_obj, Variant p_config) { + if (p_obj == nullptr && p_config.get_type() == Variant::NODE_PATH) { + ERR_FAIL_COND_V(root_path != p_config.operator NodePath(), ERR_INVALID_PARAMETER); + set_root_path(NodePath()); + return OK; + } + MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(p_config.get_validated_object()); + MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object()); + if (spawner) { + return replicator->on_despawn(p_obj, p_config); + } + if (sync) { + return replicator->on_replication_stop(p_obj, p_config); + } + return ERR_INVALID_PARAMETER; +} + +void SceneMultiplayer::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_root_path", "path"), &SceneMultiplayer::set_root_path); + ClassDB::bind_method(D_METHOD("get_root_path"), &SceneMultiplayer::get_root_path); + ClassDB::bind_method(D_METHOD("clear"), &SceneMultiplayer::clear); + ClassDB::bind_method(D_METHOD("set_refuse_new_connections", "refuse"), &SceneMultiplayer::set_refuse_new_connections); + ClassDB::bind_method(D_METHOD("is_refusing_new_connections"), &SceneMultiplayer::is_refusing_new_connections); + ClassDB::bind_method(D_METHOD("set_allow_object_decoding", "enable"), &SceneMultiplayer::set_allow_object_decoding); + ClassDB::bind_method(D_METHOD("is_object_decoding_allowed"), &SceneMultiplayer::is_object_decoding_allowed); + ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode", "channel"), &SceneMultiplayer::send_bytes, DEFVAL(MultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(MultiplayerPeer::TRANSFER_MODE_RELIABLE), DEFVAL(0)); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_path"), "set_root_path", "get_root_path"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_connections"), "set_refuse_new_connections", "is_refusing_new_connections"); + ADD_PROPERTY_DEFAULT("refuse_new_connections", false); + + ADD_SIGNAL(MethodInfo("peer_packet", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::PACKED_BYTE_ARRAY, "packet"))); +} + +SceneMultiplayer::SceneMultiplayer() { + replicator = Ref<SceneReplicationInterface>(memnew(SceneReplicationInterface(this))); + rpc = Ref<SceneRPCInterface>(memnew(SceneRPCInterface(this))); + cache = Ref<SceneCacheInterface>(memnew(SceneCacheInterface(this))); +} + +SceneMultiplayer::~SceneMultiplayer() { + clear(); +} diff --git a/modules/multiplayer/scene_multiplayer.h b/modules/multiplayer/scene_multiplayer.h new file mode 100644 index 0000000000..a99cca7b21 --- /dev/null +++ b/modules/multiplayer/scene_multiplayer.h @@ -0,0 +1,136 @@ +/*************************************************************************/ +/* scene_multiplayer.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 SCENE_MULTIPLAYER_H +#define SCENE_MULTIPLAYER_H + +#include "scene/main/multiplayer_api.h" + +#include "scene_cache_interface.h" +#include "scene_replication_interface.h" +#include "scene_rpc_interface.h" + +class SceneMultiplayer : public MultiplayerAPI { + GDCLASS(SceneMultiplayer, MultiplayerAPI); + +public: + enum NetworkCommands { + NETWORK_COMMAND_REMOTE_CALL = 0, + NETWORK_COMMAND_SIMPLIFY_PATH, + NETWORK_COMMAND_CONFIRM_PATH, + NETWORK_COMMAND_RAW, + NETWORK_COMMAND_SPAWN, + NETWORK_COMMAND_DESPAWN, + NETWORK_COMMAND_SYNC, + }; + + // For each command, the 4 MSB can contain custom flags, as defined by subsystems. + enum { + CMD_FLAG_0_SHIFT = 4, + CMD_FLAG_1_SHIFT = 5, + CMD_FLAG_2_SHIFT = 6, + CMD_FLAG_3_SHIFT = 7, + }; + + // This is the mask that will be used to extract the command. + enum { + CMD_MASK = 7, // 0x7 -> 0b00001111 + }; + +private: + Ref<MultiplayerPeer> multiplayer_peer; + HashSet<int> connected_peers; + int remote_sender_id = 0; + int remote_sender_override = 0; + + Vector<uint8_t> packet_cache; + + NodePath root_path; + bool allow_object_decoding = false; + + Ref<SceneCacheInterface> cache; + Ref<SceneReplicationInterface> replicator; + Ref<SceneRPCInterface> rpc; + +protected: + static void _bind_methods(); + + void _process_packet(int p_from, const uint8_t *p_packet, int p_packet_len); + void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len); + + void _add_peer(int p_id); + void _del_peer(int p_id); + void _connected_to_server(); + void _connection_failed(); + void _server_disconnected(); + +public: + virtual void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) override; + virtual Ref<MultiplayerPeer> get_multiplayer_peer() override; + + virtual Error poll() override; + virtual int get_unique_id() override; + virtual Vector<int> get_peer_ids() override; + virtual int get_remote_sender_id() override { return remote_sender_override ? remote_sender_override : remote_sender_id; } + + virtual Error rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) override; + + virtual Error object_configuration_add(Object *p_obj, Variant p_config) override; + virtual Error object_configuration_remove(Object *p_obj, Variant p_config) override; + + void clear(); + + // Usually from object_configuration_add/remove + void set_root_path(const NodePath &p_path); + NodePath get_root_path() const; + + Error send_bytes(Vector<uint8_t> p_data, int p_to = MultiplayerPeer::TARGET_PEER_BROADCAST, MultiplayerPeer::TransferMode p_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE, int p_channel = 0); + String get_rpc_md5(const Object *p_obj); + + const HashSet<int> get_connected_peers() const { return connected_peers; } + + void set_remote_sender_override(int p_id) { remote_sender_override = p_id; } + void set_refuse_new_connections(bool p_refuse); + bool is_refusing_new_connections() const; + + void set_allow_object_decoding(bool p_enable); + bool is_object_decoding_allowed() const; + + Ref<SceneCacheInterface> get_path_cache() { return cache; } + +#ifdef DEBUG_ENABLED + void profile_bandwidth(const String &p_inout, int p_size); +#endif + + SceneMultiplayer(); + ~SceneMultiplayer(); +}; + +#endif // SCENE_MULTIPLAYER_H diff --git a/scene/resources/scene_replication_config.cpp b/modules/multiplayer/scene_replication_config.cpp index 6789f9f7d5..ae06516b7b 100644 --- a/scene/resources/scene_replication_config.cpp +++ b/modules/multiplayer/scene_replication_config.cpp @@ -30,7 +30,7 @@ #include "scene_replication_config.h" -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/node.h" bool SceneReplicationConfig::_set(const StringName &p_name, const Variant &p_value) { diff --git a/scene/resources/scene_replication_config.h b/modules/multiplayer/scene_replication_config.h index ab3658d2a7..ab3658d2a7 100644 --- a/scene/resources/scene_replication_config.h +++ b/modules/multiplayer/scene_replication_config.h diff --git a/scene/multiplayer/scene_replication_interface.cpp b/modules/multiplayer/scene_replication_interface.cpp index e4715ceb88..2dc0766fc3 100644 --- a/scene/multiplayer/scene_replication_interface.cpp +++ b/modules/multiplayer/scene_replication_interface.cpp @@ -32,21 +32,15 @@ #include "core/io/marshalls.h" #include "scene/main/node.h" -#include "scene/multiplayer/multiplayer_spawner.h" -#include "scene/multiplayer/multiplayer_synchronizer.h" + +#include "multiplayer_spawner.h" +#include "multiplayer_synchronizer.h" +#include "scene_multiplayer.h" #define MAKE_ROOM(m_amount) \ if (packet_cache.size() < m_amount) \ packet_cache.resize(m_amount); -MultiplayerReplicationInterface *SceneReplicationInterface::_create(MultiplayerAPI *p_multiplayer) { - return memnew(SceneReplicationInterface(p_multiplayer)); -} - -void SceneReplicationInterface::make_default() { - MultiplayerAPI::create_default_replication_interface = _create; -} - void SceneReplicationInterface::_free_remotes(int p_id) { const HashMap<uint32_t, ObjectID> remotes = rep_state->peer_get_remotes(p_id); for (const KeyValue<uint32_t, ObjectID> &E : remotes) { @@ -60,14 +54,13 @@ void SceneReplicationInterface::on_peer_change(int p_id, bool p_connected) { if (p_connected) { rep_state->on_peer_change(p_id, p_connected); for (const ObjectID &oid : rep_state->get_spawned_nodes()) { - _send_spawn(rep_state->get_node(oid), rep_state->get_spawner(oid), p_id); + _update_spawn_visibility(p_id, oid); } - for (const ObjectID &oid : rep_state->get_path_only_nodes()) { - Node *node = rep_state->get_node(oid); + for (const ObjectID &oid : rep_state->get_synced_nodes()) { MultiplayerSynchronizer *sync = rep_state->get_synchronizer(oid); - ERR_CONTINUE(!node || !sync); + ERR_CONTINUE(!sync); // ERR_BUG if (sync->is_multiplayer_authority()) { - rep_state->peer_add_node(p_id, oid); + _update_sync_visibility(p_id, oid); } } } else { @@ -97,7 +90,13 @@ Error SceneReplicationInterface::on_spawn(Object *p_obj, Variant p_config) { ERR_FAIL_COND_V(!spawner, ERR_INVALID_PARAMETER); Error err = rep_state->config_add_spawn(node, spawner); ERR_FAIL_COND_V(err != OK, err); - return _send_spawn(node, spawner, 0); + const ObjectID oid = node->get_instance_id(); + if (multiplayer->has_multiplayer_peer() && spawner->is_multiplayer_authority()) { + rep_state->ensure_net_id(oid); + _update_spawn_visibility(0, oid); + } + ERR_FAIL_COND_V(err != OK, err); + return OK; } Error SceneReplicationInterface::on_despawn(Object *p_obj, Variant p_config) { @@ -105,9 +104,19 @@ Error SceneReplicationInterface::on_despawn(Object *p_obj, Variant p_config) { ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER); MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(p_config.get_validated_object()); ERR_FAIL_COND_V(!p_obj || !spawner, ERR_INVALID_PARAMETER); - Error err = rep_state->config_del_spawn(node, spawner); - ERR_FAIL_COND_V(err != OK, err); - return _send_despawn(node, 0); + // Forcibly despawn to all peers that knowns me. + int len = 0; + Error err = _make_despawn_packet(node, len); + ERR_FAIL_COND_V(err != OK, ERR_BUG); + const ObjectID oid = p_obj->get_instance_id(); + for (int pid : rep_state->get_peers()) { + if (!rep_state->is_peer_spawn(pid, oid)) { + continue; + } + _send_raw(packet_cache.ptr(), len, pid, true); + } + // Also remove spawner tracking from the replication state. + return rep_state->config_del_spawn(node, spawner); } Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_config) { @@ -115,7 +124,15 @@ Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_c ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER); MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object()); ERR_FAIL_COND_V(!sync, ERR_INVALID_PARAMETER); + + // Add to synchronizer list and setup visibility. rep_state->config_add_sync(node, sync); + const ObjectID oid = node->get_instance_id(); + sync->connect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed), varray(oid)); + if (multiplayer->has_multiplayer_peer() && sync->is_multiplayer_authority()) { + _update_sync_visibility(0, oid); + } + // Try to apply initial state if spawning (hack to apply if before ready). if (pending_spawn == p_obj->get_instance_id()) { pending_spawn = ObjectID(); // Make sure this only happens once. @@ -127,9 +144,6 @@ Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_c ERR_FAIL_COND_V(err, err); err = MultiplayerSynchronizer::set_state(props, node, vars); ERR_FAIL_COND_V(err, err); - } else if (multiplayer->has_multiplayer_peer() && sync->is_multiplayer_authority()) { - // Either it's a spawn or a static sync, in any case add it to the list of known nodes. - rep_state->peer_add_node(0, p_obj->get_instance_id()); } return OK; } @@ -138,10 +152,103 @@ Error SceneReplicationInterface::on_replication_stop(Object *p_obj, Variant p_co Node *node = Object::cast_to<Node>(p_obj); ERR_FAIL_COND_V(!node || p_config.get_type() != Variant::OBJECT, ERR_INVALID_PARAMETER); MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object()); - ERR_FAIL_COND_V(!p_obj || !sync, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(!sync, ERR_INVALID_PARAMETER); + sync->disconnect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed)); return rep_state->config_del_sync(node, sync); } +void SceneReplicationInterface::_visibility_changed(int p_peer, ObjectID p_oid) { + if (rep_state->is_spawned_node(p_oid)) { + _update_spawn_visibility(p_peer, p_oid); + } + if (rep_state->is_synced_node(p_oid)) { + _update_sync_visibility(p_peer, p_oid); + } +} + +Error SceneReplicationInterface::_update_sync_visibility(int p_peer, const ObjectID &p_oid) { + MultiplayerSynchronizer *sync = rep_state->get_synchronizer(p_oid); + ERR_FAIL_COND_V(!sync || !sync->is_multiplayer_authority(), ERR_BUG); + bool is_visible = sync->is_visible_to(p_peer); + if (p_peer == 0) { + for (int pid : rep_state->get_peers()) { + // Might be visible to this specific peer. + is_visible = is_visible || sync->is_visible_to(pid); + if (rep_state->is_peer_sync(pid, p_oid) == is_visible) { + continue; + } + if (is_visible) { + rep_state->peer_add_sync(pid, p_oid); + } else { + rep_state->peer_del_sync(pid, p_oid); + } + } + return OK; + } else { + if (is_visible == rep_state->is_peer_sync(p_peer, p_oid)) { + return OK; + } + if (is_visible) { + return rep_state->peer_add_sync(p_peer, p_oid); + } else { + return rep_state->peer_del_sync(p_peer, p_oid); + } + } +} + +Error SceneReplicationInterface::_update_spawn_visibility(int p_peer, const ObjectID &p_oid) { + MultiplayerSpawner *spawner = rep_state->get_spawner(p_oid); + MultiplayerSynchronizer *sync = rep_state->get_synchronizer(p_oid); + Node *node = Object::cast_to<Node>(ObjectDB::get_instance(p_oid)); + ERR_FAIL_COND_V(!node || !spawner || !spawner->is_multiplayer_authority(), ERR_BUG); + bool is_visible = !sync || sync->is_visible_to(p_peer); + // Spawn (and despawn) when needed. + HashSet<int> to_spawn; + HashSet<int> to_despawn; + if (p_peer) { + if (is_visible == rep_state->is_peer_spawn(p_peer, p_oid)) { + return OK; + } + if (is_visible) { + to_spawn.insert(p_peer); + } else { + to_despawn.insert(p_peer); + } + } else { + // Check visibility for each peers. + for (int pid : rep_state->get_peers()) { + bool peer_visible = is_visible || sync->is_visible_to(pid); + if (peer_visible == rep_state->is_peer_spawn(pid, p_oid)) { + continue; + } + if (peer_visible) { + to_spawn.insert(pid); + } else { + to_despawn.insert(pid); + } + } + } + if (to_spawn.size()) { + int len = 0; + _make_spawn_packet(node, len); + for (int pid : to_spawn) { + int path_id; + multiplayer->get_path_cache()->send_object_cache(spawner, pid, path_id); + _send_raw(packet_cache.ptr(), len, pid, true); + rep_state->peer_add_spawn(pid, p_oid); + } + } + if (to_despawn.size()) { + int len = 0; + _make_despawn_packet(node, len); + for (int pid : to_despawn) { + rep_state->peer_del_spawn(pid, p_oid); + _send_raw(packet_cache.ptr(), len, pid, true); + } + } + return OK; +} + Error SceneReplicationInterface::_send_raw(const uint8_t *p_buffer, int p_size, int p_peer, bool p_reliable) { ERR_FAIL_COND_V(!p_buffer || p_size < 1, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!multiplayer, ERR_UNCONFIGURED); @@ -154,22 +261,24 @@ Error SceneReplicationInterface::_send_raw(const uint8_t *p_buffer, int p_size, Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer(); peer->set_target_peer(p_peer); peer->set_transfer_channel(0); - peer->set_transfer_mode(p_reliable ? Multiplayer::TRANSFER_MODE_RELIABLE : Multiplayer::TRANSFER_MODE_UNRELIABLE); + peer->set_transfer_mode(p_reliable ? MultiplayerPeer::TRANSFER_MODE_RELIABLE : MultiplayerPeer::TRANSFER_MODE_UNRELIABLE); return peer->put_packet(p_buffer, p_size); } -Error SceneReplicationInterface::_send_spawn(Node *p_node, MultiplayerSpawner *p_spawner, int p_peer) { - ERR_FAIL_COND_V(p_peer < 0, ERR_BUG); +Error SceneReplicationInterface::_make_spawn_packet(Node *p_node, int &r_len) { ERR_FAIL_COND_V(!multiplayer, ERR_BUG); - ERR_FAIL_COND_V(!p_spawner || !p_node, ERR_BUG); const ObjectID oid = p_node->get_instance_id(); - uint32_t nid = rep_state->ensure_net_id(oid); + MultiplayerSpawner *spawner = rep_state->get_spawner(oid); + ERR_FAIL_COND_V(!spawner || !p_node, ERR_BUG); + + uint32_t nid = rep_state->get_net_id(oid); + ERR_FAIL_COND_V(!nid, ERR_UNCONFIGURED); // Prepare custom arg and scene_id - uint8_t scene_id = p_spawner->find_spawnable_scene_index_from_object(oid); + uint8_t scene_id = spawner->find_spawnable_scene_index_from_object(oid); bool is_custom = scene_id == MultiplayerSpawner::INVALID_ID; - Variant spawn_arg = p_spawner->get_spawn_argument(oid); + Variant spawn_arg = spawner->get_spawn_argument(oid); int spawn_arg_size = 0; if (is_custom) { Error err = MultiplayerAPI::encode_and_compress_variant(spawn_arg, nullptr, spawn_arg_size, false); @@ -181,7 +290,8 @@ Error SceneReplicationInterface::_send_spawn(Node *p_node, MultiplayerSpawner *p Vector<Variant> state_vars; Vector<const Variant *> state_varp; MultiplayerSynchronizer *synchronizer = rep_state->get_synchronizer(oid); - if (synchronizer && synchronizer->get_replication_config().is_valid()) { + if (synchronizer) { + ERR_FAIL_COND_V(synchronizer->get_replication_config().is_null(), ERR_BUG); const List<NodePath> props = synchronizer->get_replication_config()->get_spawn_properties(); Error err = MultiplayerSynchronizer::get_state(props, p_node, state_vars, state_varp); ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to retrieve spawn state."); @@ -189,18 +299,13 @@ Error SceneReplicationInterface::_send_spawn(Node *p_node, MultiplayerSpawner *p ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to encode spawn state."); } - // Prepare simplified path. - NodePath rel_path = multiplayer->get_root_path().rel_path_to(p_spawner->get_path()); - - int path_id = 0; - multiplayer->send_object_cache(p_spawner, rel_path, p_peer, path_id); - - // Encode name and parent ID. + // Encode scene ID, path ID, net ID, node name. + int path_id = multiplayer->get_path_cache()->make_object_cache(spawner); CharString cname = p_node->get_name().operator String().utf8(); int nlen = encode_cstring(cname.get_data(), nullptr); MAKE_ROOM(1 + 1 + 4 + 4 + 4 + nlen + (is_custom ? 4 + spawn_arg_size : 0) + state_size); uint8_t *ptr = packet_cache.ptrw(); - ptr[0] = (uint8_t)MultiplayerAPI::NETWORK_COMMAND_SPAWN; + ptr[0] = (uint8_t)SceneMultiplayer::NETWORK_COMMAND_SPAWN; ptr[1] = scene_id; int ofs = 2; ofs += encode_uint32(path_id, &ptr[ofs]); @@ -220,22 +325,20 @@ Error SceneReplicationInterface::_send_spawn(Node *p_node, MultiplayerSpawner *p ERR_FAIL_COND_V(err, err); ofs += state_size; } - Error err = _send_raw(ptr, ofs, p_peer, true); - ERR_FAIL_COND_V(err, err); - return rep_state->peer_add_node(p_peer, oid); + r_len = ofs; + return OK; } -Error SceneReplicationInterface::_send_despawn(Node *p_node, int p_peer) { +Error SceneReplicationInterface::_make_despawn_packet(Node *p_node, int &r_len) { const ObjectID oid = p_node->get_instance_id(); MAKE_ROOM(5); uint8_t *ptr = packet_cache.ptrw(); - ptr[0] = (uint8_t)MultiplayerAPI::NETWORK_COMMAND_DESPAWN; + ptr[0] = (uint8_t)SceneMultiplayer::NETWORK_COMMAND_DESPAWN; int ofs = 1; uint32_t nid = rep_state->get_net_id(oid); ofs += encode_uint32(nid, &ptr[ofs]); - Error err = _send_raw(ptr, ofs, p_peer, true); - ERR_FAIL_COND_V(err, err); - return rep_state->peer_del_node(p_peer, oid); + r_len = ofs; + return OK; } Error SceneReplicationInterface::on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) { @@ -245,7 +348,7 @@ Error SceneReplicationInterface::on_spawn_receive(int p_from, const uint8_t *p_b ofs += 1; uint32_t node_target = decode_uint32(&p_buffer[ofs]); ofs += 4; - MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(multiplayer->get_cached_object(p_from, node_target)); + MultiplayerSpawner *spawner = Object::cast_to<MultiplayerSpawner>(multiplayer->get_path_cache()->get_cached_object(p_from, node_target)); ERR_FAIL_COND_V(!spawner, ERR_DOES_NOT_EXIST); ERR_FAIL_COND_V(p_from != spawner->get_multiplayer_authority(), ERR_UNAUTHORIZED); @@ -316,25 +419,40 @@ Error SceneReplicationInterface::on_despawn_receive(int p_from, const uint8_t *p } void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) { - const HashSet<ObjectID> &known = rep_state->get_known_nodes(p_peer); - if (known.is_empty()) { + const HashSet<ObjectID> &to_sync = rep_state->get_peer_sync_nodes(p_peer); + if (to_sync.is_empty()) { return; } MAKE_ROOM(sync_mtu); uint8_t *ptr = packet_cache.ptrw(); - ptr[0] = MultiplayerAPI::NETWORK_COMMAND_SYNC; + ptr[0] = SceneMultiplayer::NETWORK_COMMAND_SYNC; int ofs = 1; ofs += encode_uint16(rep_state->peer_sync_next(p_peer), &ptr[1]); // Can only send updates for already notified nodes. // This is a lazy implementation, we could optimize much more here with by grouping by replication config. - for (const ObjectID &oid : known) { + for (const ObjectID &oid : to_sync) { if (!rep_state->update_sync_time(oid, p_msec)) { continue; // nothing to sync. } MultiplayerSynchronizer *sync = rep_state->get_synchronizer(oid); - ERR_CONTINUE(!sync); + ERR_CONTINUE(!sync || !sync->get_replication_config().is_valid()); Node *node = rep_state->get_node(oid); ERR_CONTINUE(!node); + uint32_t net_id = rep_state->get_net_id(oid); + if (net_id == 0 || (net_id & 0x80000000)) { + int path_id = 0; + bool verified = multiplayer->get_path_cache()->send_object_cache(sync, p_peer, path_id); + ERR_CONTINUE_MSG(path_id < 0, "This should never happen!"); + if (net_id == 0) { + // First time path based ID. + net_id = path_id | 0x80000000; + rep_state->set_net_id(oid, net_id | 0x80000000); + } + if (!verified) { + // The path based sync is not yet confirmed, skipping. + continue; + } + } int size; Vector<Variant> vars; Vector<const Variant *> varp; @@ -351,16 +469,6 @@ void SceneReplicationInterface::_send_sync(int p_peer, uint64_t p_msec) { ofs = 3; } if (size) { - uint32_t net_id = rep_state->get_net_id(oid); - if (net_id == 0 || (net_id & 0x80000000)) { - // First time path based ID. - NodePath rel_path = multiplayer->get_root_path().rel_path_to(sync->get_path()); - int path_id = 0; - multiplayer->send_object_cache(sync, rel_path, p_peer, path_id); - ERR_CONTINUE_MSG(net_id && net_id != (uint32_t(path_id) | 0x80000000), "This should never happen!"); - net_id = path_id; - rep_state->set_net_id(oid, net_id | 0x80000000); - } ofs += encode_uint32(rep_state->get_net_id(oid), &ptr[ofs]); ofs += encode_uint32(size, &ptr[ofs]); MultiplayerAPI::encode_and_compress_variants(varp.ptrw(), varp.size(), &ptr[ofs], size); @@ -385,7 +493,7 @@ Error SceneReplicationInterface::on_sync_receive(int p_from, const uint8_t *p_bu ofs += 4; Node *node = nullptr; if (net_id & 0x80000000) { - MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(multiplayer->get_cached_object(p_from, net_id & 0x7FFFFFFF)); + MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(multiplayer->get_path_cache()->get_cached_object(p_from, net_id & 0x7FFFFFFF)); ERR_FAIL_COND_V(!sync || sync->get_multiplayer_authority() != p_from, ERR_UNAUTHORIZED); node = sync->get_node(sync->get_root_path()); } else { diff --git a/scene/multiplayer/scene_replication_interface.h b/modules/multiplayer/scene_replication_interface.h index 60ac95c93c..8981647429 100644 --- a/scene/multiplayer/scene_replication_interface.h +++ b/modules/multiplayer/scene_replication_interface.h @@ -28,26 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_TREE_REPLICATOR_INTERFACE_H -#define SCENE_TREE_REPLICATOR_INTERFACE_H +#ifndef SCENE_REPLICATION_INTERFACE_H +#define SCENE_REPLICATION_INTERFACE_H -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" -#include "scene/multiplayer/scene_replication_state.h" +#include "scene_replication_state.h" -class SceneReplicationInterface : public MultiplayerReplicationInterface { - GDCLASS(SceneReplicationInterface, MultiplayerReplicationInterface); +class SceneMultiplayer; + +class SceneReplicationInterface : public RefCounted { + GDCLASS(SceneReplicationInterface, RefCounted); private: void _send_sync(int p_peer, uint64_t p_msec); - Error _send_spawn(Node *p_node, MultiplayerSpawner *p_spawner, int p_peer); - Error _send_despawn(Node *p_node, int p_peer); + Error _make_spawn_packet(Node *p_node, int &r_len); + Error _make_despawn_packet(Node *p_node, int &r_len); Error _send_raw(const uint8_t *p_buffer, int p_size, int p_peer, bool p_reliable); + void _visibility_changed(int p_peer, ObjectID p_oid); + Error _update_sync_visibility(int p_peer, const ObjectID &p_oid); + Error _update_spawn_visibility(int p_peer, const ObjectID &p_oid); void _free_remotes(int p_peer); Ref<SceneReplicationState> rep_state; - MultiplayerAPI *multiplayer = nullptr; + SceneMultiplayer *multiplayer = nullptr; PackedByteArray packet_cache; int sync_mtu = 1350; // Highly dependent on underlying protocol. @@ -56,29 +61,26 @@ private: const uint8_t *pending_buffer = nullptr; int pending_buffer_size = 0; -protected: - static MultiplayerReplicationInterface *_create(MultiplayerAPI *p_multiplayer); - public: static void make_default(); - virtual void on_reset() override; - virtual void on_peer_change(int p_id, bool p_connected) override; + void on_reset(); + void on_peer_change(int p_id, bool p_connected); - virtual Error on_spawn(Object *p_obj, Variant p_config) override; - virtual Error on_despawn(Object *p_obj, Variant p_config) override; - virtual Error on_replication_start(Object *p_obj, Variant p_config) override; - virtual Error on_replication_stop(Object *p_obj, Variant p_config) override; - virtual void on_network_process() override; + Error on_spawn(Object *p_obj, Variant p_config); + Error on_despawn(Object *p_obj, Variant p_config); + Error on_replication_start(Object *p_obj, Variant p_config); + Error on_replication_stop(Object *p_obj, Variant p_config); + void on_network_process(); - virtual Error on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) override; - virtual Error on_despawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) override; - virtual Error on_sync_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len) override; + Error on_spawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len); + Error on_despawn_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len); + Error on_sync_receive(int p_from, const uint8_t *p_buffer, int p_buffer_len); - SceneReplicationInterface(MultiplayerAPI *p_multiplayer) { + SceneReplicationInterface(SceneMultiplayer *p_multiplayer) { rep_state.instantiate(); multiplayer = p_multiplayer; } }; -#endif // SCENE_TREE_REPLICATOR_INTERFACE_H +#endif // SCENE_REPLICATION_INTERFACE_H diff --git a/scene/multiplayer/scene_replication_state.cpp b/modules/multiplayer/scene_replication_state.cpp index 937b30cb36..5ad27e9a97 100644 --- a/scene/multiplayer/scene_replication_state.cpp +++ b/modules/multiplayer/scene_replication_state.cpp @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene/multiplayer/scene_replication_state.h" +#include "scene_replication_state.h" -#include "core/multiplayer/multiplayer_api.h" -#include "scene/multiplayer/multiplayer_spawner.h" -#include "scene/multiplayer/multiplayer_synchronizer.h" #include "scene/scene_string_names.h" +#include "multiplayer_spawner.h" +#include "multiplayer_synchronizer.h" + SceneReplicationState::TrackedNode &SceneReplicationState::_track(const ObjectID &p_id) { if (!tracked_nodes.has(p_id)) { tracked_nodes[p_id] = TrackedNode(p_id); @@ -56,7 +56,8 @@ void SceneReplicationState::_untrack(const ObjectID &p_id) { // If we spawned or synced it, we need to remove it from any peer it was sent to. if (net_id || peer == 0) { for (KeyValue<int, PeerInfo> &E : peers_info) { - E.value.known_nodes.erase(p_id); + E.value.sync_nodes.erase(p_id); + E.value.spawn_nodes.erase(p_id); } } } @@ -93,11 +94,6 @@ bool SceneReplicationState::update_sync_time(const ObjectID &p_id, uint64_t p_ms return false; } -const HashSet<ObjectID> SceneReplicationState::get_known_nodes(int p_peer) { - ERR_FAIL_COND_V(!peers_info.has(p_peer), HashSet<ObjectID>()); - return peers_info[p_peer].known_nodes; -} - uint32_t SceneReplicationState::get_net_id(const ObjectID &p_id) const { const TrackedNode *tnode = tracked_nodes.getptr(p_id); ERR_FAIL_COND_V(!tnode, 0); @@ -147,8 +143,6 @@ Error SceneReplicationState::config_add_spawn(Node *p_node, MultiplayerSpawner * ERR_FAIL_COND_V(tobj.spawner != ObjectID(), ERR_ALREADY_IN_USE); tobj.spawner = p_spawner->get_instance_id(); spawned_nodes.insert(oid); - // The spawner may be notified after the synchronizer. - path_only_nodes.erase(oid); return OK; } @@ -159,6 +153,9 @@ Error SceneReplicationState::config_del_spawn(Node *p_node, MultiplayerSpawner * ERR_FAIL_COND_V(tobj.spawner != p_spawner->get_instance_id(), ERR_INVALID_PARAMETER); tobj.spawner = ObjectID(); spawned_nodes.erase(oid); + for (KeyValue<int, PeerInfo> &E : peers_info) { + E.value.spawn_nodes.erase(oid); + } return OK; } @@ -167,10 +164,7 @@ Error SceneReplicationState::config_add_sync(Node *p_node, MultiplayerSynchroniz TrackedNode &tobj = _track(oid); ERR_FAIL_COND_V(tobj.synchronizer != ObjectID(), ERR_ALREADY_IN_USE); tobj.synchronizer = p_sync->get_instance_id(); - // If it doesn't have a spawner, we might need to assign ID for this node using it's path. - if (tobj.spawner.is_null()) { - path_only_nodes.insert(oid); - } + synced_nodes.insert(oid); return OK; } @@ -180,38 +174,57 @@ Error SceneReplicationState::config_del_sync(Node *p_node, MultiplayerSynchroniz TrackedNode &tobj = _track(oid); ERR_FAIL_COND_V(tobj.synchronizer != p_sync->get_instance_id(), ERR_INVALID_PARAMETER); tobj.synchronizer = ObjectID(); - if (path_only_nodes.has(oid)) { - p_node->disconnect(SceneStringNames::get_singleton()->tree_exited, callable_mp(this, &SceneReplicationState::_untrack)); - _untrack(oid); - path_only_nodes.erase(oid); + synced_nodes.erase(oid); + for (KeyValue<int, PeerInfo> &E : peers_info) { + E.value.sync_nodes.erase(oid); } return OK; } -Error SceneReplicationState::peer_add_node(int p_peer, const ObjectID &p_id) { - if (p_peer) { - ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER); - peers_info[p_peer].known_nodes.insert(p_id); - } else { - for (KeyValue<int, PeerInfo> &E : peers_info) { - E.value.known_nodes.insert(p_id); - } - } +Error SceneReplicationState::peer_add_sync(int p_peer, const ObjectID &p_id) { + ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER); + peers_info[p_peer].sync_nodes.insert(p_id); return OK; } -Error SceneReplicationState::peer_del_node(int p_peer, const ObjectID &p_id) { - if (p_peer) { - ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER); - peers_info[p_peer].known_nodes.erase(p_id); - } else { - for (KeyValue<int, PeerInfo> &E : peers_info) { - E.value.known_nodes.erase(p_id); - } - } +Error SceneReplicationState::peer_del_sync(int p_peer, const ObjectID &p_id) { + ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER); + peers_info[p_peer].sync_nodes.erase(p_id); + return OK; +} + +const HashSet<ObjectID> SceneReplicationState::get_peer_sync_nodes(int p_peer) { + ERR_FAIL_COND_V(!peers_info.has(p_peer), HashSet<ObjectID>()); + return peers_info[p_peer].sync_nodes; +} + +bool SceneReplicationState::is_peer_sync(int p_peer, const ObjectID &p_id) const { + ERR_FAIL_COND_V(!peers_info.has(p_peer), false); + return peers_info[p_peer].sync_nodes.has(p_id); +} + +Error SceneReplicationState::peer_add_spawn(int p_peer, const ObjectID &p_id) { + ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER); + peers_info[p_peer].spawn_nodes.insert(p_id); + return OK; +} + +Error SceneReplicationState::peer_del_spawn(int p_peer, const ObjectID &p_id) { + ERR_FAIL_COND_V(!peers_info.has(p_peer), ERR_INVALID_PARAMETER); + peers_info[p_peer].spawn_nodes.erase(p_id); return OK; } +const HashSet<ObjectID> SceneReplicationState::get_peer_spawn_nodes(int p_peer) { + ERR_FAIL_COND_V(!peers_info.has(p_peer), HashSet<ObjectID>()); + return peers_info[p_peer].spawn_nodes; +} + +bool SceneReplicationState::is_peer_spawn(int p_peer, const ObjectID &p_id) const { + ERR_FAIL_COND_V(!peers_info.has(p_peer), false); + return peers_info[p_peer].spawn_nodes.has(p_id); +} + Node *SceneReplicationState::peer_get_remote(int p_peer, uint32_t p_net_id) { PeerInfo *info = peers_info.getptr(p_peer); return info && info->recv_nodes.has(p_net_id) ? Object::cast_to<Node>(ObjectDB::get_instance(info->recv_nodes[p_net_id])) : nullptr; diff --git a/scene/multiplayer/scene_replication_state.h b/modules/multiplayer/scene_replication_state.h index 60a6c5d70c..bdff6ae3b7 100644 --- a/scene/multiplayer/scene_replication_state.h +++ b/modules/multiplayer/scene_replication_state.h @@ -28,11 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_REPLICATON_STATE_H -#define SCENE_REPLICATON_STATE_H +#ifndef SCENE_REPLICATION_STATE_H +#define SCENE_REPLICATION_STATE_H #include "core/object/ref_counted.h" +#include "multiplayer_spawner.h" +#include "multiplayer_synchronizer.h" + class MultiplayerSpawner; class MultiplayerSynchronizer; class Node; @@ -62,7 +65,8 @@ private: }; struct PeerInfo { - HashSet<ObjectID> known_nodes; + HashSet<ObjectID> sync_nodes; + HashSet<ObjectID> spawn_nodes; HashMap<uint32_t, ObjectID> recv_nodes; uint16_t last_sent_sync = 0; uint16_t last_recv_sync = 0; @@ -73,7 +77,7 @@ private: HashMap<ObjectID, TrackedNode> tracked_nodes; HashMap<int, PeerInfo> peers_info; HashSet<ObjectID> spawned_nodes; - HashSet<ObjectID> path_only_nodes; + HashSet<ObjectID> synced_nodes; TrackedNode &_track(const ObjectID &p_id); void _untrack(const ObjectID &p_id); @@ -82,7 +86,9 @@ private: public: const HashSet<int> get_peers() const { return known_peers; } const HashSet<ObjectID> &get_spawned_nodes() const { return spawned_nodes; } - const HashSet<ObjectID> &get_path_only_nodes() const { return path_only_nodes; } + bool is_spawned_node(const ObjectID &p_id) const { return spawned_nodes.has(p_id); } + const HashSet<ObjectID> &get_synced_nodes() const { return synced_nodes; } + bool is_synced_node(const ObjectID &p_id) const { return synced_nodes.has(p_id); } MultiplayerSynchronizer *get_synchronizer(const ObjectID &p_id) { return tracked_nodes.has(p_id) ? tracked_nodes[p_id].get_synchronizer() : nullptr; } MultiplayerSpawner *get_spawner(const ObjectID &p_id) { return tracked_nodes.has(p_id) ? tracked_nodes[p_id].get_spawner() : nullptr; } @@ -90,7 +96,6 @@ public: bool update_last_node_sync(const ObjectID &p_id, uint16_t p_time); bool update_sync_time(const ObjectID &p_id, uint64_t p_msec); - const HashSet<ObjectID> get_known_nodes(int p_peer); uint32_t get_net_id(const ObjectID &p_id) const; void set_net_id(const ObjectID &p_id, uint32_t p_net_id); uint32_t ensure_net_id(const ObjectID &p_id); @@ -104,8 +109,17 @@ public: Error config_add_sync(Node *p_node, MultiplayerSynchronizer *p_sync); Error config_del_sync(Node *p_node, MultiplayerSynchronizer *p_sync); - Error peer_add_node(int p_peer, const ObjectID &p_id); - Error peer_del_node(int p_peer, const ObjectID &p_id); + Error peer_add_sync(int p_peer, const ObjectID &p_id); + Error peer_del_sync(int p_peer, const ObjectID &p_id); + + const HashSet<ObjectID> get_peer_sync_nodes(int p_peer); + bool is_peer_sync(int p_peer, const ObjectID &p_id) const; + + Error peer_add_spawn(int p_peer, const ObjectID &p_id); + Error peer_del_spawn(int p_peer, const ObjectID &p_id); + + const HashSet<ObjectID> get_peer_spawn_nodes(int p_peer); + bool is_peer_spawn(int p_peer, const ObjectID &p_id) const; const HashMap<uint32_t, ObjectID> peer_get_remotes(int p_peer) const; Node *peer_get_remote(int p_peer, uint32_t p_net_id); @@ -118,4 +132,4 @@ public: SceneReplicationState() {} }; -#endif // SCENE_REPLICATON_STATE_H +#endif // SCENE_REPLICATION_STATE_H diff --git a/scene/multiplayer/scene_rpc_interface.cpp b/modules/multiplayer/scene_rpc_interface.cpp index 84700a82f3..65090b9316 100644 --- a/scene/multiplayer/scene_rpc_interface.cpp +++ b/modules/multiplayer/scene_rpc_interface.cpp @@ -28,21 +28,28 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene/multiplayer/scene_rpc_interface.h" +#include "scene_rpc_interface.h" #include "core/debugger/engine_debugger.h" #include "core/io/marshalls.h" -#include "core/multiplayer/multiplayer_api.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/node.h" #include "scene/main/window.h" -MultiplayerRPCInterface *SceneRPCInterface::_create(MultiplayerAPI *p_multiplayer) { - return memnew(SceneRPCInterface(p_multiplayer)); -} +#include "scene_multiplayer.h" -void SceneRPCInterface::make_default() { - MultiplayerAPI::create_default_rpc_interface = _create; -} +// The RPC meta is composed by a single byte that contains (starting from the least significant bit): +// - `NetworkCommands` in the first four bits. +// - `NetworkNodeIdCompression` in the next 2 bits. +// - `NetworkNameIdCompression` in the next 1 bit. +// - `byte_only_or_no_args` in the next 1 bit. +#define NODE_ID_COMPRESSION_SHIFT SceneMultiplayer::CMD_FLAG_0_SHIFT +#define NAME_ID_COMPRESSION_SHIFT SceneMultiplayer::CMD_FLAG_2_SHIFT +#define BYTE_ONLY_OR_NO_ARGS_SHIFT SceneMultiplayer::CMD_FLAG_3_SHIFT + +#define NODE_ID_COMPRESSION_FLAG ((1 << NODE_ID_COMPRESSION_SHIFT) | (1 << (NODE_ID_COMPRESSION_SHIFT + 1))) +#define NAME_ID_COMPRESSION_FLAG (1 << NAME_ID_COMPRESSION_SHIFT) +#define BYTE_ONLY_OR_NO_ARGS_FLAG (1 << BYTE_ONLY_OR_NO_ARGS_SHIFT) #ifdef DEBUG_ENABLED _FORCE_INLINE_ void SceneRPCInterface::_profile_node_data(const String &p_what, ObjectID p_id) { @@ -67,50 +74,58 @@ int get_packet_len(uint32_t p_node_target, int p_packet_len) { } } -const Multiplayer::RPCConfig _get_rpc_config(const Node *p_node, const StringName &p_method, uint16_t &r_id) { - const Vector<Multiplayer::RPCConfig> node_config = p_node->get_node_rpc_methods(); - for (int i = 0; i < node_config.size(); i++) { - if (node_config[i].name == p_method) { - r_id = ((uint16_t)i) | (1 << 15); - return node_config[i]; - } +void SceneRPCInterface::_parse_rpc_config(const Variant &p_config, bool p_for_node, RPCConfigCache &r_cache) { + if (p_config.get_type() == Variant::NIL) { + return; } - if (p_node->get_script_instance()) { - const Vector<Multiplayer::RPCConfig> script_config = p_node->get_script_instance()->get_rpc_methods(); - for (int i = 0; i < script_config.size(); i++) { - if (script_config[i].name == p_method) { - r_id = (uint16_t)i; - return script_config[i]; - } + ERR_FAIL_COND(p_config.get_type() != Variant::DICTIONARY); + const Dictionary config = p_config; + Array names = config.keys(); + names.sort(); // Ensure ID order + for (int i = 0; i < names.size(); i++) { + ERR_CONTINUE(names[i].get_type() != Variant::STRING); + String name = names[i].operator String(); + ERR_CONTINUE(config[name].get_type() != Variant::DICTIONARY); + ERR_CONTINUE(!config[name].operator Dictionary().has("rpc_mode")); + Dictionary dict = config[name]; + RPCConfig cfg; + cfg.name = name; + cfg.rpc_mode = ((MultiplayerAPI::RPCMode)dict.get("rpc_mode", MultiplayerAPI::RPC_MODE_AUTHORITY).operator int()); + cfg.transfer_mode = ((MultiplayerPeer::TransferMode)dict.get("transfer_mode", MultiplayerPeer::TRANSFER_MODE_RELIABLE).operator int()); + cfg.call_local = dict.get("call_local", false).operator bool(); + cfg.channel = dict.get("channel", 0).operator int(); + uint16_t id = ((uint16_t)i); + if (p_for_node) { + id |= (1 << 15); } + r_cache.configs[id] = cfg; + r_cache.ids[name] = id; } - return Multiplayer::RPCConfig(); } -const Multiplayer::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_id) { - Vector<Multiplayer::RPCConfig> config; - uint16_t id = p_id; - if (id & (1 << 15)) { - id = id & ~(1 << 15); - config = p_node->get_node_rpc_methods(); - } else if (p_node->get_script_instance()) { - config = p_node->get_script_instance()->get_rpc_methods(); +const SceneRPCInterface::RPCConfigCache &SceneRPCInterface::_get_node_config(const Node *p_node) { + const ObjectID oid = p_node->get_instance_id(); + if (rpc_cache.has(oid)) { + return rpc_cache[oid]; } - if (id < config.size()) { - return config[id]; + RPCConfigCache cache; + _parse_rpc_config(p_node->get_node_rpc_config(), true, cache); + if (p_node->get_script_instance()) { + _parse_rpc_config(p_node->get_script_instance()->get_rpc_config(), false, cache); } - return Multiplayer::RPCConfig(); + rpc_cache[oid] = cache; + return rpc_cache[oid]; } -_FORCE_INLINE_ bool _can_call_mode(Node *p_node, Multiplayer::RPCMode mode, int p_remote_id) { +_FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) { switch (mode) { - case Multiplayer::RPC_MODE_DISABLED: { + case MultiplayerAPI::RPC_MODE_DISABLED: { return false; } break; - case Multiplayer::RPC_MODE_ANY_PEER: { + case MultiplayerAPI::RPC_MODE_ANY_PEER: { return true; } break; - case Multiplayer::RPC_MODE_AUTHORITY: { + case MultiplayerAPI::RPC_MODE_AUTHORITY: { return !p_node->is_multiplayer_authority() && p_remote_id == p_node->get_multiplayer_authority(); } break; } @@ -118,19 +133,13 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, Multiplayer::RPCMode mode, int return false; } -String SceneRPCInterface::get_rpc_md5(const Object *p_obj) const { +String SceneRPCInterface::get_rpc_md5(const Object *p_obj) { const Node *node = Object::cast_to<Node>(p_obj); ERR_FAIL_COND_V(!node, ""); + const RPCConfigCache cache = _get_node_config(node); String rpc_list; - const Vector<Multiplayer::RPCConfig> node_config = node->get_node_rpc_methods(); - for (int i = 0; i < node_config.size(); i++) { - rpc_list += String(node_config[i].name); - } - if (node->get_script_instance()) { - const Vector<Multiplayer::RPCConfig> script_config = node->get_script_instance()->get_rpc_methods(); - for (int i = 0; i < script_config.size(); i++) { - rpc_list += String(script_config[i].name); - } + for (const KeyValue<uint16_t, RPCConfig> &config : cache.configs) { + rpc_list += String(config.value.name); } return rpc_list.md5_text(); } @@ -159,7 +168,7 @@ Node *SceneRPCInterface::_process_get_node(int p_from, const uint8_t *p_packet, return node; } else { // Use cached path. - return Object::cast_to<Node>(multiplayer->get_cached_object(p_from, p_node_target)); + return Object::cast_to<Node>(multiplayer->get_path_cache()->get_cached_object(p_from, p_node_target)); } } @@ -240,8 +249,9 @@ void SceneRPCInterface::_process_rpc(Node *p_node, const uint16_t p_rpc_method_i ERR_FAIL_COND_MSG(p_offset > p_packet_len, "Invalid packet received. Size too small."); // Check that remote can call the RPC on this node. - const Multiplayer::RPCConfig config = _get_rpc_config_by_id(p_node, p_rpc_method_id); - ERR_FAIL_COND(config.name == StringName()); + const RPCConfigCache &cache_config = _get_node_config(p_node); + ERR_FAIL_COND(!cache_config.configs.has(p_rpc_method_id)); + const RPCConfig &config = cache_config.configs[p_rpc_method_id]; bool can_call = _can_call_mode(p_node, config.rpc_mode, p_from); ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(config.name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)config.rpc_mode) + ", authority is " + itos(p_node->get_multiplayer_authority()) + "."); @@ -286,7 +296,7 @@ void SceneRPCInterface::_process_rpc(Node *p_node, const uint16_t p_rpc_method_i } } -void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const Multiplayer::RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount) { +void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount) { Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer(); ERR_FAIL_COND_MSG(peer.is_null(), "Attempt to call RPC without active multiplayer peer."); @@ -297,17 +307,14 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con ERR_FAIL_COND_MSG(p_argcount > 255, "Too many arguments (>255)."); if (p_to != 0 && !multiplayer->get_connected_peers().has(ABS(p_to))) { - ERR_FAIL_COND_MSG(p_to == peer->get_unique_id(), "Attempt to call RPC on yourself! Peer unique ID: " + itos(peer->get_unique_id()) + "."); + ERR_FAIL_COND_MSG(p_to == multiplayer->get_unique_id(), "Attempt to call RPC on yourself! Peer unique ID: " + itos(multiplayer->get_unique_id()) + "."); ERR_FAIL_MSG("Attempt to call RPC with unknown peer ID: " + itos(p_to) + "."); } - NodePath from_path = multiplayer->get_root_path().rel_path_to(p_from->get_path()); - ERR_FAIL_COND_MSG(from_path.is_empty(), "Unable to send RPC. Relative path is empty. THIS IS LIKELY A BUG IN THE ENGINE!"); - // See if all peers have cached path (if so, call can be fast). int psc_id; - const bool has_all_peers = multiplayer->send_object_cache(p_from, from_path, p_to, psc_id); + const bool has_all_peers = multiplayer->get_path_cache()->send_object_cache(p_from, p_to, psc_id); // Create base packet, lots of hardcode because it must be tight. @@ -318,7 +325,7 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con packet_cache.resize(m_amount); // Encode meta. - uint8_t command_type = MultiplayerAPI::NETWORK_COMMAND_REMOTE_CALL; + uint8_t command_type = SceneMultiplayer::NETWORK_COMMAND_REMOTE_CALL; uint8_t node_id_compression = UINT8_MAX; uint8_t name_id_compression = UINT8_MAX; bool byte_only_or_no_args = false; @@ -414,6 +421,7 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con // Not all verified path, so send one by one. // Append path at the end, since we will need it for some packets. + NodePath from_path = multiplayer->get_root_path().rel_path_to(p_from->get_path()); CharString pname = String(from_path).utf8(); int path_len = encode_cstring(pname.get_data(), nullptr); MAKE_ROOM(ofs + path_len); @@ -428,7 +436,7 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con continue; // Continue, not for this peer. } - bool confirmed = multiplayer->is_cache_confirmed(from_path, P); + bool confirmed = multiplayer->get_path_cache()->is_cache_confirmed(from_path, P); peer->set_target_peer(P); // To this one specifically. @@ -445,22 +453,25 @@ void SceneRPCInterface::_send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, con } } -void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { +Error SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { Ref<MultiplayerPeer> peer = multiplayer->get_multiplayer_peer(); - ERR_FAIL_COND_MSG(!peer.is_valid(), "Trying to call an RPC while no multiplayer peer is active."); + ERR_FAIL_COND_V_MSG(!peer.is_valid(), ERR_UNCONFIGURED, "Trying to call an RPC while no multiplayer peer is active."); Node *node = Object::cast_to<Node>(p_obj); - ERR_FAIL_COND(!node); - ERR_FAIL_COND_MSG(!node->is_inside_tree(), "Trying to call an RPC on a node which is not inside SceneTree."); - ERR_FAIL_COND_MSG(peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a multiplayer peer which is not connected."); + ERR_FAIL_COND_V_MSG(!node || !node->is_inside_tree(), ERR_INVALID_PARAMETER, "The object must be a valid Node inside the SceneTree"); + ERR_FAIL_COND_V_MSG(peer->get_connection_status() != MultiplayerPeer::CONNECTION_CONNECTED, ERR_CONNECTION_ERROR, "Trying to call an RPC via a multiplayer peer which is not connected."); - int node_id = peer->get_unique_id(); + int caller_id = multiplayer->get_unique_id(); bool call_local_native = false; bool call_local_script = false; - uint16_t rpc_id = UINT16_MAX; - const Multiplayer::RPCConfig config = _get_rpc_config(node, p_method, rpc_id); - ERR_FAIL_COND_MSG(config.name == StringName(), + const RPCConfigCache &config_cache = _get_node_config(node); + uint16_t rpc_id = config_cache.ids.has(p_method) ? config_cache.ids[p_method] : UINT16_MAX; + ERR_FAIL_COND_V_MSG(rpc_id == UINT16_MAX, ERR_INVALID_PARAMETER, vformat("Unable to get the RPC configuration for the function \"%s\" at path: \"%s\". This happens when the method is missing or not marked for RPCs in the local script.", p_method, node->get_path())); - if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) { + const RPCConfig &config = config_cache.configs[rpc_id]; + + ERR_FAIL_COND_V_MSG(p_peer_id == caller_id && !config.call_local, ERR_INVALID_PARAMETER, "RPC '" + p_method + "' on yourself is not allowed by selected mode."); + + if (p_peer_id == 0 || p_peer_id == caller_id || (p_peer_id < 0 && p_peer_id != -caller_id)) { if (rpc_id & (1 << 15)) { call_local_native = config.call_local; } else { @@ -468,7 +479,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m } } - if (p_peer_id != node_id) { + if (p_peer_id != caller_id) { #ifdef DEBUG_ENABLED _profile_node_data("rpc_out", node->get_instance_id()); #endif @@ -479,7 +490,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m if (call_local_native) { Callable::CallError ce; - multiplayer->set_remote_sender_override(peer->get_unique_id()); + multiplayer->set_remote_sender_override(multiplayer->get_unique_id()); node->callp(p_method, p_arg, p_argcount, ce); multiplayer->set_remote_sender_override(0); @@ -487,7 +498,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m String error = Variant::get_call_error_text(node, p_method, p_arg, p_argcount, ce); error = "rpc() aborted in local call: - " + error + "."; ERR_PRINT(error); - return; + return FAILED; } } @@ -495,7 +506,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m Callable::CallError ce; ce.error = Callable::CallError::CALL_OK; - multiplayer->set_remote_sender_override(peer->get_unique_id()); + multiplayer->set_remote_sender_override(multiplayer->get_unique_id()); node->get_script_instance()->callp(p_method, p_arg, p_argcount, ce); multiplayer->set_remote_sender_override(0); @@ -503,9 +514,8 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m String error = Variant::get_call_error_text(node, p_method, p_arg, p_argcount, ce); error = "rpc() aborted in script local call: - " + error + "."; ERR_PRINT(error); - return; + return FAILED; } } - - ERR_FAIL_COND_MSG(p_peer_id == node_id && !config.call_local, "RPC '" + p_method + "' on yourself is not allowed by selected mode."); + return OK; } diff --git a/scene/multiplayer/scene_rpc_interface.h b/modules/multiplayer/scene_rpc_interface.h index 86e1d0d280..aa9be525a2 100644 --- a/scene/multiplayer/scene_rpc_interface.h +++ b/modules/multiplayer/scene_rpc_interface.h @@ -31,13 +31,40 @@ #ifndef SCENE_RPC_INTERFACE_H #define SCENE_RPC_INTERFACE_H -#include "core/multiplayer/multiplayer.h" -#include "core/multiplayer/multiplayer_api.h" +#include "core/object/ref_counted.h" +#include "scene/main/multiplayer_api.h" -class SceneRPCInterface : public MultiplayerRPCInterface { - GDCLASS(SceneRPCInterface, MultiplayerRPCInterface); +class SceneMultiplayer; +class Node; + +class SceneRPCInterface : public RefCounted { + GDCLASS(SceneRPCInterface, RefCounted); private: + struct RPCConfig { + StringName name; + MultiplayerAPI::RPCMode rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; + bool call_local = false; + MultiplayerPeer::TransferMode transfer_mode = MultiplayerPeer::TRANSFER_MODE_RELIABLE; + int channel = 0; + + bool operator==(RPCConfig const &p_other) const { + return name == p_other.name; + } + }; + + struct RPCConfigCache { + HashMap<uint16_t, RPCConfig> configs; + HashMap<StringName, uint16_t> ids; + }; + + struct SortRPCConfig { + StringName::AlphCompare compare; + bool operator()(const RPCConfig &p_a, const RPCConfig &p_b) const { + return compare(p_a.name, p_b.name); + } + }; + enum NetworkNodeIdCompression { NETWORK_NODE_ID_COMPRESSION_8 = 0, NETWORK_NODE_ID_COMPRESSION_16, @@ -49,43 +76,27 @@ private: NETWORK_NAME_ID_COMPRESSION_16, }; - // The RPC meta is composed by a single byte that contains (starting from the least significant bit): - // - `NetworkCommands` in the first four bits. - // - `NetworkNodeIdCompression` in the next 2 bits. - // - `NetworkNameIdCompression` in the next 1 bit. - // - `byte_only_or_no_args` in the next 1 bit. - enum { - NODE_ID_COMPRESSION_SHIFT = MultiplayerAPI::CMD_FLAG_0_SHIFT, // 2 bits for this. - NAME_ID_COMPRESSION_SHIFT = MultiplayerAPI::CMD_FLAG_2_SHIFT, - BYTE_ONLY_OR_NO_ARGS_SHIFT = MultiplayerAPI::CMD_FLAG_3_SHIFT, - }; - - enum { - NODE_ID_COMPRESSION_FLAG = (1 << NODE_ID_COMPRESSION_SHIFT) | (1 << (NODE_ID_COMPRESSION_SHIFT + 1)), // 2 bits for this. - NAME_ID_COMPRESSION_FLAG = (1 << NAME_ID_COMPRESSION_SHIFT), - BYTE_ONLY_OR_NO_ARGS_FLAG = (1 << BYTE_ONLY_OR_NO_ARGS_SHIFT), - }; - - MultiplayerAPI *multiplayer = nullptr; + SceneMultiplayer *multiplayer = nullptr; Vector<uint8_t> packet_cache; -protected: - static MultiplayerRPCInterface *_create(MultiplayerAPI *p_multiplayer); + HashMap<ObjectID, RPCConfigCache> rpc_cache; +protected: _FORCE_INLINE_ void _profile_node_data(const String &p_what, ObjectID p_id); void _process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); - void _send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const Multiplayer::RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount); + void _send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount); Node *_process_get_node(int p_from, const uint8_t *p_packet, uint32_t p_node_target, int p_packet_len); -public: - static void make_default(); + void _parse_rpc_config(const Variant &p_config, bool p_for_node, RPCConfigCache &r_cache); + const RPCConfigCache &_get_node_config(const Node *p_node); - virtual void rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) override; - virtual void process_rpc(int p_from, const uint8_t *p_packet, int p_packet_len) override; - virtual String get_rpc_md5(const Object *p_obj) const override; +public: + Error rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); + void process_rpc(int p_from, const uint8_t *p_packet, int p_packet_len); + String get_rpc_md5(const Object *p_obj); - SceneRPCInterface(MultiplayerAPI *p_multiplayer) { multiplayer = p_multiplayer; } + SceneRPCInterface(SceneMultiplayer *p_multiplayer) { multiplayer = p_multiplayer; } }; #endif // SCENE_RPC_INTERFACE_H diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 17d6e0a0a1..46daa54239 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -30,9 +30,9 @@ #include "nav_map.h" +#include "core/object/worker_thread_pool.h" #include "nav_region.h" #include "rvo_agent.h" - #include <algorithm> #define THREE_POINTS_CROSS_PRODUCT(m_a, m_b, m_c) (((m_c) - (m_a)).cross((m_b) - (m_a))) @@ -683,14 +683,8 @@ void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) { void NavMap::step(real_t p_deltatime) { deltatime = p_deltatime; if (controlled_agents.size() > 0) { - if (step_work_pool.get_thread_count() == 0) { - step_work_pool.init(); - } - step_work_pool.do_work( - controlled_agents.size(), - this, - &NavMap::compute_single_step, - controlled_agents.data()); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &NavMap::compute_single_step, controlled_agents.data(), controlled_agents.size(), -1, true, SNAME("NavigationMapAgents")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); } } @@ -736,5 +730,4 @@ NavMap::NavMap() { } NavMap::~NavMap() { - step_work_pool.finish(); } diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index 2036dbecd7..98a5c24b3e 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -34,8 +34,8 @@ #include "nav_rid.h" #include "core/math/math_defs.h" +#include "core/object/worker_thread_pool.h" #include "core/templates/rb_map.h" -#include "core/templates/thread_work_pool.h" #include "nav_utils.h" #include <KdTree.h> @@ -81,9 +81,6 @@ class NavMap : public NavRid { /// Change the id each time the map is updated. uint32_t map_update_id = 0; - /// Pooled threads for computing steps - ThreadWorkPool step_work_pool; - public: NavMap(); ~NavMap(); diff --git a/modules/ogg/config.py b/modules/ogg/config.py index 5a417ba8dd..f7ec4de6be 100644 --- a/modules/ogg/config.py +++ b/modules/ogg/config.py @@ -8,8 +8,8 @@ def configure(env): def get_doc_classes(): return [ - "OGGPacketSequence", - "OGGPacketSequencePlayback", + "OggPacketSequence", + "OggPacketSequencePlayback", ] diff --git a/modules/ogg/doc_classes/OGGPacketSequence.xml b/modules/ogg/doc_classes/OggPacketSequence.xml index bff3691ce0..d3bd4455d8 100644 --- a/modules/ogg/doc_classes/OGGPacketSequence.xml +++ b/modules/ogg/doc_classes/OggPacketSequence.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OGGPacketSequence" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OggPacketSequence" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> - A sequence of OGG packets. + A sequence of Ogg packets. </brief_description> <description> - A sequence of OGG packets. + A sequence of Ogg packets. </description> <tutorials> </tutorials> @@ -21,7 +21,7 @@ Contains the granule positions for each page in this packet sequence. </member> <member name="packet_data" type="Array" setter="set_packet_data" getter="get_packet_data" default="[]"> - Contains the raw packets that make up this OGGPacketSequence. + Contains the raw packets that make up this OggPacketSequence. </member> <member name="sampling_rate" type="float" setter="set_sampling_rate" getter="get_sampling_rate" default="0.0"> Holds sample rate information about this sequence. Must be set by another class that actually understands the codec. diff --git a/modules/ogg/doc_classes/OGGPacketSequencePlayback.xml b/modules/ogg/doc_classes/OggPacketSequencePlayback.xml index 11fc1f4cb6..5c0d75278b 100644 --- a/modules/ogg/doc_classes/OGGPacketSequencePlayback.xml +++ b/modules/ogg/doc_classes/OggPacketSequencePlayback.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OGGPacketSequencePlayback" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OggPacketSequencePlayback" inherits="RefCounted" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> </brief_description> <description> diff --git a/modules/ogg/ogg_packet_sequence.cpp b/modules/ogg/ogg_packet_sequence.cpp index da52ecfdd5..de8bf4a087 100644 --- a/modules/ogg/ogg_packet_sequence.cpp +++ b/modules/ogg/ogg_packet_sequence.cpp @@ -31,7 +31,7 @@ #include "ogg_packet_sequence.h" #include "core/variant/typed_array.h" -void OGGPacketSequence::push_page(int64_t p_granule_pos, const Vector<PackedByteArray> &p_data) { +void OggPacketSequence::push_page(int64_t p_granule_pos, const Vector<PackedByteArray> &p_data) { Vector<PackedByteArray> data_stored; for (int i = 0; i < p_data.size(); i++) { data_stored.push_back(p_data[i]); @@ -41,7 +41,7 @@ void OGGPacketSequence::push_page(int64_t p_granule_pos, const Vector<PackedByte data_version++; } -void OGGPacketSequence::set_packet_data(const Array &p_data) { +void OggPacketSequence::set_packet_data(const Array &p_data) { data_version++; // Update the data version so old playbacks know that they can't rely on us anymore. page_data.clear(); for (int page_idx = 0; page_idx < p_data.size(); page_idx++) { @@ -54,7 +54,7 @@ void OGGPacketSequence::set_packet_data(const Array &p_data) { } } -Array OGGPacketSequence::get_packet_data() const { +Array OggPacketSequence::get_packet_data() const { Array ret; for (const Vector<PackedByteArray> &page : page_data) { Array page_variant; @@ -66,7 +66,7 @@ Array OGGPacketSequence::get_packet_data() const { return ret; } -void OGGPacketSequence::set_packet_granule_positions(const Array &p_granule_positions) { +void OggPacketSequence::set_packet_granule_positions(const Array &p_granule_positions) { data_version++; // Update the data version so old playbacks know that they can't rely on us anymore. page_granule_positions.clear(); for (int page_idx = 0; page_idx < p_granule_positions.size(); page_idx++) { @@ -75,7 +75,7 @@ void OGGPacketSequence::set_packet_granule_positions(const Array &p_granule_posi } } -Array OGGPacketSequence::get_packet_granule_positions() const { +Array OggPacketSequence::get_packet_granule_positions() const { Array ret; for (int64_t granule_pos : page_granule_positions) { ret.push_back(granule_pos); @@ -83,22 +83,22 @@ Array OGGPacketSequence::get_packet_granule_positions() const { return ret; } -void OGGPacketSequence::set_sampling_rate(float p_sampling_rate) { +void OggPacketSequence::set_sampling_rate(float p_sampling_rate) { sampling_rate = p_sampling_rate; } -float OGGPacketSequence::get_sampling_rate() const { +float OggPacketSequence::get_sampling_rate() const { return sampling_rate; } -int64_t OGGPacketSequence::get_final_granule_pos() const { +int64_t OggPacketSequence::get_final_granule_pos() const { if (!page_granule_positions.is_empty()) { return page_granule_positions[page_granule_positions.size() - 1]; } return -1; } -float OGGPacketSequence::get_length() const { +float OggPacketSequence::get_length() const { int64_t granule_pos = get_final_granule_pos(); if (granule_pos < 0) { return 0; @@ -106,33 +106,33 @@ float OGGPacketSequence::get_length() const { return granule_pos / sampling_rate; } -Ref<OGGPacketSequencePlayback> OGGPacketSequence::instance_playback() { - Ref<OGGPacketSequencePlayback> playback; +Ref<OggPacketSequencePlayback> OggPacketSequence::instantiate_playback() { + Ref<OggPacketSequencePlayback> playback; playback.instantiate(); - playback->ogg_packet_sequence = Ref<OGGPacketSequence>(this); + playback->ogg_packet_sequence = Ref<OggPacketSequence>(this); playback->data_version = data_version; return playback; } -void OGGPacketSequence::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_packet_data", "packet_data"), &OGGPacketSequence::set_packet_data); - ClassDB::bind_method(D_METHOD("get_packet_data"), &OGGPacketSequence::get_packet_data); +void OggPacketSequence::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_packet_data", "packet_data"), &OggPacketSequence::set_packet_data); + ClassDB::bind_method(D_METHOD("get_packet_data"), &OggPacketSequence::get_packet_data); - ClassDB::bind_method(D_METHOD("set_packet_granule_positions", "granule_positions"), &OGGPacketSequence::set_packet_granule_positions); - ClassDB::bind_method(D_METHOD("get_packet_granule_positions"), &OGGPacketSequence::get_packet_granule_positions); + ClassDB::bind_method(D_METHOD("set_packet_granule_positions", "granule_positions"), &OggPacketSequence::set_packet_granule_positions); + ClassDB::bind_method(D_METHOD("get_packet_granule_positions"), &OggPacketSequence::get_packet_granule_positions); - ClassDB::bind_method(D_METHOD("set_sampling_rate", "sampling_rate"), &OGGPacketSequence::set_sampling_rate); - ClassDB::bind_method(D_METHOD("get_sampling_rate"), &OGGPacketSequence::get_sampling_rate); + ClassDB::bind_method(D_METHOD("set_sampling_rate", "sampling_rate"), &OggPacketSequence::set_sampling_rate); + ClassDB::bind_method(D_METHOD("get_sampling_rate"), &OggPacketSequence::get_sampling_rate); - ClassDB::bind_method(D_METHOD("get_length"), &OGGPacketSequence::get_length); + ClassDB::bind_method(D_METHOD("get_length"), &OggPacketSequence::get_length); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "packet_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_data", "get_packet_data"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "granule_positions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_granule_positions", "get_packet_granule_positions"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sampling_rate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_sampling_rate", "get_sampling_rate"); } -bool OGGPacketSequencePlayback::next_ogg_packet(ogg_packet **p_packet) const { +bool OggPacketSequencePlayback::next_ogg_packet(ogg_packet **p_packet) const { ERR_FAIL_COND_V(data_version != ogg_packet_sequence->data_version, false); ERR_FAIL_COND_V(ogg_packet_sequence->page_data.is_empty(), false); ERR_FAIL_COND_V(ogg_packet_sequence->page_granule_positions.is_empty(), false); @@ -161,7 +161,7 @@ bool OGGPacketSequencePlayback::next_ogg_packet(ogg_packet **p_packet) const { return true; } -uint32_t OGGPacketSequencePlayback::seek_page_internal(int64_t granule, uint32_t after_page_inclusive, uint32_t before_page_inclusive) { +uint32_t OggPacketSequencePlayback::seek_page_internal(int64_t granule, uint32_t after_page_inclusive, uint32_t before_page_inclusive) { // FIXME: This function needs better corner case handling. if (before_page_inclusive == after_page_inclusive) { return before_page_inclusive; @@ -198,7 +198,7 @@ uint32_t OGGPacketSequencePlayback::seek_page_internal(int64_t granule, uint32_t } } -bool OGGPacketSequencePlayback::seek_page(int64_t p_granule_pos) { +bool OggPacketSequencePlayback::seek_page(int64_t p_granule_pos) { int correct_page = seek_page_internal(p_granule_pos, 0, ogg_packet_sequence->page_data.size() - 1); if (correct_page == -1) { return false; @@ -213,10 +213,10 @@ bool OGGPacketSequencePlayback::seek_page(int64_t p_granule_pos) { return true; } -OGGPacketSequencePlayback::OGGPacketSequencePlayback() { +OggPacketSequencePlayback::OggPacketSequencePlayback() { packet = new ogg_packet(); } -OGGPacketSequencePlayback::~OGGPacketSequencePlayback() { +OggPacketSequencePlayback::~OggPacketSequencePlayback() { delete packet; } diff --git a/modules/ogg/ogg_packet_sequence.h b/modules/ogg/ogg_packet_sequence.h index 73e3cb4fff..efd3b64a39 100644 --- a/modules/ogg/ogg_packet_sequence.h +++ b/modules/ogg/ogg_packet_sequence.h @@ -38,12 +38,12 @@ #include "core/variant/variant.h" #include "thirdparty/libogg/ogg/ogg.h" -class OGGPacketSequencePlayback; +class OggPacketSequencePlayback; -class OGGPacketSequence : public Resource { - GDCLASS(OGGPacketSequence, Resource); +class OggPacketSequence : public Resource { + GDCLASS(OggPacketSequence, Resource); - friend class OGGPacketSequencePlayback; + friend class OggPacketSequencePlayback; // List of pages, each of which is a list of packets on that page. The innermost PackedByteArrays contain complete ogg packets. Vector<Vector<PackedByteArray>> page_data; @@ -73,7 +73,7 @@ public: void set_packet_granule_positions(const Array &p_granule_positions); Array get_packet_granule_positions() const; - // Sets a sampling rate associated with this object. OGGPacketSequence doesn't understand codecs, + // Sets a sampling rate associated with this object. OggPacketSequence doesn't understand codecs, // so this value is naively stored as a convenience. void set_sampling_rate(float p_sampling_rate); @@ -86,18 +86,18 @@ public: // Returns the granule position of the last page in this sequence. int64_t get_final_granule_pos() const; - Ref<OGGPacketSequencePlayback> instance_playback(); + Ref<OggPacketSequencePlayback> instantiate_playback(); - OGGPacketSequence() {} - virtual ~OGGPacketSequence() {} + OggPacketSequence() {} + virtual ~OggPacketSequence() {} }; -class OGGPacketSequencePlayback : public RefCounted { - GDCLASS(OGGPacketSequencePlayback, RefCounted); +class OggPacketSequencePlayback : public RefCounted { + GDCLASS(OggPacketSequencePlayback, RefCounted); - friend class OGGPacketSequence; + friend class OggPacketSequence; - Ref<OGGPacketSequence> ogg_packet_sequence; + Ref<OggPacketSequence> ogg_packet_sequence; mutable int64_t page_cursor = 0; mutable int32_t packet_cursor = 0; @@ -121,8 +121,8 @@ public: // Returns true on success, false on failure. bool seek_page(int64_t p_granule_pos); - OGGPacketSequencePlayback(); - virtual ~OGGPacketSequencePlayback(); + OggPacketSequencePlayback(); + virtual ~OggPacketSequencePlayback(); }; #endif // OGG_PACKET_SEQUENCE_H diff --git a/modules/ogg/register_types.cpp b/modules/ogg/register_types.cpp index 01f04aa3d5..aca6d1e1f8 100644 --- a/modules/ogg/register_types.cpp +++ b/modules/ogg/register_types.cpp @@ -37,8 +37,8 @@ void initialize_ogg_module(ModuleInitializationLevel p_level) { return; } - GDREGISTER_CLASS(OGGPacketSequence); - GDREGISTER_CLASS(OGGPacketSequencePlayback); + GDREGISTER_CLASS(OggPacketSequence); + GDREGISTER_CLASS(OggPacketSequencePlayback); } void uninitialize_ogg_module(ModuleInitializationLevel p_level) { diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub index 8783e061d2..593d1ff3c1 100644 --- a/modules/openxr/SCsub +++ b/modules/openxr/SCsub @@ -35,7 +35,11 @@ if env["platform"] == "android": # may need to include java parts of the openxr loader elif env["platform"] == "linuxbsd": - env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_LINUX", "XR_USE_PLATFORM_XLIB"]) + env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_LINUX"]) + + if env["x11"]: + env_thirdparty.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"]) + # FIXME: Review what needs to be set for Android and macOS. env_thirdparty.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"]) elif env["platform"] == "windows": diff --git a/modules/openxr/action_map/openxr_action.h b/modules/openxr/action_map/openxr_action.h index 5e57f89133..a7c1c9988c 100644 --- a/modules/openxr/action_map/openxr_action.h +++ b/modules/openxr/action_map/openxr_action.h @@ -84,4 +84,4 @@ public: VARIANT_ENUM_CAST(OpenXRAction::ActionType); -#endif // !OPENXR_ACTION_H +#endif // OPENXR_ACTION_H diff --git a/modules/openxr/action_map/openxr_action_map.h b/modules/openxr/action_map/openxr_action_map.h index dcd8fc71aa..8659cd3942 100644 --- a/modules/openxr/action_map/openxr_action_map.h +++ b/modules/openxr/action_map/openxr_action_map.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OPENXR_ACTION_SETS_H -#define OPENXR_ACTION_SETS_H +#ifndef OPENXR_ACTION_MAP_H +#define OPENXR_ACTION_MAP_H #include "core/io/resource.h" @@ -79,4 +79,4 @@ public: ~OpenXRActionMap(); }; -#endif // !OPENXR_ACTION_SETS_H +#endif // OPENXR_ACTION_MAP_H diff --git a/modules/openxr/action_map/openxr_action_set.h b/modules/openxr/action_map/openxr_action_set.h index b1d7168894..2ef7ba4c32 100644 --- a/modules/openxr/action_map/openxr_action_set.h +++ b/modules/openxr/action_map/openxr_action_set.h @@ -72,4 +72,4 @@ public: ~OpenXRActionSet(); }; -#endif // !OPENXR_ACTION_SET_H +#endif // OPENXR_ACTION_SET_H diff --git a/modules/openxr/action_map/openxr_defs.h b/modules/openxr/action_map/openxr_defs.h index 9bdd9a6ded..446e6eb9c6 100644 --- a/modules/openxr/action_map/openxr_defs.h +++ b/modules/openxr/action_map/openxr_defs.h @@ -121,4 +121,4 @@ public: static PackedStringArray get_interaction_profile_paths(); }; -#endif // !OPENXR_DEFS_H +#endif // OPENXR_DEFS_H diff --git a/modules/openxr/action_map/openxr_interaction_profile.cpp b/modules/openxr/action_map/openxr_interaction_profile.cpp index 342c36cdff..99d7a17acf 100644 --- a/modules/openxr/action_map/openxr_interaction_profile.cpp +++ b/modules/openxr/action_map/openxr_interaction_profile.cpp @@ -40,7 +40,7 @@ void OpenXRIPBinding::_bind_methods() { ClassDB::bind_method(D_METHOD("get_paths"), &OpenXRIPBinding::get_paths); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "paths", PROPERTY_HINT_ARRAY_TYPE, "STRING"), "set_paths", "get_paths"); - ClassDB::bind_method(D_METHOD("has_path"), &OpenXRIPBinding::has_path); + ClassDB::bind_method(D_METHOD("has_path", "path"), &OpenXRIPBinding::has_path); ClassDB::bind_method(D_METHOD("add_path", "path"), &OpenXRIPBinding::add_path); ClassDB::bind_method(D_METHOD("remove_path", "path"), &OpenXRIPBinding::remove_path); } diff --git a/modules/openxr/action_map/openxr_interaction_profile.h b/modules/openxr/action_map/openxr_interaction_profile.h index 46b1bda50f..c77fd490bb 100644 --- a/modules/openxr/action_map/openxr_interaction_profile.h +++ b/modules/openxr/action_map/openxr_interaction_profile.h @@ -98,4 +98,4 @@ public: ~OpenXRInteractionProfile(); }; -#endif // !OPENXR_INTERACTION_PROFILE_H +#endif // OPENXR_INTERACTION_PROFILE_H diff --git a/modules/openxr/doc_classes/OpenXRIPBinding.xml b/modules/openxr/doc_classes/OpenXRIPBinding.xml index 9e1176874a..f96637f2f5 100644 --- a/modules/openxr/doc_classes/OpenXRIPBinding.xml +++ b/modules/openxr/doc_classes/OpenXRIPBinding.xml @@ -24,7 +24,7 @@ </method> <method name="has_path" qualifiers="const"> <return type="bool" /> - <argument index="0" name="arg0" type="String" /> + <argument index="0" name="path" type="String" /> <description> Returns [code]true[/code] if this input/output path is part of this binding. </description> diff --git a/modules/openxr/doc_classes/OpenXRInterface.xml b/modules/openxr/doc_classes/OpenXRInterface.xml index 74f708bc95..25bf496de9 100644 --- a/modules/openxr/doc_classes/OpenXRInterface.xml +++ b/modules/openxr/doc_classes/OpenXRInterface.xml @@ -5,10 +5,10 @@ </brief_description> <description> The OpenXR interface allows Godot to interact with OpenXR runtimes and make it possible to create XR experiences and games. - Due to the needs of OpenXR this interface works slightly different then other plugin based XR interfaces. It needs to be initialised when Godot starts. You need to enable OpenXR, settings for this can be found in your games project settings under the XR heading. You do need to mark a viewport for use with XR in order for Godot to know which render result should be output to the headset. + Due to the needs of OpenXR this interface works slightly different than other plugin based XR interfaces. It needs to be initialised when Godot starts. You need to enable OpenXR, settings for this can be found in your games project settings under the XR heading. You do need to mark a viewport for use with XR in order for Godot to know which render result should be output to the headset. </description> <tutorials> - <link title="OpenXR documentation">$DOCS_URL/tutorials/vr/openxr/index.html</link> + <link title="Setting up XR">$DOCS_URL/tutorials/xr/setting_up_xr.html</link> </tutorials> <signals> <signal name="pose_recentered"> diff --git a/modules/openxr/editor/openxr_action_editor.h b/modules/openxr/editor/openxr_action_editor.h index 6e1b7ab779..6cf098cf08 100644 --- a/modules/openxr/editor/openxr_action_editor.h +++ b/modules/openxr/editor/openxr_action_editor.h @@ -64,4 +64,4 @@ public: OpenXRActionEditor(Ref<OpenXRAction> p_action); }; -#endif // !OPENXR_ACTION_EDITOR_H +#endif // OPENXR_ACTION_EDITOR_H diff --git a/modules/openxr/editor/openxr_action_map_editor.h b/modules/openxr/editor/openxr_action_map_editor.h index dfc941b500..a19bc90f56 100644 --- a/modules/openxr/editor/openxr_action_map_editor.h +++ b/modules/openxr/editor/openxr_action_map_editor.h @@ -97,4 +97,4 @@ public: ~OpenXRActionMapEditor(); }; -#endif // !OPENXR_ACTION_MAP_EDITOR_H +#endif // OPENXR_ACTION_MAP_EDITOR_H diff --git a/modules/openxr/editor/openxr_action_set_editor.h b/modules/openxr/editor/openxr_action_set_editor.h index f3960dcbf9..d8c85d03dd 100644 --- a/modules/openxr/editor/openxr_action_set_editor.h +++ b/modules/openxr/editor/openxr_action_set_editor.h @@ -85,4 +85,4 @@ public: OpenXRActionSetEditor(Ref<OpenXRActionMap> p_action_map, Ref<OpenXRActionSet> p_action_set); }; -#endif // !OPENXR_ACTION_SET_EDITOR_H +#endif // OPENXR_ACTION_SET_EDITOR_H diff --git a/modules/openxr/editor/openxr_editor_plugin.h b/modules/openxr/editor/openxr_editor_plugin.h index af8ee7d54c..ce230ee95b 100644 --- a/modules/openxr/editor/openxr_editor_plugin.h +++ b/modules/openxr/editor/openxr_editor_plugin.h @@ -50,4 +50,4 @@ public: ~OpenXREditorPlugin(); }; -#endif // !OPENXR_EDITOR_PLUGIN_H +#endif // OPENXR_EDITOR_PLUGIN_H diff --git a/modules/openxr/editor/openxr_interaction_profile_editor.h b/modules/openxr/editor/openxr_interaction_profile_editor.h index f50da1a003..20a37a80eb 100644 --- a/modules/openxr/editor/openxr_interaction_profile_editor.h +++ b/modules/openxr/editor/openxr_interaction_profile_editor.h @@ -80,4 +80,4 @@ public: OpenXRInteractionProfileEditor(Ref<OpenXRActionMap> p_action_map, Ref<OpenXRInteractionProfile> p_interaction_profile); }; -#endif // !OPENXR_INTERACTION_PROFILE_EDITOR_H +#endif // OPENXR_INTERACTION_PROFILE_EDITOR_H diff --git a/modules/openxr/editor/openxr_select_action_dialog.h b/modules/openxr/editor/openxr_select_action_dialog.h index ea2c30373b..cbe1380e18 100644 --- a/modules/openxr/editor/openxr_select_action_dialog.h +++ b/modules/openxr/editor/openxr_select_action_dialog.h @@ -64,4 +64,4 @@ public: OpenXRSelectActionDialog(Ref<OpenXRActionMap> p_action_map); }; -#endif // !OPENXR_SELECT_ACTION_DIALOG_H +#endif // OPENXR_SELECT_ACTION_DIALOG_H diff --git a/modules/openxr/editor/openxr_select_interaction_profile_dialog.h b/modules/openxr/editor/openxr_select_interaction_profile_dialog.h index d177861ff3..54bfe3120a 100644 --- a/modules/openxr/editor/openxr_select_interaction_profile_dialog.h +++ b/modules/openxr/editor/openxr_select_interaction_profile_dialog.h @@ -63,4 +63,4 @@ public: OpenXRSelectInteractionProfileDialog(); }; -#endif // !OPENXR_SELECT_INTERACTION_PROFILE_DIALOG_H +#endif // OPENXR_SELECT_INTERACTION_PROFILE_DIALOG_H diff --git a/modules/openxr/extensions/openxr_android_extension.h b/modules/openxr/extensions/openxr_android_extension.h index e102197a55..88b0e310e7 100644 --- a/modules/openxr/extensions/openxr_android_extension.h +++ b/modules/openxr/extensions/openxr_android_extension.h @@ -44,4 +44,4 @@ private: static OpenXRAndroidExtension *singleton; }; -#endif // !OPENXR_ANDROID_EXTENSION_H +#endif // OPENXR_ANDROID_EXTENSION_H diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h index 0f7c0ba0bc..ecc6e0dd4e 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper.h +++ b/modules/openxr/extensions/openxr_extension_wrapper.h @@ -32,7 +32,7 @@ #define OPENXR_EXTENSION_WRAPPER_H #include "core/error/error_macros.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/hash_map.h" #include "core/templates/rid.h" @@ -97,11 +97,11 @@ public: virtual String get_swapchain_format_name(int64_t p_swapchain_format) const = 0; virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) = 0; virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) = 0; - virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) = 0; + virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) = 0; virtual bool copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) = 0; OpenXRGraphicsExtensionWrapper(OpenXRAPI *p_openxr_api) : OpenXRExtensionWrapper(p_openxr_api){}; }; -#endif // ~OPENXR_EXTENSION_WRAPPER_H +#endif // OPENXR_EXTENSION_WRAPPER_H diff --git a/modules/openxr/extensions/openxr_htc_vive_tracker_extension.h b/modules/openxr/extensions/openxr_htc_vive_tracker_extension.h index 7670bc074b..7f37351f27 100644 --- a/modules/openxr/extensions/openxr_htc_vive_tracker_extension.h +++ b/modules/openxr/extensions/openxr_htc_vive_tracker_extension.h @@ -49,4 +49,4 @@ private: bool available = false; }; -#endif // !OPENXR_HTC_VIVE_TRACKER_EXTENSION_H +#endif // OPENXR_HTC_VIVE_TRACKER_EXTENSION_H diff --git a/modules/openxr/extensions/openxr_vulkan_extension.cpp b/modules/openxr/extensions/openxr_vulkan_extension.cpp index 3d3d4de5b6..2608c4ac17 100644 --- a/modules/openxr/extensions/openxr_vulkan_extension.cpp +++ b/modules/openxr/extensions/openxr_vulkan_extension.cpp @@ -420,7 +420,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in return true; } -bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) { +bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) { // Even though this is a Vulkan renderer we're using OpenGL coordinate systems XrMatrix4x4f matrix; XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far); diff --git a/modules/openxr/extensions/openxr_vulkan_extension.h b/modules/openxr/extensions/openxr_vulkan_extension.h index 1e34fe1f80..5dddc4b9c9 100644 --- a/modules/openxr/extensions/openxr_vulkan_extension.h +++ b/modules/openxr/extensions/openxr_vulkan_extension.h @@ -63,7 +63,7 @@ public: virtual String get_swapchain_format_name(int64_t p_swapchain_format) const override; virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) override; virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override; - virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) override; + virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override; virtual bool copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) override; private: @@ -90,4 +90,4 @@ private: XrResult xrCreateVulkanDeviceKHR(XrInstance p_instance, const XrVulkanDeviceCreateInfoKHR *p_create_info, VkDevice *r_device, VkResult *r_result); }; -#endif // !OPENXR_VULKAN_EXTENSION_H +#endif // OPENXR_VULKAN_EXTENSION_H diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 5e35942012..92d074cb75 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -58,19 +58,14 @@ bool OpenXRAPI::openxr_is_enabled(bool p_check_run_in_editor) { // @TODO we need an overrule switch so we can force enable openxr, i.e run "godot --openxr_enabled" if (Engine::get_singleton()->is_editor_hint() && p_check_run_in_editor) { -#ifdef TOOLS_ENABLED // Disabled for now, using XR inside of the editor we'll be working on during the coming months. return false; - - // bool enabled = GLOBAL_GET("xr/openxr/in_editor"); // EDITOR_GET("xr/openxr/in_editor"); - // return enabled; -#else - // we should never get here, editor hint won't be true if the editor isn't compiled in. - return false; -#endif } else { - bool enabled = GLOBAL_GET("xr/openxr/enabled"); - return enabled; + if (XRServer::get_xr_mode() == XRServer::XRMODE_DEFAULT) { + return GLOBAL_GET("xr/openxr/enabled"); + } else { + return XRServer::get_xr_mode() == XRServer::XRMODE_ON; + } } } @@ -1180,7 +1175,7 @@ bool OpenXRAPI::get_view_transform(uint32_t p_view, Transform3D &r_transform) { return true; } -bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, CameraMatrix &p_camera_matrix) { +bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, Projection &p_camera_matrix) { ERR_FAIL_COND_V(!running, false); ERR_FAIL_NULL_V(graphics_extension, false); diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index fe9e2937b2..dc224c4237 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OPENXR_DRIVER_H -#define OPENXR_DRIVER_H +#ifndef OPENXR_API_H +#define OPENXR_API_H #include "core/error/error_macros.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/math/transform_3d.h" #include "core/math/vector2.h" #include "core/os/memory.h" @@ -249,7 +249,7 @@ public: Size2 get_recommended_target_size(); XRPose::TrackingConfidence get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity); bool get_view_transform(uint32_t p_view, Transform3D &r_transform); - bool get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, CameraMatrix &p_camera_matrix); + bool get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, Projection &p_camera_matrix); bool process(); void pre_render(); @@ -292,4 +292,4 @@ public: ~OpenXRAPI(); }; -#endif // !OPENXR_DRIVER_H +#endif // OPENXR_API_H diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index 9dfa005600..1447be5c77 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -631,8 +631,8 @@ Transform3D OpenXRInterface::get_transform_for_view(uint32_t p_view, const Trans return p_cam_transform * xr_server->get_reference_frame() * t; } -CameraMatrix OpenXRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { - CameraMatrix cm; +Projection OpenXRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { + Projection cm; if (openxr_api) { if (openxr_api->get_view_projection(p_view, p_z_near, p_z_far, cm)) { diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h index a223acfed0..a99012fd1d 100644 --- a/modules/openxr/openxr_interface.h +++ b/modules/openxr/openxr_interface.h @@ -121,7 +121,7 @@ public: virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual void process() override; virtual void pre_render() override; @@ -140,4 +140,4 @@ public: ~OpenXRInterface(); }; -#endif // !OPENXR_INTERFACE_H +#endif // OPENXR_INTERFACE_H diff --git a/modules/openxr/openxr_util.h b/modules/openxr/openxr_util.h index 4371b74d2f..a5cc7cd512 100644 --- a/modules/openxr/openxr_util.h +++ b/modules/openxr/openxr_util.h @@ -44,4 +44,4 @@ public: static String make_xr_version_string(XrVersion p_version); }; -#endif // !OPENXR_UTIL_H +#endif // OPENXR_UTIL_H diff --git a/modules/raycast/lightmap_raycaster.h b/modules/raycast/lightmap_raycaster.h index 4266b46ea8..2e9f59dda4 100644 --- a/modules/raycast/lightmap_raycaster.h +++ b/modules/raycast/lightmap_raycaster.h @@ -74,4 +74,4 @@ public: ~LightmapRaycasterEmbree(); }; -#endif +#endif // LIGHTMAP_RAYCASTER_H diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index 89e75f774e..13824c3830 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -30,6 +30,7 @@ #include "raycast_occlusion_cull.h" #include "core/config/project_settings.h" +#include "core/object/worker_thread_pool.h" #include "core/templates/local_vector.h" #ifdef __SSE2__ @@ -78,9 +79,9 @@ void RaycastOcclusionCull::RaycastHZBuffer::resize(const Size2i &p_size) { memset(camera_ray_masks.ptr(), ~0, camera_rays_tile_count * TILE_RAYS * sizeof(uint32_t)); } -void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool) { +void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) { CameraRayThreadData td; - td.thread_count = p_thread_work_pool.get_thread_count(); + td.thread_count = WorkerThreadPool::get_singleton()->get_thread_count(); td.z_near = p_cam_projection.get_z_near(); td.z_far = p_cam_projection.get_z_far() * 1.05f; @@ -88,7 +89,7 @@ void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D td.camera_dir = -p_cam_transform.basis.get_column(2); td.camera_orthogonal = p_cam_orthogonal; - CameraMatrix inv_camera_matrix = p_cam_projection.inverse(); + Projection inv_camera_matrix = p_cam_projection.inverse(); Vector3 camera_corner_proj = Vector3(-1.0f, -1.0f, -1.0f); Vector3 camera_corner_view = inv_camera_matrix.xform(camera_corner_proj); td.pixel_corner = p_cam_transform.xform(camera_corner_view); @@ -106,7 +107,8 @@ void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D debug_tex_range = td.z_far; - p_thread_work_pool.do_work(td.thread_count, this, &RaycastHZBuffer::_camera_rays_threaded, &td); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RaycastHZBuffer::_camera_rays_threaded, &td, td.thread_count, -1, true, SNAME("RaycastOcclusionCullUpdateCamera")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); } void RaycastOcclusionCull::RaycastHZBuffer::_camera_rays_threaded(uint32_t p_thread, const CameraRayThreadData *p_data) { @@ -331,10 +333,10 @@ void RaycastOcclusionCull::scenario_remove_instance(RID p_scenario, RID p_instan } void RaycastOcclusionCull::Scenario::_update_dirty_instance_thread(int p_idx, RID *p_instances) { - _update_dirty_instance(p_idx, p_instances, nullptr); + _update_dirty_instance(p_idx, p_instances); } -void RaycastOcclusionCull::Scenario::_update_dirty_instance(int p_idx, RID *p_instances, ThreadWorkPool *p_thread_pool) { +void RaycastOcclusionCull::Scenario::_update_dirty_instance(int p_idx, RID *p_instances) { OccluderInstance *occ_inst = instances.getptr(p_instances[p_idx]); if (!occ_inst) { @@ -355,14 +357,16 @@ void RaycastOcclusionCull::Scenario::_update_dirty_instance(int p_idx, RID *p_in const Vector3 *read_ptr = occ->vertices.ptr(); Vector3 *write_ptr = occ_inst->xformed_vertices.ptr(); - if (p_thread_pool && vertices_size > 1024) { + if (vertices_size > 1024) { TransformThreadData td; td.xform = occ_inst->xform; td.read = read_ptr; td.write = write_ptr; td.vertex_count = vertices_size; - td.thread_count = p_thread_pool->get_thread_count(); - p_thread_pool->do_work(td.thread_count, this, &Scenario::_transform_vertices_thread, &td); + td.thread_count = WorkerThreadPool::get_singleton()->get_thread_count(); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &Scenario::_transform_vertices_thread, &td, td.thread_count, -1, true, SNAME("RaycastOcclusionCull")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + } else { _transform_vertices_range(read_ptr, write_ptr, occ_inst->xform, 0, vertices_size); } @@ -392,7 +396,7 @@ void RaycastOcclusionCull::Scenario::_commit_scene(void *p_ud) { scenario->commit_done = true; } -bool RaycastOcclusionCull::Scenario::update(ThreadWorkPool &p_thread_pool) { +bool RaycastOcclusionCull::Scenario::update() { ERR_FAIL_COND_V(singleton == nullptr, false); if (commit_thread == nullptr) { @@ -426,13 +430,15 @@ bool RaycastOcclusionCull::Scenario::update(ThreadWorkPool &p_thread_pool) { instances.erase(removed_instances[i]); } - if (dirty_instances_array.size() / p_thread_pool.get_thread_count() > 128) { + if (dirty_instances_array.size() / WorkerThreadPool::get_singleton()->get_thread_count() > 128) { // Lots of instances, use per-instance threading - p_thread_pool.do_work(dirty_instances_array.size(), this, &Scenario::_update_dirty_instance_thread, dirty_instances_array.ptr()); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &Scenario::_update_dirty_instance_thread, dirty_instances_array.ptr(), dirty_instances_array.size(), -1, true, SNAME("RaycastOcclusionCullUpdate")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + } else { // Few instances, use threading on the vertex transforms for (unsigned int i = 0; i < dirty_instances_array.size(); i++) { - _update_dirty_instance(i, dirty_instances_array.ptr(), &p_thread_pool); + _update_dirty_instance(i, dirty_instances_array.ptr()); } } @@ -484,7 +490,7 @@ void RaycastOcclusionCull::Scenario::_raycast(uint32_t p_idx, const RaycastThrea rtcIntersect16((const int *)&p_raycast_data->masks[p_idx * TILE_RAYS], ebr_scene[current_scene_idx], &ctx, &p_raycast_data->rays[p_idx]); } -void RaycastOcclusionCull::Scenario::raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count, ThreadWorkPool &p_thread_pool) const { +void RaycastOcclusionCull::Scenario::raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count) const { ERR_FAIL_COND(singleton == nullptr); if (raycast_singleton->ebr_device == nullptr) { return; // Embree is initialized on demand when there is some scenario with occluders in it. @@ -498,7 +504,8 @@ void RaycastOcclusionCull::Scenario::raycast(CameraRayTile *r_rays, const uint32 td.rays = r_rays; td.masks = p_valid_masks; - p_thread_pool.do_work(p_tile_count, this, &Scenario::_raycast, &td); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &Scenario::_raycast, &td, p_tile_count, -1, true, SNAME("RaycastOcclusionCullRaycast")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); } //////////////////////////////////////////////////////// @@ -524,7 +531,7 @@ void RaycastOcclusionCull::buffer_set_size(RID p_buffer, const Vector2i &p_size) buffers[p_buffer].resize(p_size); } -void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) { +void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) { if (!buffers.has(p_buffer)) { return; } @@ -537,16 +544,16 @@ void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_ Scenario &scenario = scenarios[buffer.scenario_rid]; - bool removed = scenario.update(p_thread_pool); + bool removed = scenario.update(); if (removed) { scenarios.erase(buffer.scenario_rid); return; } - buffer.update_camera_rays(p_cam_transform, p_cam_projection, p_cam_orthogonal, p_thread_pool); + buffer.update_camera_rays(p_cam_transform, p_cam_projection, p_cam_orthogonal); - scenario.raycast(buffer.camera_rays, buffer.camera_ray_masks.ptr(), buffer.camera_rays_tile_count, p_thread_pool); + scenario.raycast(buffer.camera_rays, buffer.camera_ray_masks.ptr(), buffer.camera_rays_tile_count); buffer.sort_rays(-p_cam_transform.basis.get_column(2), p_cam_orthogonal); buffer.update_mips(); } diff --git a/modules/raycast/raycast_occlusion_cull.h b/modules/raycast/raycast_occlusion_cull.h index 6562c4e9c4..056b808640 100644 --- a/modules/raycast/raycast_occlusion_cull.h +++ b/modules/raycast/raycast_occlusion_cull.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OCCLUSION_CULL_RAYCASTER_H -#define OCCLUSION_CULL_RAYCASTER_H +#ifndef RAYCAST_OCCLUSION_CULL_H +#define RAYCAST_OCCLUSION_CULL_H #include "core/io/image.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/object/object.h" #include "core/object/ref_counted.h" #include "core/templates/local_vector.h" @@ -76,7 +76,7 @@ public: virtual void clear() override; virtual void resize(const Size2i &p_size) override; void sort_rays(const Vector3 &p_camera_dir, bool p_orthogonal); - void update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool); + void update_camera_rays(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal); ~RaycastHZBuffer(); }; @@ -143,14 +143,14 @@ private: LocalVector<RID> removed_instances; void _update_dirty_instance_thread(int p_idx, RID *p_instances); - void _update_dirty_instance(int p_idx, RID *p_instances, ThreadWorkPool *p_thread_pool); + void _update_dirty_instance(int p_idx, RID *p_instances); void _transform_vertices_thread(uint32_t p_thread, TransformThreadData *p_data); void _transform_vertices_range(const Vector3 *p_read, Vector3 *p_write, const Transform3D &p_xform, int p_from, int p_to); static void _commit_scene(void *p_ud); - bool update(ThreadWorkPool &p_thread_pool); + bool update(); void _raycast(uint32_t p_thread, const RaycastThreadData *p_raycast_data) const; - void raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count, ThreadWorkPool &p_thread_pool) const; + void raycast(CameraRayTile *r_rays, const uint32_t *p_valid_masks, uint32_t p_tile_count) const; }; static RaycastOcclusionCull *raycast_singleton; @@ -183,7 +183,8 @@ public: virtual HZBuffer *buffer_get_ptr(RID p_buffer) override; virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) override; virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) override; - virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) override; + virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) override; + virtual RID buffer_get_debug_texture(RID p_buffer) override; virtual void set_build_quality(RS::ViewportOcclusionCullingBuildQuality p_quality) override; @@ -192,4 +193,4 @@ public: ~RaycastOcclusionCull(); }; -#endif // OCCLUSION_CULL_RAYCASTER_H +#endif // RAYCAST_OCCLUSION_CULL_H diff --git a/modules/raycast/static_raycaster.h b/modules/raycast/static_raycaster.h index e2909f9b56..607a392683 100644 --- a/modules/raycast/static_raycaster.h +++ b/modules/raycast/static_raycaster.h @@ -61,4 +61,4 @@ public: ~StaticRaycasterEmbree(); }; -#endif +#endif // STATIC_RAYCASTER_H diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index dcb1f1d744..87e2fae2d0 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -80,8 +80,8 @@ void ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, String p_strin float fw, fh; picture->size(&fw, &fh); - uint32_t width = MIN(fw * p_scale, 16 * 1024); - uint32_t height = MIN(fh * p_scale, 16 * 1024); + uint32_t width = MIN(round(fw * p_scale), 16 * 1024); + uint32_t height = MIN(round(fh * p_scale), 16 * 1024); picture->size(width, height); std::unique_ptr<tvg::SwCanvas> sw_canvas = tvg::SwCanvas::gen(); diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct index 69848a9e52..0170c007ae 100644 --- a/modules/text_server_adv/gdextension_build/SConstruct +++ b/modules/text_server_adv/gdextension_build/SConstruct @@ -624,15 +624,15 @@ env.Append(CPPDEFINES=["GDEXTENSION"]) env.Append(CPPPATH=["../"]) sources = Glob("../*.cpp") -if env["platform"] == "osx": - methods.write_osx_plist( - f'./bin/libtextserver_advanced.osx.{env["target"]}.framework', - f'libtextserver_advanced.osx.{env["target"]}', +if env["platform"] == "macos": + methods.write_macos_plist( + f'./bin/libtextserver_advanced.macos.{env["target"]}.framework', + f'libtextserver_advanced.macos.{env["target"]}', "org.godotengine.textserver_advanced", "ICU / HarfBuzz / Graphite Text Server", ) library = env.SharedLibrary( - f'./bin/libtextserver_advanced.osx.{env["target"]}.framework/libtextserver_advanced.osx.{env["target"]}', + f'./bin/libtextserver_advanced.macos.{env["target"]}.framework/libtextserver_advanced.macos.{env["target"]}', source=sources, ) else: diff --git a/modules/text_server_adv/gdextension_build/methods.py b/modules/text_server_adv/gdextension_build/methods.py index d404f2851e..3c5229462c 100644 --- a/modules/text_server_adv/gdextension_build/methods.py +++ b/modules/text_server_adv/gdextension_build/methods.py @@ -98,7 +98,7 @@ def make_icu_data(target, source, env): g.write("#endif") -def write_osx_plist(target, binary_name, identifier, name): +def write_macos_plist(target, binary_name, identifier, name): os.makedirs(f"{target}/Resourece/", exist_ok=True) f = open(f"{target}/Resourece/Info.plist", "w") diff --git a/modules/text_server_adv/gdextension_build/text_server_adv.gdextension b/modules/text_server_adv/gdextension_build/text_server_adv.gdextension index 5956476a5e..11ed271ae9 100644 --- a/modules/text_server_adv/gdextension_build/text_server_adv.gdextension +++ b/modules/text_server_adv/gdextension_build/text_server_adv.gdextension @@ -8,5 +8,5 @@ linux.64.debug = "bin/libtextserver_advanced.linux.debug.64.so" linux.64.release = "bin/libtextserver_advanced.linux.release.64.so" windows.64.debug = "bin/libtextserver_advanced.windows.debug.64.dll" windows.64.release = "bin/libtextserver_advanced.windows.release.64.dll" -macos.debug = "bin/libtextserver_advanced.osx.debug.framework" -macos.release = "bin/libtextserver_advanced.osx.release.framework" +macos.debug = "bin/libtextserver_advanced.macos.debug.framework" +macos.release = "bin/libtextserver_advanced.macos.release.framework" diff --git a/modules/text_server_adv/script_iterator.h b/modules/text_server_adv/script_iterator.h index 2bd045b91a..025b62c6fb 100644 --- a/modules/text_server_adv/script_iterator.h +++ b/modules/text_server_adv/script_iterator.h @@ -75,4 +75,4 @@ public: ScriptIterator(const String &p_string, int p_start, int p_length); }; -#endif //SCRIPT_ITERATOR_H +#endif // SCRIPT_ITERATOR_H diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index fe2279df69..fa234081f0 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "text_server_adv.h" +#include "core/object/worker_thread_pool.h" #ifdef GDEXTENSION // Headers for building as GDExtension plug-in. @@ -1039,10 +1040,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( td.projection = &projection; td.distancePixelConversion = &distancePixelConversion; - if (p_font_data->work_pool.get_thread_count() == 0) { - p_font_data->work_pool.init(); - } - p_font_data->work_pool.do_work(h, this, &TextServerAdvanced::_generateMTSDF_threaded, &td); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &TextServerAdvanced::_generateMTSDF_threaded, &td, h, -1, true, SNAME("FontServerRasterizeMSDF")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); msdfgen::msdfErrorCorrection(image, shape, projection, p_pixel_range, config); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index a772955d90..8cd0e753ba 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -65,11 +65,12 @@ #include <godot_cpp/classes/image.hpp> #include <godot_cpp/classes/image_texture.hpp> #include <godot_cpp/classes/ref.hpp> +#include <godot_cpp/classes/worker_thread_pool.hpp> #include <godot_cpp/templates/hash_map.hpp> #include <godot_cpp/templates/hash_set.hpp> #include <godot_cpp/templates/rid_owner.hpp> -#include <godot_cpp/templates/thread_work_pool.hpp> + #include <godot_cpp/templates/vector.hpp> using namespace godot; @@ -77,9 +78,9 @@ using namespace godot; #else // Headers for building as built-in module. +#include "core/object/worker_thread_pool.h" #include "core/templates/hash_map.h" #include "core/templates/rid_owner.h" -#include "core/templates/thread_work_pool.h" #include "scene/resources/texture.h" #include "servers/text/text_server_extension.h" @@ -252,10 +253,8 @@ class TextServerAdvanced : public TextServerExtension { const uint8_t *data_ptr; size_t data_size; int face_index = 0; - mutable ThreadWorkPool work_pool; ~FontAdvanced() { - work_pool.finish(); for (const KeyValue<Vector2i, FontForSizeAdvanced *> &E : cache) { memdelete(E.value); } diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct index 6c9e10db18..de0a549900 100644 --- a/modules/text_server_fb/gdextension_build/SConstruct +++ b/modules/text_server_fb/gdextension_build/SConstruct @@ -184,15 +184,15 @@ env.Append(CPPDEFINES=["GDEXTENSION"]) env.Append(CPPPATH=["../"]) sources = Glob("../*.cpp") -if env["platform"] == "osx": - methods.write_osx_plist( - f'./bin/libtextserver_fallback.osx.{env["target"]}.framework', - f'libtextserver_fallback.osx.{env["target"]}', +if env["platform"] == "macos": + methods.write_macos_plist( + f'./bin/libtextserver_fallback.macos.{env["target"]}.framework', + f'libtextserver_fallback.macos.{env["target"]}', "org.godotengine.textserver_fallback", "Fallback Text Server", ) library = env.SharedLibrary( - f'./bin/libtextserver_fallback.osx.{env["target"]}.framework/libtextserver_fallback.osx.{env["target"]}', + f'./bin/libtextserver_fallback.macos.{env["target"]}.framework/libtextserver_fallback.macos.{env["target"]}', source=sources, ) else: diff --git a/modules/text_server_fb/gdextension_build/methods.py b/modules/text_server_fb/gdextension_build/methods.py index d404f2851e..3c5229462c 100644 --- a/modules/text_server_fb/gdextension_build/methods.py +++ b/modules/text_server_fb/gdextension_build/methods.py @@ -98,7 +98,7 @@ def make_icu_data(target, source, env): g.write("#endif") -def write_osx_plist(target, binary_name, identifier, name): +def write_macos_plist(target, binary_name, identifier, name): os.makedirs(f"{target}/Resourece/", exist_ok=True) f = open(f"{target}/Resourece/Info.plist", "w") diff --git a/modules/text_server_fb/gdextension_build/text_server_fb.gdextension b/modules/text_server_fb/gdextension_build/text_server_fb.gdextension index 1026c6cb85..9236555d63 100644 --- a/modules/text_server_fb/gdextension_build/text_server_fb.gdextension +++ b/modules/text_server_fb/gdextension_build/text_server_fb.gdextension @@ -8,5 +8,5 @@ linux.64.debug = "bin/libtextserver_fallback.linux.debug.64.so" linux.64.release = "bin/libtextserver_fallback.linux.release.64.so" windows.64.debug = "bin/libtextserver_fallback.windows.debug.64.dll" windows.64.release = "bin/libtextserver_fallback.windows.release.64.dll" -macos.debug = "bin/libtextserver_fallback.osx.debug.framework" -macos.release = "bin/libtextserver_fallback.osx.release.framework" +macos.debug = "bin/libtextserver_fallback.macos.debug.framework" +macos.release = "bin/libtextserver_fallback.macos.release.framework" diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index b845beb158..50ea4677b1 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -461,10 +461,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( td.projection = &projection; td.distancePixelConversion = &distancePixelConversion; - if (p_font_data->work_pool.get_thread_count() == 0) { - p_font_data->work_pool.init(); - } - p_font_data->work_pool.do_work(h, this, &TextServerFallback::_generateMTSDF_threaded, &td); + WorkerThreadPool::GroupID group_id = WorkerThreadPool::get_singleton()->add_template_group_task(this, &TextServerFallback::_generateMTSDF_threaded, &td, h, -1, true, SNAME("TextServerFBRenderMSDF")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_id); msdfgen::msdfErrorCorrection(image, shape, projection, p_pixel_range, config); diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 497403afd7..adb5cbb817 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TEXT_SERVER_FALLBACK_H -#define TEXT_SERVER_FALLBACK_H +#ifndef TEXT_SERVER_FB_H +#define TEXT_SERVER_FB_H /*************************************************************************/ /* Fallback Text Server provides simplified TS functionality, without */ @@ -79,9 +79,9 @@ using namespace godot; #include "servers/text/text_server_extension.h" +#include "core/object/worker_thread_pool.h" #include "core/templates/hash_map.h" #include "core/templates/rid_owner.h" -#include "core/templates/thread_work_pool.h" #include "scene/resources/texture.h" #include "modules/modules_enabled.gen.h" // For freetype, msdfgen. @@ -208,10 +208,7 @@ class TextServerFallback : public TextServerExtension { size_t data_size; int face_index = 0; - mutable ThreadWorkPool work_pool; - ~FontFallback() { - work_pool.finish(); for (const KeyValue<Vector2i, FontForSizeFallback *> &E : cache) { memdelete(E.value); } @@ -586,4 +583,4 @@ public: ~TextServerFallback(); }; -#endif // TEXT_SERVER_FALLBACK_H +#endif // TEXT_SERVER_FB_H diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index 8940ed6aff..00d799dc24 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -170,7 +170,7 @@ protected: static void _bind_methods(); public: - Ref<VideoStreamPlayback> instance_playback() override { + Ref<VideoStreamPlayback> instantiate_playback() override { Ref<VideoStreamPlaybackTheora> pb = memnew(VideoStreamPlaybackTheora); pb->set_audio_track(audio_track); pb->set_file(file); @@ -192,4 +192,4 @@ public: virtual String get_resource_type(const String &p_path) const; }; -#endif +#endif // VIDEO_STREAM_THEORA_H diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h index c147861c26..0d3de93956 100644 --- a/modules/tinyexr/image_loader_tinyexr.h +++ b/modules/tinyexr/image_loader_tinyexr.h @@ -40,4 +40,4 @@ public: ImageLoaderTinyEXR(); }; -#endif +#endif // IMAGE_LOADER_TINYEXR_H diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h index 6d87b42c56..be7ede3ee0 100644 --- a/modules/upnp/upnp.h +++ b/modules/upnp/upnp.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_UPNP_H -#define GODOT_UPNP_H +#ifndef UPNP_H +#define UPNP_H #include "core/object/ref_counted.h" @@ -121,4 +121,4 @@ public: VARIANT_ENUM_CAST(UPNP::UPNPResult) -#endif // GODOT_UPNP_H +#endif // UPNP_H diff --git a/modules/upnp/upnp_device.h b/modules/upnp/upnp_device.h index 18491dce27..1c9dc82df5 100644 --- a/modules/upnp/upnp_device.h +++ b/modules/upnp/upnp_device.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_UPNP_DEVICE_H -#define GODOT_UPNP_DEVICE_H +#ifndef UPNP_DEVICE_H +#define UPNP_DEVICE_H #include "core/object/ref_counted.h" @@ -90,4 +90,4 @@ private: VARIANT_ENUM_CAST(UPNPDevice::IGDStatus) -#endif // GODOT_UPNP_DEVICE_H +#endif // UPNP_DEVICE_H diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 61ff56b62a..74a61bc4b7 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -376,6 +376,12 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::VECTOR3I: color = Color(0.84, 0.49, 0.93); break; + case Variant::VECTOR4: + color = Color(0.84, 0.49, 0.94); + break; + case Variant::VECTOR4I: + color = Color(0.84, 0.49, 0.94); + break; case Variant::TRANSFORM2D: color = Color(0.77, 0.93, 0.41); break; @@ -1227,7 +1233,7 @@ void VisualScriptEditor::_member_selected() { selected = ti->get_metadata(0); if (ti->get_parent() == members->get_root()->get_first_child()) { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::META); #else bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL); @@ -2208,7 +2214,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant & String(d["type"]) == "files" || String(d["type"]) == "nodes")) { if (String(d["type"]) == "obj_property") { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Getter. Hold Shift to drop a generic signature."), find_keycode_name(Key::META))); #else const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature.")); @@ -2216,7 +2222,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant & } if (String(d["type"]) == "nodes") { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a simple reference to the node."), find_keycode_name(Key::META))); #else const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a simple reference to the node.")); @@ -2224,7 +2230,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant & } if (String(d["type"]) == "visual_script_variable_drag") { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Variable Setter."), find_keycode_name(Key::META))); #else const_cast<VisualScriptEditor *>(this)->_show_hint(TTR("Hold Ctrl to drop a Variable Setter.")); @@ -2287,7 +2293,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } if (String(d["type"]) == "visual_script_variable_drag") { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool use_set = Input::get_singleton()->is_key_pressed(Key::META); #else bool use_set = Input::get_singleton()->is_key_pressed(Key::CTRL); @@ -2396,7 +2402,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da } if (String(d["type"]) == "files") { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool use_preload = Input::get_singleton()->is_key_pressed(Key::META); #else bool use_preload = Input::get_singleton()->is_key_pressed(Key::CTRL); @@ -2459,7 +2465,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da return; } -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool use_node = Input::get_singleton()->is_key_pressed(Key::META); #else bool use_node = Input::get_singleton()->is_key_pressed(Key::CTRL); @@ -2524,7 +2530,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da Node *node = Object::cast_to<Node>(obj); Vector2 pos = _get_pos_in_graph(p_point); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool use_get = Input::get_singleton()->is_key_pressed(Key::META); #else bool use_get = Input::get_singleton()->is_key_pressed(Key::CTRL); @@ -3378,7 +3384,7 @@ void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<Visua } void VisualScriptEditor::_selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting) { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::META); #else bool held_ctrl = Input::get_singleton()->is_key_pressed(Key::CTRL); @@ -4821,12 +4827,15 @@ VisualScriptEditor::VisualScriptEditor() { base_type_map.insert("Rect2i", Variant::RECT2I); base_type_map.insert("Vector3", Variant::VECTOR3); base_type_map.insert("Vector3i", Variant::VECTOR3I); + base_type_map.insert("Vector4", Variant::VECTOR4); + base_type_map.insert("Vector4i", Variant::VECTOR4I); base_type_map.insert("Transform2D", Variant::TRANSFORM2D); base_type_map.insert("Plane", Variant::PLANE); base_type_map.insert("Quaternion", Variant::QUATERNION); base_type_map.insert("AABB", Variant::AABB); base_type_map.insert("Basis", Variant::BASIS); base_type_map.insert("Transform3D", Variant::TRANSFORM3D); + base_type_map.insert("Projection", Variant::PROJECTION); base_type_map.insert("Color", Variant::COLOR); base_type_map.insert("NodePath", Variant::NODE_PATH); base_type_map.insert("RID", Variant::RID); diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h index fd59d22cbe..a6df7bba73 100644 --- a/modules/visual_script/editor/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VISUALSCRIPT_EDITOR_H -#define VISUALSCRIPT_EDITOR_H +#ifndef VISUAL_SCRIPT_EDITOR_H +#define VISUAL_SCRIPT_EDITOR_H #include "../visual_script.h" #include "editor/create_dialog.h" @@ -374,4 +374,4 @@ public: #endif -#endif // VISUALSCRIPT_EDITOR_H +#endif // VISUAL_SCRIPT_EDITOR_H diff --git a/modules/visual_script/editor/visual_script_property_selector.h b/modules/visual_script/editor/visual_script_property_selector.h index 91d81bba47..41f8eea735 100644 --- a/modules/visual_script/editor/visual_script_property_selector.h +++ b/modules/visual_script/editor/visual_script_property_selector.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VISUALSCRIPT_PROPERTYSELECTOR_H -#define VISUALSCRIPT_PROPERTYSELECTOR_H +#ifndef VISUAL_SCRIPT_PROPERTY_SELECTOR_H +#define VISUAL_SCRIPT_PROPERTY_SELECTOR_H #include "../visual_script.h" #include "editor/editor_help.h" @@ -226,4 +226,4 @@ public: SearchRunner(VisualScriptPropertySelector *p_selector_ui, Tree *p_results_tree); }; -#endif // VISUALSCRIPT_PROPERTYSELECTOR_H +#endif // VISUAL_SCRIPT_PROPERTY_SELECTOR_H diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 742fa75bb7..1ef3723011 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -948,7 +948,7 @@ bool VisualScript::are_subnodes_edited() const { } #endif -const Vector<Multiplayer::RPCConfig> VisualScript::get_rpc_methods() const { +const Variant VisualScript::get_rpc_config() const { return rpc_functions; } @@ -1012,22 +1012,16 @@ void VisualScript::_set_data(const Dictionary &p_data) { for (const KeyValue<StringName, Function> &E : functions) { if (E.value.func_id >= 0 && nodes.has(E.value.func_id)) { Ref<VisualScriptFunction> vsf = nodes[E.value.func_id].node; - if (vsf.is_valid()) { - if (vsf->get_rpc_mode() != Multiplayer::RPC_MODE_DISABLED) { - Multiplayer::RPCConfig nd; - nd.name = E.key; - nd.rpc_mode = vsf->get_rpc_mode(); - nd.transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; // TODO - if (rpc_functions.find(nd) == -1) { - rpc_functions.push_back(nd); - } - } + if (!vsf.is_valid() || vsf->get_rpc_mode() == MultiplayerAPI::RPC_MODE_DISABLED) { + continue; } + Dictionary nd; + nd["rpc_mode"] = vsf->get_rpc_mode(); + nd["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE; // TODO + nd["call_local"] = false; // TODO + rpc_functions[E.key] = nd; } } - - // Sort so we are 100% that they are always the same. - rpc_functions.sort_custom<Multiplayer::SortRPCConfig>(); } Dictionary VisualScript::_get_data() const { @@ -1811,8 +1805,8 @@ Ref<Script> VisualScriptInstance::get_script() const { return script; } -const Vector<Multiplayer::RPCConfig> VisualScriptInstance::get_rpc_methods() const { - return script->get_rpc_methods(); +const Variant VisualScriptInstance::get_rpc_config() const { + return script->get_rpc_config(); } void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) { diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 716310f59b..14cb14e8d9 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -235,7 +235,7 @@ private: HashMap<StringName, Function> functions; HashMap<StringName, Variable> variables; HashMap<StringName, Vector<Argument>> custom_signals; - Vector<Multiplayer::RPCConfig> rpc_functions; + Dictionary rpc_functions; HashMap<Object *, VisualScriptInstance *> instances; @@ -363,7 +363,7 @@ public: virtual int get_member_line(const StringName &p_member) const override; - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override; + virtual const Variant get_rpc_config() const override; #ifdef TOOLS_ENABLED virtual bool are_subnodes_edited() const; @@ -444,7 +444,7 @@ public: virtual ScriptLanguage *get_language(); - virtual const Vector<Multiplayer::RPCConfig> get_rpc_methods() const; + virtual const Variant get_rpc_config() const; VisualScriptInstance(); ~VisualScriptInstance(); diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h index c93eb0686b..7e10f98f36 100644 --- a/modules/visual_script/visual_script_expression.h +++ b/modules/visual_script/visual_script_expression.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VISUALSCRIPTEXPRESSION_H -#define VISUALSCRIPTEXPRESSION_H +#ifndef VISUAL_SCRIPT_EXPRESSION_H +#define VISUAL_SCRIPT_EXPRESSION_H #include "visual_script.h" #include "visual_script_builtin_funcs.h" @@ -281,4 +281,4 @@ public: void register_visual_script_expression_node(); -#endif // VISUALSCRIPTEXPRESSION_H +#endif // VISUAL_SCRIPT_EXPRESSION_H diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 2dfc6da181..5907e6a489 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -90,7 +90,7 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value } if (p_name == "rpc/mode") { - rpc_mode = Multiplayer::RPCMode(int(p_value)); + rpc_mode = MultiplayerAPI::RPCMode(int(p_value)); return true; } @@ -261,11 +261,11 @@ int VisualScriptFunction::get_argument_count() const { return arguments.size(); } -void VisualScriptFunction::set_rpc_mode(Multiplayer::RPCMode p_mode) { +void VisualScriptFunction::set_rpc_mode(MultiplayerAPI::RPCMode p_mode) { rpc_mode = p_mode; } -Multiplayer::RPCMode VisualScriptFunction::get_rpc_mode() const { +MultiplayerAPI::RPCMode VisualScriptFunction::get_rpc_mode() const { return rpc_mode; } @@ -311,14 +311,14 @@ void VisualScriptFunction::reset_state() { stack_size = 256; stack_less = false; sequenced = true; - rpc_mode = Multiplayer::RPC_MODE_DISABLED; + rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; } VisualScriptFunction::VisualScriptFunction() { stack_size = 256; stack_less = false; sequenced = true; - rpc_mode = Multiplayer::RPC_MODE_DISABLED; + rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED; } void VisualScriptFunction::set_stack_less(bool p_enable) { @@ -4025,6 +4025,8 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2I), create_node_deconst_typed<Variant::Type::VECTOR2I>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3), create_node_deconst_typed<Variant::Type::VECTOR3>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3I), create_node_deconst_typed<Variant::Type::VECTOR3I>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR4), create_node_deconst_typed<Variant::Type::VECTOR4>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR4I), create_node_deconst_typed<Variant::Type::VECTOR4I>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::COLOR), create_node_deconst_typed<Variant::Type::COLOR>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2), create_node_deconst_typed<Variant::Type::RECT2>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2I), create_node_deconst_typed<Variant::Type::RECT2I>); @@ -4034,6 +4036,7 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::AABB), create_node_deconst_typed<Variant::Type::AABB>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::BASIS), create_node_deconst_typed<Variant::Type::BASIS>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM3D), create_node_deconst_typed<Variant::Type::TRANSFORM3D>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PROJECTION), create_node_deconst_typed<Variant::Type::PROJECTION>); VisualScriptLanguage::singleton->add_register_func("functions/compose_array", create_node_generic<VisualScriptComposeArray>); for (int i = 1; i < Variant::VARIANT_MAX; i++) { diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h index 18573f8682..35e3c490cd 100644 --- a/modules/visual_script/visual_script_nodes.h +++ b/modules/visual_script/visual_script_nodes.h @@ -33,6 +33,7 @@ #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" +#include "scene/main/multiplayer_api.h" #include "visual_script.h" class VisualScriptFunction : public VisualScriptNode { @@ -49,7 +50,7 @@ class VisualScriptFunction : public VisualScriptNode { bool stack_less; int stack_size; - Multiplayer::RPCMode rpc_mode; + MultiplayerAPI::RPCMode rpc_mode; bool sequenced; protected: @@ -90,8 +91,8 @@ public: void set_stack_size(int p_size); int get_stack_size() const; - void set_rpc_mode(Multiplayer::RPCMode p_mode); - Multiplayer::RPCMode get_rpc_mode() const; + void set_rpc_mode(MultiplayerAPI::RPCMode p_mode); + MultiplayerAPI::RPCMode get_rpc_mode() const; virtual VisualScriptNodeInstance *instantiate(VisualScriptInstance *p_instance) override; diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp index 89a6b03ff8..8315eea614 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp @@ -34,7 +34,7 @@ #include "core/variant/typed_array.h" #include "thirdparty/libogg/ogg/ogg.h" -int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) { +int AudioStreamPlaybackOggVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) { ERR_FAIL_COND_V(!ready, 0); if (!active) { @@ -43,28 +43,93 @@ int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram int todo = p_frames; - int start_buffer = 0; + int beat_length_frames = -1; + bool beat_loop = vorbis_stream->has_loop(); + if (beat_loop && vorbis_stream->get_bpm() > 0 && vorbis_stream->get_beat_count() > 0) { + beat_length_frames = vorbis_stream->get_beat_count() * vorbis_data->get_sampling_rate() * 60 / vorbis_stream->get_bpm(); + } while (todo > 0 && active) { AudioFrame *buffer = p_buffer; - if (start_buffer > 0) { - buffer = buffer + start_buffer; + buffer += p_frames - todo; + + int to_mix = todo; + if (beat_length_frames >= 0 && (beat_length_frames - (int)frames_mixed) < to_mix) { + to_mix = MAX(0, beat_length_frames - (int)frames_mixed); } - int mixed = _mix_frames_vorbis(buffer, todo); + + int mixed = _mix_frames_vorbis(buffer, to_mix); ERR_FAIL_COND_V(mixed < 0, 0); todo -= mixed; frames_mixed += mixed; - start_buffer += mixed; + + if (loop_fade_remaining < FADE_SIZE) { + int to_fade = loop_fade_remaining + MIN(FADE_SIZE - loop_fade_remaining, mixed); + for (int i = loop_fade_remaining; i < to_fade; i++) { + buffer[i - loop_fade_remaining] += loop_fade[i] * (float(FADE_SIZE - i) / float(FADE_SIZE)); + } + loop_fade_remaining = to_fade; + } + + if (beat_length_frames >= 0) { + /** + * Length determined by beat length + * This code is commented out because, in practice, it is prefered that the fade + * is done by the transitioner and this stream just goes on until it ends while fading out. + * + * End fade implementation is left here for reference in case at some point this feature + * is desired. + + if (!beat_loop && (int)frames_mixed > beat_length_frames - FADE_SIZE) { + print_line("beat length fade/after mix?"); + //No loop, just fade and finish + for (int i = 0; i < mixed; i++) { + int idx = frames_mixed + i - mixed; + buffer[i] *= 1.0 - float(MAX(0, (idx - (beat_length_frames - FADE_SIZE)))) / float(FADE_SIZE); + } + if ((int)frames_mixed == beat_length_frames) { + for (int i = p_frames - todo; i < p_frames; i++) { + p_buffer[i] = AudioFrame(0, 0); + } + active = false; + break; + } + } else + **/ + + if (beat_loop && beat_length_frames <= (int)frames_mixed) { + // End of file when doing beat-based looping. <= used instead of == because importer editing + if (!have_packets_left && !have_samples_left) { + //Nothing remaining, so do nothing. + loop_fade_remaining = FADE_SIZE; + } else { + // Add some loop fade; + int faded_mix = _mix_frames_vorbis(loop_fade, FADE_SIZE); + + for (int i = faded_mix; i < FADE_SIZE; i++) { + // In case lesss was mixed, pad with zeros + loop_fade[i] = AudioFrame(0, 0); + } + loop_fade_remaining = 0; + } + + seek(vorbis_stream->loop_offset); + loops++; + // We still have buffer to fill, start from this element in the next iteration. + continue; + } + } + if (!have_packets_left && !have_samples_left) { - //end of file! + // Actual end of file! bool is_not_empty = mixed > 0 || vorbis_stream->get_length() > 0; if (vorbis_stream->loop && is_not_empty) { //loop seek(vorbis_stream->loop_offset); loops++; - // we still have buffer to fill, start from this element in the next iteration. - start_buffer = p_frames - todo; + // We still have buffer to fill, start from this element in the next iteration. + } else { for (int i = p_frames - todo; i < p_frames; i++) { p_buffer[i] = AudioFrame(0, 0); @@ -76,7 +141,7 @@ int AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram return p_frames - todo; } -int AudioStreamPlaybackOGGVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p_frames) { +int AudioStreamPlaybackOggVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p_frames) { ERR_FAIL_COND_V(!ready, 0); if (!have_samples_left) { ogg_packet *packet = nullptr; @@ -119,18 +184,18 @@ int AudioStreamPlaybackOGGVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p return frames; } -float AudioStreamPlaybackOGGVorbis::get_stream_sampling_rate() { +float AudioStreamPlaybackOggVorbis::get_stream_sampling_rate() { return vorbis_data->get_sampling_rate(); } -bool AudioStreamPlaybackOGGVorbis::_alloc_vorbis() { +bool AudioStreamPlaybackOggVorbis::_alloc_vorbis() { vorbis_info_init(&info); info_is_allocated = true; vorbis_comment_init(&comment); comment_is_allocated = true; ERR_FAIL_COND_V(vorbis_data.is_null(), false); - vorbis_data_playback = vorbis_data->instance_playback(); + vorbis_data_playback = vorbis_data->instantiate_playback(); ogg_packet *packet; int err; @@ -158,31 +223,36 @@ bool AudioStreamPlaybackOGGVorbis::_alloc_vorbis() { return true; } -void AudioStreamPlaybackOGGVorbis::start(float p_from_pos) { +void AudioStreamPlaybackOggVorbis::start(float p_from_pos) { ERR_FAIL_COND(!ready); + loop_fade_remaining = FADE_SIZE; active = true; seek(p_from_pos); loops = 0; begin_resample(); } -void AudioStreamPlaybackOGGVorbis::stop() { +void AudioStreamPlaybackOggVorbis::stop() { active = false; } -bool AudioStreamPlaybackOGGVorbis::is_playing() const { +bool AudioStreamPlaybackOggVorbis::is_playing() const { return active; } -int AudioStreamPlaybackOGGVorbis::get_loop_count() const { +int AudioStreamPlaybackOggVorbis::get_loop_count() const { return loops; } -float AudioStreamPlaybackOGGVorbis::get_playback_position() const { +float AudioStreamPlaybackOggVorbis::get_playback_position() const { return float(frames_mixed) / vorbis_data->get_sampling_rate(); } -void AudioStreamPlaybackOGGVorbis::seek(float p_time) { +void AudioStreamPlaybackOggVorbis::tag_used_streams() { + vorbis_stream->tag_used(get_playback_position()); +} + +void AudioStreamPlaybackOggVorbis::seek(float p_time) { ERR_FAIL_COND(!ready); ERR_FAIL_COND(vorbis_stream.is_null()); if (!active) { @@ -300,7 +370,7 @@ void AudioStreamPlaybackOGGVorbis::seek(float p_time) { } } -AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() { +AudioStreamPlaybackOggVorbis::~AudioStreamPlaybackOggVorbis() { if (block_is_allocated) { vorbis_block_clear(&block); } @@ -315,13 +385,13 @@ AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() { } } -Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() { - Ref<AudioStreamPlaybackOGGVorbis> ovs; +Ref<AudioStreamPlayback> AudioStreamOggVorbis::instantiate_playback() { + Ref<AudioStreamPlaybackOggVorbis> ovs; ERR_FAIL_COND_V(packet_sequence.is_null(), nullptr); ovs.instantiate(); - ovs->vorbis_stream = Ref<AudioStreamOGGVorbis>(this); + ovs->vorbis_stream = Ref<AudioStreamOggVorbis>(this); ovs->vorbis_data = packet_sequence; ovs->frames_mixed = 0; ovs->active = false; @@ -333,11 +403,11 @@ Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() { return nullptr; } -String AudioStreamOGGVorbis::get_stream_name() const { +String AudioStreamOggVorbis::get_stream_name() const { return ""; //return stream_name; } -void AudioStreamOGGVorbis::maybe_update_info() { +void AudioStreamOggVorbis::maybe_update_info() { ERR_FAIL_COND(packet_sequence.is_null()); vorbis_info info; @@ -347,7 +417,7 @@ void AudioStreamOGGVorbis::maybe_update_info() { vorbis_info_init(&info); vorbis_comment_init(&comment); - Ref<OGGPacketSequencePlayback> packet_sequence_playback = packet_sequence->instance_playback(); + Ref<OggPacketSequencePlayback> packet_sequence_playback = packet_sequence->instantiate_playback(); for (int i = 0; i < 3; i++) { ogg_packet *packet; @@ -373,57 +443,99 @@ void AudioStreamOGGVorbis::maybe_update_info() { vorbis_info_clear(&info); } -void AudioStreamOGGVorbis::set_packet_sequence(Ref<OGGPacketSequence> p_packet_sequence) { +void AudioStreamOggVorbis::set_packet_sequence(Ref<OggPacketSequence> p_packet_sequence) { packet_sequence = p_packet_sequence; if (packet_sequence.is_valid()) { maybe_update_info(); } } -Ref<OGGPacketSequence> AudioStreamOGGVorbis::get_packet_sequence() const { +Ref<OggPacketSequence> AudioStreamOggVorbis::get_packet_sequence() const { return packet_sequence; } -void AudioStreamOGGVorbis::set_loop(bool p_enable) { +void AudioStreamOggVorbis::set_loop(bool p_enable) { loop = p_enable; } -bool AudioStreamOGGVorbis::has_loop() const { +bool AudioStreamOggVorbis::has_loop() const { return loop; } -void AudioStreamOGGVorbis::set_loop_offset(float p_seconds) { +void AudioStreamOggVorbis::set_loop_offset(float p_seconds) { loop_offset = p_seconds; } -float AudioStreamOGGVorbis::get_loop_offset() const { +float AudioStreamOggVorbis::get_loop_offset() const { return loop_offset; } -float AudioStreamOGGVorbis::get_length() const { +float AudioStreamOggVorbis::get_length() const { ERR_FAIL_COND_V(packet_sequence.is_null(), 0); return packet_sequence->get_length(); } -bool AudioStreamOGGVorbis::is_monophonic() const { +void AudioStreamOggVorbis::set_bpm(double p_bpm) { + ERR_FAIL_COND(p_bpm < 0); + bpm = p_bpm; + emit_changed(); +} + +double AudioStreamOggVorbis::get_bpm() const { + return bpm; +} + +void AudioStreamOggVorbis::set_beat_count(int p_beat_count) { + ERR_FAIL_COND(p_beat_count < 0); + beat_count = p_beat_count; + emit_changed(); +} + +int AudioStreamOggVorbis::get_beat_count() const { + return beat_count; +} + +void AudioStreamOggVorbis::set_bar_beats(int p_bar_beats) { + ERR_FAIL_COND(p_bar_beats < 2); + bar_beats = p_bar_beats; + emit_changed(); +} + +int AudioStreamOggVorbis::get_bar_beats() const { + return bar_beats; +} + +bool AudioStreamOggVorbis::is_monophonic() const { return false; } -void AudioStreamOGGVorbis::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_packet_sequence", "packet_sequence"), &AudioStreamOGGVorbis::set_packet_sequence); - ClassDB::bind_method(D_METHOD("get_packet_sequence"), &AudioStreamOGGVorbis::get_packet_sequence); +void AudioStreamOggVorbis::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_packet_sequence", "packet_sequence"), &AudioStreamOggVorbis::set_packet_sequence); + ClassDB::bind_method(D_METHOD("get_packet_sequence"), &AudioStreamOggVorbis::get_packet_sequence); + + ClassDB::bind_method(D_METHOD("set_loop", "enable"), &AudioStreamOggVorbis::set_loop); + ClassDB::bind_method(D_METHOD("has_loop"), &AudioStreamOggVorbis::has_loop); + + ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamOggVorbis::set_loop_offset); + ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamOggVorbis::get_loop_offset); + + ClassDB::bind_method(D_METHOD("set_bpm", "bpm"), &AudioStreamOggVorbis::set_bpm); + ClassDB::bind_method(D_METHOD("get_bpm"), &AudioStreamOggVorbis::get_bpm); - ClassDB::bind_method(D_METHOD("set_loop", "enable"), &AudioStreamOGGVorbis::set_loop); - ClassDB::bind_method(D_METHOD("has_loop"), &AudioStreamOGGVorbis::has_loop); + ClassDB::bind_method(D_METHOD("set_beat_count", "count"), &AudioStreamOggVorbis::set_beat_count); + ClassDB::bind_method(D_METHOD("get_beat_count"), &AudioStreamOggVorbis::get_beat_count); - ClassDB::bind_method(D_METHOD("set_loop_offset", "seconds"), &AudioStreamOGGVorbis::set_loop_offset); - ClassDB::bind_method(D_METHOD("get_loop_offset"), &AudioStreamOGGVorbis::get_loop_offset); + ClassDB::bind_method(D_METHOD("set_bar_beats", "count"), &AudioStreamOggVorbis::set_bar_beats); + ClassDB::bind_method(D_METHOD("get_bar_beats"), &AudioStreamOggVorbis::get_bar_beats); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "packet_sequence", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_packet_sequence", "get_packet_sequence"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bpm", PROPERTY_HINT_RANGE, "0,400,0.01,or_greater"), "set_bpm", "get_bpm"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "beat_count", PROPERTY_HINT_RANGE, "0,512,1,or_greater"), "set_beat_count", "get_beat_count"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "bar_beats", PROPERTY_HINT_RANGE, "2,32,1,or_greater"), "set_bar_beats", "get_bar_beats"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "has_loop"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "loop_offset"), "set_loop_offset", "get_loop_offset"); } -AudioStreamOGGVorbis::AudioStreamOGGVorbis() {} +AudioStreamOggVorbis::AudioStreamOggVorbis() {} -AudioStreamOGGVorbis::~AudioStreamOGGVorbis() {} +AudioStreamOggVorbis::~AudioStreamOggVorbis() {} diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h index b09ef9ff5d..0350e1f761 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.h +++ b/modules/vorbis/audio_stream_ogg_vorbis.h @@ -28,23 +28,29 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIO_STREAM_LIBVORBIS_H -#define AUDIO_STREAM_LIBVORBIS_H +#ifndef AUDIO_STREAM_OGG_VORBIS_H +#define AUDIO_STREAM_OGG_VORBIS_H #include "core/variant/variant.h" #include "modules/ogg/ogg_packet_sequence.h" #include "servers/audio/audio_stream.h" #include "thirdparty/libvorbis/vorbis/codec.h" -class AudioStreamOGGVorbis; +class AudioStreamOggVorbis; -class AudioStreamPlaybackOGGVorbis : public AudioStreamPlaybackResampled { - GDCLASS(AudioStreamPlaybackOGGVorbis, AudioStreamPlaybackResampled); +class AudioStreamPlaybackOggVorbis : public AudioStreamPlaybackResampled { + GDCLASS(AudioStreamPlaybackOggVorbis, AudioStreamPlaybackResampled); uint32_t frames_mixed = 0; bool active = false; int loops = 0; + enum { + FADE_SIZE = 256 + }; + AudioFrame loop_fade[FADE_SIZE]; + int loop_fade_remaining = FADE_SIZE; + vorbis_info info; vorbis_comment comment; vorbis_dsp_state dsp_state; @@ -60,12 +66,13 @@ class AudioStreamPlaybackOGGVorbis : public AudioStreamPlaybackResampled { bool have_samples_left = false; bool have_packets_left = false; - friend class AudioStreamOGGVorbis; + friend class AudioStreamOggVorbis; - Ref<OGGPacketSequence> vorbis_data; - Ref<OGGPacketSequencePlayback> vorbis_data_playback; - Ref<AudioStreamOGGVorbis> vorbis_stream; + Ref<OggPacketSequence> vorbis_data; + Ref<OggPacketSequencePlayback> vorbis_data_playback; + Ref<AudioStreamOggVorbis> vorbis_stream; + int _mix_frames(AudioFrame *p_buffer, int p_frames); int _mix_frames_vorbis(AudioFrame *p_buffer, int p_frames); // Allocates vorbis data structures. Returns true upon success, false on failure. @@ -85,16 +92,18 @@ public: virtual float get_playback_position() const override; virtual void seek(float p_time) override; - AudioStreamPlaybackOGGVorbis() {} - ~AudioStreamPlaybackOGGVorbis(); + virtual void tag_used_streams() override; + + AudioStreamPlaybackOggVorbis() {} + ~AudioStreamPlaybackOggVorbis(); }; -class AudioStreamOGGVorbis : public AudioStream { - GDCLASS(AudioStreamOGGVorbis, AudioStream); +class AudioStreamOggVorbis : public AudioStream { + GDCLASS(AudioStreamOggVorbis, AudioStream); OBJ_SAVE_TYPE(AudioStream); // Saves derived classes with common type so they can be interchanged. RES_BASE_EXTENSION("oggvorbisstr"); - friend class AudioStreamPlaybackOGGVorbis; + friend class AudioStreamPlaybackOggVorbis; int channels = 1; float length = 0.0; @@ -105,30 +114,43 @@ class AudioStreamOGGVorbis : public AudioStream { // Also causes allocation and deallocation. void maybe_update_info(); - Ref<OGGPacketSequence> packet_sequence; + Ref<OggPacketSequence> packet_sequence; + + double bpm = 0; + int beat_count = 0; + int bar_beats = 4; protected: static void _bind_methods(); public: void set_loop(bool p_enable); - bool has_loop() const; + virtual bool has_loop() const override; void set_loop_offset(float p_seconds); float get_loop_offset() const; - virtual Ref<AudioStreamPlayback> instance_playback() override; + void set_bpm(double p_bpm); + virtual double get_bpm() const override; + + void set_beat_count(int p_beat_count); + virtual int get_beat_count() const override; + + void set_bar_beats(int p_bar_beats); + virtual int get_bar_beats() const override; + + virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; - void set_packet_sequence(Ref<OGGPacketSequence> p_packet_sequence); - Ref<OGGPacketSequence> get_packet_sequence() const; + void set_packet_sequence(Ref<OggPacketSequence> p_packet_sequence); + Ref<OggPacketSequence> get_packet_sequence() const; virtual float get_length() const override; //if supported, otherwise return 0 virtual bool is_monophonic() const override; - AudioStreamOGGVorbis(); - virtual ~AudioStreamOGGVorbis(); + AudioStreamOggVorbis(); + virtual ~AudioStreamOggVorbis(); }; -#endif // AUDIO_STREAM_LIBVORBIS_H +#endif // AUDIO_STREAM_OGG_VORBIS_H diff --git a/modules/vorbis/config.py b/modules/vorbis/config.py index 978eccb29f..7ce885a37a 100644 --- a/modules/vorbis/config.py +++ b/modules/vorbis/config.py @@ -8,8 +8,8 @@ def configure(env): def get_doc_classes(): return [ - "AudioStreamOGGVorbis", - "AudioStreamPlaybackOGGVorbis", + "AudioStreamOggVorbis", + "AudioStreamPlaybackOggVorbis", ] diff --git a/modules/vorbis/doc_classes/AudioStreamOGGVorbis.xml b/modules/vorbis/doc_classes/AudioStreamOggVorbis.xml index 2f210a6cb4..225ea4e6ae 100644 --- a/modules/vorbis/doc_classes/AudioStreamOGGVorbis.xml +++ b/modules/vorbis/doc_classes/AudioStreamOggVorbis.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamOGGVorbis" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="AudioStreamOggVorbis" inherits="AudioStream" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> </brief_description> <description> @@ -7,14 +7,20 @@ <tutorials> </tutorials> <members> + <member name="bar_beats" type="int" setter="set_bar_beats" getter="get_bar_beats" default="4"> + </member> + <member name="beat_count" type="int" setter="set_beat_count" getter="get_beat_count" default="0"> + </member> + <member name="bpm" type="float" setter="set_bpm" getter="get_bpm" default="0.0"> + </member> <member name="loop" type="bool" setter="set_loop" getter="has_loop" default="false"> If [code]true[/code], the stream will automatically loop when it reaches the end. </member> <member name="loop_offset" type="float" setter="set_loop_offset" getter="get_loop_offset" default="0.0"> Time in seconds at which the stream starts after being looped. </member> - <member name="packet_sequence" type="OGGPacketSequence" setter="set_packet_sequence" getter="get_packet_sequence"> - Contains the raw OGG data for this stream. + <member name="packet_sequence" type="OggPacketSequence" setter="set_packet_sequence" getter="get_packet_sequence"> + Contains the raw Ogg data for this stream. </member> </members> </class> diff --git a/modules/vorbis/doc_classes/AudioStreamPlaybackOGGVorbis.xml b/modules/vorbis/doc_classes/AudioStreamPlaybackOggVorbis.xml index 68aa46147f..0879c773ac 100644 --- a/modules/vorbis/doc_classes/AudioStreamPlaybackOGGVorbis.xml +++ b/modules/vorbis/doc_classes/AudioStreamPlaybackOggVorbis.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AudioStreamPlaybackOGGVorbis" inherits="AudioStreamPlaybackResampled" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="AudioStreamPlaybackOggVorbis" inherits="AudioStreamPlaybackResampled" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> </brief_description> <description> diff --git a/modules/vorbis/register_types.cpp b/modules/vorbis/register_types.cpp index 7f81f88cdb..84a71fe82d 100644 --- a/modules/vorbis/register_types.cpp +++ b/modules/vorbis/register_types.cpp @@ -40,13 +40,13 @@ void initialize_vorbis_module(ModuleInitializationLevel p_level) { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - Ref<ResourceImporterOGGVorbis> ogg_vorbis_importer; + Ref<ResourceImporterOggVorbis> ogg_vorbis_importer; ogg_vorbis_importer.instantiate(); ResourceFormatImporter::get_singleton()->add_importer(ogg_vorbis_importer); } #endif - GDREGISTER_CLASS(AudioStreamOGGVorbis); - GDREGISTER_CLASS(AudioStreamPlaybackOGGVorbis); + GDREGISTER_CLASS(AudioStreamOggVorbis); + GDREGISTER_CLASS(AudioStreamPlaybackOggVorbis); } void uninitialize_vorbis_module(ModuleInitializationLevel p_level) { diff --git a/modules/vorbis/resource_importer_ogg_vorbis.cpp b/modules/vorbis/resource_importer_ogg_vorbis.cpp index 7ee6446313..1ad1366d0b 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/vorbis/resource_importer_ogg_vorbis.cpp @@ -30,56 +30,59 @@ #include "resource_importer_ogg_vorbis.h" -#include "audio_stream_ogg_vorbis.h" #include "core/io/file_access.h" #include "core/io/resource_saver.h" #include "scene/resources/texture.h" #include "thirdparty/libogg/ogg/ogg.h" #include "thirdparty/libvorbis/vorbis/codec.h" -String ResourceImporterOGGVorbis::get_importer_name() const { +#ifdef TOOLS_ENABLED +#include "editor/import/audio_stream_import_settings.h" +#endif + +String ResourceImporterOggVorbis::get_importer_name() const { return "oggvorbisstr"; } -String ResourceImporterOGGVorbis::get_visible_name() const { +String ResourceImporterOggVorbis::get_visible_name() const { return "oggvorbisstr"; } -void ResourceImporterOGGVorbis::get_recognized_extensions(List<String> *p_extensions) const { +void ResourceImporterOggVorbis::get_recognized_extensions(List<String> *p_extensions) const { p_extensions->push_back("ogg"); } -String ResourceImporterOGGVorbis::get_save_extension() const { +String ResourceImporterOggVorbis::get_save_extension() const { return "oggvorbisstr"; } -String ResourceImporterOGGVorbis::get_resource_type() const { - return "AudioStreamOGGVorbis"; +String ResourceImporterOggVorbis::get_resource_type() const { + return "AudioStreamOggVorbis"; } -bool ResourceImporterOGGVorbis::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const { +bool ResourceImporterOggVorbis::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const { return true; } -int ResourceImporterOGGVorbis::get_preset_count() const { +int ResourceImporterOggVorbis::get_preset_count() const { return 0; } -String ResourceImporterOGGVorbis::get_preset_name(int p_idx) const { +String ResourceImporterOggVorbis::get_preset_name(int p_idx) const { return String(); } -void ResourceImporterOGGVorbis::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { +void ResourceImporterOggVorbis::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "loop_offset"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "bpm", PROPERTY_HINT_RANGE, "0,400,0.01,or_greater"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "beat_count", PROPERTY_HINT_RANGE, "0,512,or_greater"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "bar_beats", PROPERTY_HINT_RANGE, "2,32,or_greater"), 4)); } -Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { - bool loop = p_options["loop"]; - float loop_offset = p_options["loop_offset"]; - - Ref<FileAccess> f = FileAccess::open(p_source_file, FileAccess::READ); - ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, "Cannot open file '" + p_source_file + "'."); +Ref<AudioStreamOggVorbis> ResourceImporterOggVorbis::import_ogg_vorbis(const String &p_path) { + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V_MSG(f.is_null(), Ref<AudioStreamOggVorbis>(), "Cannot open file '" + p_path + "'."); uint64_t len = f->get_length(); @@ -89,10 +92,10 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin f->get_buffer(w, len); - Ref<AudioStreamOGGVorbis> ogg_vorbis_stream; + Ref<AudioStreamOggVorbis> ogg_vorbis_stream; ogg_vorbis_stream.instantiate(); - Ref<OGGPacketSequence> ogg_packet_sequence; + Ref<OggPacketSequence> ogg_packet_sequence; ogg_packet_sequence.instantiate(); ogg_stream_state stream_state; @@ -107,16 +110,16 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin size_t packet_count = 0; bool done = false; while (!done) { - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Error::ERR_INVALID_DATA, "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); while (ogg_sync_pageout(&sync_state, &page) != 1) { if (cursor >= len) { done = true; break; } - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Error::ERR_INVALID_DATA, "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); char *sync_buf = ogg_sync_buffer(&sync_state, OGG_SYNC_BUFFER_SIZE); - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Error::ERR_INVALID_DATA, "Ogg sync error " + itos(err)); - ERR_FAIL_COND_V(cursor > len, Error::ERR_INVALID_DATA); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V(cursor > len, Ref<AudioStreamOggVorbis>()); size_t copy_size = len - cursor; if (copy_size > OGG_SYNC_BUFFER_SIZE) { copy_size = OGG_SYNC_BUFFER_SIZE; @@ -124,22 +127,22 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin memcpy(sync_buf, &file_data[cursor], copy_size); ogg_sync_wrote(&sync_state, copy_size); cursor += copy_size; - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Error::ERR_INVALID_DATA, "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); } if (done) { break; } - ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Error::ERR_INVALID_DATA, "Ogg sync error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err)); // Have a page now. if (!initialized_stream) { if (ogg_stream_init(&stream_state, ogg_page_serialno(&page))) { - ERR_FAIL_V_MSG(Error::ERR_OUT_OF_MEMORY, "Failed allocating memory for OGG Vorbis stream."); + ERR_FAIL_V_MSG(Ref<AudioStreamOggVorbis>(), "Failed allocating memory for Ogg Vorbis stream."); } initialized_stream = true; } ogg_stream_pagein(&stream_state, &page); - ERR_FAIL_COND_V_MSG((err = ogg_stream_check(&stream_state)), Error::ERR_INVALID_DATA, "Ogg stream error " + itos(err)); + ERR_FAIL_COND_V_MSG((err = ogg_stream_check(&stream_state)), Ref<AudioStreamOggVorbis>(), "Ogg stream error " + itos(err)); int desync_iters = 0; Vector<Vector<uint8_t>> packet_data; @@ -150,7 +153,7 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin if (err == -1) { // According to the docs this is usually recoverable, but don't sit here spinning forever. desync_iters++; - ERR_FAIL_COND_V_MSG(desync_iters > 100, Error::ERR_INVALID_DATA, "Packet sync issue during ogg import"); + ERR_FAIL_COND_V_MSG(desync_iters > 100, Ref<AudioStreamOggVorbis>(), "Packet sync issue during Ogg import"); continue; } else if (err == 0) { // Not enough data to fully reconstruct a packet. Go on to the next page. @@ -183,15 +186,48 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin ogg_sync_clear(&sync_state); if (ogg_packet_sequence->get_packet_granule_positions().is_empty()) { - ERR_FAIL_V_MSG(Error::ERR_FILE_CORRUPT, "OGG Vorbis decoding failed. Check that your data is a valid OGG Vorbis audio stream."); + ERR_FAIL_V_MSG(Ref<AudioStreamOggVorbis>(), "Ogg Vorbis decoding failed. Check that your data is a valid Ogg Vorbis audio stream."); } ogg_vorbis_stream->set_packet_sequence(ogg_packet_sequence); + + return ogg_vorbis_stream; +} + +#ifdef TOOLS_ENABLED + +bool ResourceImporterOggVorbis::has_advanced_options() const { + return true; +} + +void ResourceImporterOggVorbis::show_advanced_options(const String &p_path) { + Ref<AudioStreamOggVorbis> ogg_stream = import_ogg_vorbis(p_path); + if (ogg_stream.is_valid()) { + AudioStreamImportSettings::get_singleton()->edit(p_path, "oggvorbisstr", ogg_stream); + } +} +#endif + +Error ResourceImporterOggVorbis::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { + bool loop = p_options["loop"]; + float loop_offset = p_options["loop_offset"]; + double bpm = p_options["bpm"]; + int beat_count = p_options["beat_count"]; + int bar_beats = p_options["bar_beats"]; + + Ref<AudioStreamOggVorbis> ogg_vorbis_stream = import_ogg_vorbis(p_source_file); + if (ogg_vorbis_stream.is_null()) { + return ERR_CANT_OPEN; + } + ogg_vorbis_stream->set_loop(loop); ogg_vorbis_stream->set_loop_offset(loop_offset); + ogg_vorbis_stream->set_bpm(bpm); + ogg_vorbis_stream->set_beat_count(beat_count); + ogg_vorbis_stream->set_bar_beats(bar_beats); return ResourceSaver::save(p_save_path + ".oggvorbisstr", ogg_vorbis_stream); } -ResourceImporterOGGVorbis::ResourceImporterOGGVorbis() { +ResourceImporterOggVorbis::ResourceImporterOggVorbis() { } diff --git a/modules/vorbis/resource_importer_ogg_vorbis.h b/modules/vorbis/resource_importer_ogg_vorbis.h index 3b4a68a1fd..a1a970e2cc 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.h +++ b/modules/vorbis/resource_importer_ogg_vorbis.h @@ -31,10 +31,11 @@ #ifndef RESOURCE_IMPORTER_OGG_VORBIS_H #define RESOURCE_IMPORTER_OGG_VORBIS_H +#include "audio_stream_ogg_vorbis.h" #include "core/io/resource_importer.h" -class ResourceImporterOGGVorbis : public ResourceImporter { - GDCLASS(ResourceImporterOGGVorbis, ResourceImporter); +class ResourceImporterOggVorbis : public ResourceImporter { + GDCLASS(ResourceImporterOggVorbis, ResourceImporter); enum { OGG_SYNC_BUFFER_SIZE = 8192, @@ -43,7 +44,13 @@ class ResourceImporterOGGVorbis : public ResourceImporter { private: // virtual int get_samples_in_packet(Vector<uint8_t> p_packet) = 0; + static Ref<AudioStreamOggVorbis> import_ogg_vorbis(const String &p_path); + public: +#ifdef TOOLS_ENABLED + virtual bool has_advanced_options() const override; + virtual void show_advanced_options(const String &p_path) override; +#endif virtual void get_recognized_extensions(List<String> *p_extensions) const override; virtual String get_save_extension() const override; virtual String get_resource_type() const override; @@ -56,7 +63,7 @@ public: virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; - ResourceImporterOGGVorbis(); + ResourceImporterOggVorbis(); }; #endif // RESOURCE_IMPORTER_OGG_VORBIS_H diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h index 448f683eb3..9a5dc6cd7c 100644 --- a/modules/webp/image_loader_webp.h +++ b/modules/webp/image_loader_webp.h @@ -40,4 +40,4 @@ public: ImageLoaderWebP(); }; -#endif +#endif // IMAGE_LOADER_WEBP_H diff --git a/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml b/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml index 3996a002ed..df92097135 100644 --- a/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml +++ b/modules/webrtc/doc_classes/WebRTCMultiplayerPeer.xml @@ -57,7 +57,7 @@ Initialize the multiplayer peer with the given [code]peer_id[/code] (must be between 1 and 2147483647). If [code]server_compatibilty[/code] is [code]false[/code] (default), the multiplayer peer will be immediately in state [constant MultiplayerPeer.CONNECTION_CONNECTED] and [signal MultiplayerPeer.connection_succeeded] will not be emitted. If [code]server_compatibilty[/code] is [code]true[/code] the peer will suppress all [signal MultiplayerPeer.peer_connected] signals until a peer with id [constant MultiplayerPeer.TARGET_PEER_SERVER] connects and then emit [signal MultiplayerPeer.connection_succeeded]. After that the signal [signal MultiplayerPeer.peer_connected] will be emitted for every already connected peer, and any new peer that might connect. If the server peer disconnects after that, signal [signal MultiplayerPeer.server_disconnected] will be emitted and state will become [constant MultiplayerPeer.CONNECTION_CONNECTED]. - You can optionally specify a [code]channels_config[/code] array of [enum TransferMode] which will be used to create extra channels (WebRTC only supports one transfer mode per channel). + You can optionally specify a [code]channels_config[/code] array of [enum MultiplayerPeer.TransferMode] which will be used to create extra channels (WebRTC only supports one transfer mode per channel). </description> </method> <method name="remove_peer"> diff --git a/modules/webrtc/webrtc_data_channel.h b/modules/webrtc/webrtc_data_channel.h index 75e29283ec..9d20ad3266 100644 --- a/modules/webrtc/webrtc_data_channel.h +++ b/modules/webrtc/webrtc_data_channel.h @@ -81,4 +81,5 @@ public: VARIANT_ENUM_CAST(WebRTCDataChannel::WriteMode); VARIANT_ENUM_CAST(WebRTCDataChannel::ChannelState); + #endif // WEBRTC_DATA_CHANNEL_H diff --git a/modules/webrtc/webrtc_multiplayer_peer.cpp b/modules/webrtc/webrtc_multiplayer_peer.cpp index 6f68b84ad3..e03b6b2473 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.cpp +++ b/modules/webrtc/webrtc_multiplayer_peer.cpp @@ -197,14 +197,14 @@ Error WebRTCMultiplayerPeer::initialize(int p_self_id, bool p_server_compat, Arr cfg["ordered"] = true; switch (mode) { - case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: + case TRANSFER_MODE_UNRELIABLE_ORDERED: cfg["maxPacketLifetime"] = 1; break; - case Multiplayer::TRANSFER_MODE_UNRELIABLE: + case TRANSFER_MODE_UNRELIABLE: cfg["maxPacketLifetime"] = 1; cfg["ordered"] = false; break; - case Multiplayer::TRANSFER_MODE_RELIABLE: + case TRANSFER_MODE_RELIABLE: break; default: ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, vformat("The 'channels_config' array must contain only enum values from 'MultiplayerPeer.Multiplayer::TransferMode'. Got: %d", mode)); @@ -339,13 +339,13 @@ Error WebRTCMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_si int ch = get_transfer_channel(); if (ch == 0) { switch (get_transfer_mode()) { - case Multiplayer::TRANSFER_MODE_RELIABLE: + case TRANSFER_MODE_RELIABLE: ch = CH_RELIABLE; break; - case Multiplayer::TRANSFER_MODE_UNRELIABLE_ORDERED: + case TRANSFER_MODE_UNRELIABLE_ORDERED: ch = CH_ORDERED; break; - case Multiplayer::TRANSFER_MODE_UNRELIABLE: + case TRANSFER_MODE_UNRELIABLE: ch = CH_UNRELIABLE; break; } diff --git a/modules/webrtc/webrtc_multiplayer_peer.h b/modules/webrtc/webrtc_multiplayer_peer.h index 97550a3e9d..ea7c60036b 100644 --- a/modules/webrtc/webrtc_multiplayer_peer.h +++ b/modules/webrtc/webrtc_multiplayer_peer.h @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef WEBRTC_MULTIPLAYER_H -#define WEBRTC_MULTIPLAYER_H +#ifndef WEBRTC_MULTIPLAYER_PEER_H +#define WEBRTC_MULTIPLAYER_PEER_H -#include "core/multiplayer/multiplayer_peer.h" +#include "scene/main/multiplayer_peer.h" #include "webrtc_peer_connection.h" class WebRTCMultiplayerPeer : public MultiplayerPeer { @@ -106,4 +106,4 @@ public: ConnectionStatus get_connection_status() const override; }; -#endif // WEBRTC_MULTIPLAYER_H +#endif // WEBRTC_MULTIPLAYER_PEER_H diff --git a/modules/webrtc/webrtc_peer_connection.h b/modules/webrtc/webrtc_peer_connection.h index 8c324d0942..122ea3d00f 100644 --- a/modules/webrtc/webrtc_peer_connection.h +++ b/modules/webrtc/webrtc_peer_connection.h @@ -74,4 +74,5 @@ public: }; VARIANT_ENUM_CAST(WebRTCPeerConnection::ConnectionState); + #endif // WEBRTC_PEER_CONNECTION_H diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h index ca327a56fa..b71fd78124 100644 --- a/modules/websocket/emws_client.h +++ b/modules/websocket/emws_client.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EMWSCLIENT_H -#define EMWSCLIENT_H +#ifndef EMWS_CLIENT_H +#define EMWS_CLIENT_H #ifdef JAVASCRIPT_ENABLED @@ -68,4 +68,4 @@ public: #endif // JAVASCRIPT_ENABLED -#endif // EMWSCLIENT_H +#endif // EMWS_CLIENT_H diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h index 6bb4552c37..f52f615c35 100644 --- a/modules/websocket/emws_peer.h +++ b/modules/websocket/emws_peer.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EMWSPEER_H -#define EMWSPEER_H +#ifndef EMWS_PEER_H +#define EMWS_PEER_H #ifdef JAVASCRIPT_ENABLED @@ -90,4 +90,4 @@ public: #endif // JAVASCRIPT_ENABLED -#endif // LSWPEER_H +#endif // EMWS_PEER_H diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h index ae31d9dbb0..14a9449605 100644 --- a/modules/websocket/emws_server.h +++ b/modules/websocket/emws_server.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef EMWSSERVER_H -#define EMWSSERVER_H +#ifndef EMWS_SERVER_H +#define EMWS_SERVER_H #ifdef JAVASCRIPT_ENABLED @@ -61,4 +61,4 @@ public: #endif -#endif // LWSSERVER_H +#endif // EMWS_SERVER_H diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index db529a669d..3259e78b3b 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -32,8 +32,8 @@ #define WEBSOCKET_MULTIPLAYER_PEER_H #include "core/error/error_list.h" -#include "core/multiplayer/multiplayer_peer.h" #include "core/templates/list.h" +#include "scene/main/multiplayer_peer.h" #include "websocket_peer.h" class WebSocketMultiplayerPeer : public MultiplayerPeer { diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h index 13fef2424f..22099f7258 100644 --- a/modules/websocket/websocket_peer.h +++ b/modules/websocket/websocket_peer.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef WEBSOCKETPEER_H -#define WEBSOCKETPEER_H +#ifndef WEBSOCKET_PEER_H +#define WEBSOCKET_PEER_H #include "core/error/error_list.h" #include "core/io/packet_peer.h" @@ -66,4 +66,5 @@ public: }; VARIANT_ENUM_CAST(WebSocketPeer::WriteMode); -#endif // WEBSOCKETPEER_H + +#endif // WEBSOCKET_PEER_H diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h index 7bd80851f5..ac04c4e57e 100644 --- a/modules/websocket/websocket_server.h +++ b/modules/websocket/websocket_server.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef WEBSOCKET_H -#define WEBSOCKET_H +#ifndef WEBSOCKET_SERVER_H +#define WEBSOCKET_SERVER_H #include "core/crypto/crypto.h" #include "core/object/ref_counted.h" @@ -87,4 +87,4 @@ public: ~WebSocketServer(); }; -#endif // WEBSOCKET_H +#endif // WEBSOCKET_SERVER_H diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h index 22d7ffa839..58b867fbe4 100644 --- a/modules/websocket/wsl_client.h +++ b/modules/websocket/wsl_client.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef WSLCLIENT_H -#define WSLCLIENT_H +#ifndef WSL_CLIENT_H +#define WSL_CLIENT_H #ifndef JAVASCRIPT_ENABLED @@ -88,4 +88,4 @@ public: #endif // JAVASCRIPT_ENABLED -#endif // WSLCLIENT_H +#endif // WSL_CLIENT_H diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index abeecdd537..aabd3fd43e 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef WSLPEER_H -#define WSLPEER_H +#ifndef WSL_PEER_H +#define WSL_PEER_H #ifndef JAVASCRIPT_ENABLED @@ -112,4 +112,4 @@ public: #endif // JAVASCRIPT_ENABLED -#endif // LSWPEER_H +#endif // WSL_PEER_H diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h index a920e9c665..ec7567c732 100644 --- a/modules/websocket/wsl_server.h +++ b/modules/websocket/wsl_server.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef WSLSERVER_H -#define WSLSERVER_H +#ifndef WSL_SERVER_H +#define WSL_SERVER_H #ifndef JAVASCRIPT_ENABLED @@ -95,4 +95,4 @@ public: #endif // JAVASCRIPT_ENABLED -#endif // WSLSERVER_H +#endif // WSL_SERVER_H diff --git a/modules/webxr/godot_webxr.h b/modules/webxr/godot_webxr.h index 34225df001..52104895d4 100644 --- a/modules/webxr/godot_webxr.h +++ b/modules/webxr/godot_webxr.h @@ -82,4 +82,4 @@ extern int *godot_webxr_get_bounds_geometry(); } #endif -#endif /* GODOT_WEBXR_H */ +#endif // GODOT_WEBXR_H diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp index 74e744402b..07e6760555 100644 --- a/modules/webxr/webxr_interface_js.cpp +++ b/modules/webxr/webxr_interface_js.cpp @@ -363,8 +363,8 @@ Transform3D WebXRInterfaceJS::get_transform_for_view(uint32_t p_view, const Tran return p_cam_transform * xr_server->get_reference_frame() * transform_for_eye; }; -CameraMatrix WebXRInterfaceJS::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { - CameraMatrix eye; +Projection WebXRInterfaceJS::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { + Projection eye; float *js_matrix = godot_webxr_get_projection_for_eye(p_view + 1); if (!initialized || js_matrix == nullptr) { diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h index 31858194f6..f1ffedba46 100644 --- a/modules/webxr/webxr_interface_js.h +++ b/modules/webxr/webxr_interface_js.h @@ -87,7 +87,7 @@ public: virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override; virtual void process() override; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 560f188b82..5bbe0ffab6 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -30,10 +30,10 @@ #include "export.h" -#include "export_plugin.h" - #include "core/os/os.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" +#include "export_plugin.h" void register_android_exporter() { EDITOR_DEF("export/android/android_sdk_path", ""); diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index 15ac8091be..8fd2f0680d 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -35,7 +35,7 @@ #include "core/io/zip_io.h" #include "core/os/os.h" -#include "editor/editor_export.h" +#include "editor/export/editor_export_platform.h" const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 7896392d16..232b4458c6 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_GRADLE_EXPORT_UTIL_H -#define GODOT_GRADLE_EXPORT_UTIL_H +#ifndef ANDROID_GRADLE_EXPORT_UTIL_H +#define ANDROID_GRADLE_EXPORT_UTIL_H #include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/io/zip_io.h" #include "core/os/os.h" -#include "editor/editor_export.h" +#include "editor/export/editor_export.h" const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="utf-8"?> <!--WARNING: THIS FILE WILL BE OVERWRITTEN AT BUILD TIME--> @@ -106,4 +106,4 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset); String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission); -#endif // GODOT_GRADLE_EXPORT_UTIL_H +#endif // ANDROID_GRADLE_EXPORT_UTIL_H diff --git a/platform/android/file_access_filesystem_jandroid.cpp b/platform/android/file_access_filesystem_jandroid.cpp index c1a48e025e..733d92f741 100644 --- a/platform/android/file_access_filesystem_jandroid.cpp +++ b/platform/android/file_access_filesystem_jandroid.cpp @@ -30,6 +30,7 @@ #include "file_access_filesystem_jandroid.h" #include "core/os/os.h" +#include "core/templates/local_vector.h" #include "thread_jandroid.h" #include <unistd.h> @@ -166,6 +167,51 @@ uint8_t FileAccessFilesystemJAndroid::get_8() const { return byte; } +String FileAccessFilesystemJAndroid::get_line() const { + ERR_FAIL_COND_V_MSG(!is_open(), String(), "File must be opened before use."); + + const size_t buffer_size_limit = 2048; + const uint64_t file_size = get_length(); + const uint64_t start_position = get_position(); + + String result; + LocalVector<uint8_t> line_buffer; + size_t current_buffer_size = 0; + uint64_t line_buffer_position = 0; + + while (true) { + size_t line_buffer_size = MIN(buffer_size_limit, file_size - get_position()); + if (line_buffer_size <= 0) { + break; + } + + current_buffer_size += line_buffer_size; + line_buffer.resize(current_buffer_size); + + uint64_t bytes_read = get_buffer(&line_buffer[line_buffer_position], current_buffer_size - line_buffer_position); + if (bytes_read <= 0) { + break; + } + + for (; bytes_read > 0; line_buffer_position++, bytes_read--) { + uint8_t elem = line_buffer[line_buffer_position]; + if (elem == '\n' || elem == '\0') { + // Found the end of the line + const_cast<FileAccessFilesystemJAndroid *>(this)->seek(start_position + line_buffer_position + 1); + if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position)) { + return String(); + } + return result; + } + } + } + + if (result.parse_utf8((const char *)line_buffer.ptr(), line_buffer_position)) { + return String(); + } + return result; +} + uint64_t FileAccessFilesystemJAndroid::get_buffer(uint8_t *p_dst, uint64_t p_length) const { if (_file_read) { ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use."); diff --git a/platform/android/file_access_filesystem_jandroid.h b/platform/android/file_access_filesystem_jandroid.h index 18d5df1628..7deb8de37b 100644 --- a/platform/android/file_access_filesystem_jandroid.h +++ b/platform/android/file_access_filesystem_jandroid.h @@ -74,6 +74,7 @@ public: virtual bool eof_reached() const override; ///< reading passed EOF virtual uint8_t get_8() const override; ///< get a byte + virtual String get_line() const override; ///< get a line virtual uint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const override; virtual Error get_error() const override; ///< get last error diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt index c7bd55b620..c9282dd247 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt @@ -54,11 +54,19 @@ internal enum class StorageScope { */ UNKNOWN; - companion object { + class Identifier(context: Context) { + + private val internalAppDir: String? = context.filesDir.canonicalPath + private val internalCacheDir: String? = context.cacheDir.canonicalPath + private val externalAppDir: String? = context.getExternalFilesDir(null)?.canonicalPath + private val sharedDir : String? = Environment.getExternalStorageDirectory().canonicalPath + private val downloadsSharedDir: String? = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).canonicalPath + private val documentsSharedDir: String? = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).canonicalPath + /** * Determines which [StorageScope] the given path falls under. */ - fun getStorageScope(context: Context, path: String?): StorageScope { + fun identifyStorageScope(path: String?): StorageScope { if (path == null) { return UNKNOWN } @@ -70,23 +78,19 @@ internal enum class StorageScope { val canonicalPathFile = pathFile.canonicalPath - val internalAppDir = context.filesDir.canonicalPath ?: return UNKNOWN - if (canonicalPathFile.startsWith(internalAppDir)) { + if (internalAppDir != null && canonicalPathFile.startsWith(internalAppDir)) { return APP } - val internalCacheDir = context.cacheDir.canonicalPath ?: return UNKNOWN - if (canonicalPathFile.startsWith(internalCacheDir)) { + if (internalCacheDir != null && canonicalPathFile.startsWith(internalCacheDir)) { return APP } - val externalAppDir = context.getExternalFilesDir(null)?.canonicalPath ?: return UNKNOWN - if (canonicalPathFile.startsWith(externalAppDir)) { + if (externalAppDir != null && canonicalPathFile.startsWith(externalAppDir)) { return APP } - val sharedDir = Environment.getExternalStorageDirectory().canonicalPath ?: return UNKNOWN - if (canonicalPathFile.startsWith(sharedDir)) { + if (sharedDir != null && canonicalPathFile.startsWith(sharedDir)) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { // Before R, apps had access to shared storage so long as they have the right // permissions (and flag on Q). @@ -95,13 +99,8 @@ internal enum class StorageScope { // Post R, access is limited based on the target destination // 'Downloads' and 'Documents' are still accessible - val downloadsSharedDir = - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).canonicalPath - ?: return SHARED - val documentsSharedDir = - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).canonicalPath - ?: return SHARED - if (canonicalPathFile.startsWith(downloadsSharedDir) || canonicalPathFile.startsWith(documentsSharedDir)) { + if ((downloadsSharedDir != null && canonicalPathFile.startsWith(downloadsSharedDir)) + || (documentsSharedDir != null && canonicalPathFile.startsWith(documentsSharedDir))) { return APP } diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt index c3acf42568..54fc56fa3e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt @@ -54,6 +54,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): private data class DirData(val dirFile: File, val files: Array<File>, var current: Int = 0) + private val storageScopeIdentifier = StorageScope.Identifier(context) private val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager private var lastDirId = STARTING_DIR_ID private val dirs = SparseArray<DirData>() @@ -62,7 +63,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): // Directory access is available for shared storage on Android 11+ // On Android 10, access is also available as long as the `requestLegacyExternalStorage` // tag is available. - return StorageScope.getStorageScope(context, path) != StorageScope.UNKNOWN + return storageScopeIdentifier.identifyStorageScope(path) != StorageScope.UNKNOWN } override fun hasDirId(dirId: Int) = dirs.indexOfKey(dirId) >= 0 @@ -102,7 +103,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): } } - override fun fileExists(path: String) = FileAccessHandler.fileExists(context, path) + override fun fileExists(path: String) = FileAccessHandler.fileExists(context, storageScopeIdentifier, path) override fun dirNext(dirId: Int): String { val dirData = dirs[dirId] @@ -199,7 +200,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): if (fromFile.isDirectory) { fromFile.renameTo(File(to)) } else { - FileAccessHandler.renameFile(context, from, to) + FileAccessHandler.renameFile(context, storageScopeIdentifier, from, to) } } catch (e: SecurityException) { false @@ -218,7 +219,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): if (deleteFile.isDirectory) { deleteFile.delete() } else { - FileAccessHandler.removeFile(context, filename) + FileAccessHandler.removeFile(context, storageScopeIdentifier, filename) } } else { true diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt index aef1bed8ce..463dabfb23 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt @@ -161,8 +161,9 @@ internal abstract class DataAccess(private val filePath: String) { fun read(buffer: ByteBuffer): Int { return try { val readBytes = fileChannel.read(buffer) + endOfFile = readBytes == -1 + || (fileChannel.position() >= fileChannel.size() && fileChannel.size() > 0) if (readBytes == -1) { - endOfFile = true 0 } else { readBytes diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt index a4e0a82d6e..04b6772c45 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt @@ -49,8 +49,8 @@ class FileAccessHandler(val context: Context) { private const val INVALID_FILE_ID = 0 private const val STARTING_FILE_ID = 1 - fun fileExists(context: Context, path: String?): Boolean { - val storageScope = StorageScope.getStorageScope(context, path) + internal fun fileExists(context: Context, storageScopeIdentifier: StorageScope.Identifier, path: String?): Boolean { + val storageScope = storageScopeIdentifier.identifyStorageScope(path) if (storageScope == StorageScope.UNKNOWN) { return false } @@ -62,8 +62,8 @@ class FileAccessHandler(val context: Context) { } } - fun removeFile(context: Context, path: String?): Boolean { - val storageScope = StorageScope.getStorageScope(context, path) + internal fun removeFile(context: Context, storageScopeIdentifier: StorageScope.Identifier, path: String?): Boolean { + val storageScope = storageScopeIdentifier.identifyStorageScope(path) if (storageScope == StorageScope.UNKNOWN) { return false } @@ -75,8 +75,8 @@ class FileAccessHandler(val context: Context) { } } - fun renameFile(context: Context, from: String?, to: String?): Boolean { - val storageScope = StorageScope.getStorageScope(context, from) + internal fun renameFile(context: Context, storageScopeIdentifier: StorageScope.Identifier, from: String?, to: String?): Boolean { + val storageScope = storageScopeIdentifier.identifyStorageScope(from) if (storageScope == StorageScope.UNKNOWN) { return false } @@ -89,13 +89,14 @@ class FileAccessHandler(val context: Context) { } } + private val storageScopeIdentifier = StorageScope.Identifier(context) private val files = SparseArray<DataAccess>() private var lastFileId = STARTING_FILE_ID private fun hasFileId(fileId: Int) = files.indexOfKey(fileId) >= 0 fun fileOpen(path: String?, modeFlags: Int): Int { - val storageScope = StorageScope.getStorageScope(context, path) + val storageScope = storageScopeIdentifier.identifyStorageScope(path) if (storageScope == StorageScope.UNKNOWN) { return INVALID_FILE_ID } @@ -162,10 +163,10 @@ class FileAccessHandler(val context: Context) { files[fileId].flush() } - fun fileExists(path: String?) = Companion.fileExists(context, path) + fun fileExists(path: String?) = Companion.fileExists(context, storageScopeIdentifier, path) fun fileLastModified(filepath: String?): Long { - val storageScope = StorageScope.getStorageScope(context, filepath) + val storageScope = storageScopeIdentifier.identifyStorageScope(filepath) if (storageScope == StorageScope.UNKNOWN) { return 0L } diff --git a/platform/android/java_godot_view_wrapper.h b/platform/android/java_godot_view_wrapper.h index b1f258bbb5..c52f459d64 100644 --- a/platform/android/java_godot_view_wrapper.h +++ b/platform/android/java_godot_view_wrapper.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_JAVA_GODOT_VIEW_WRAPPER_H -#define GODOT_JAVA_GODOT_VIEW_WRAPPER_H +#ifndef JAVA_GODOT_VIEW_WRAPPER_H +#define JAVA_GODOT_VIEW_WRAPPER_H #include <android/log.h> #include <jni.h> @@ -57,4 +57,4 @@ public: ~GodotJavaViewWrapper(); }; -#endif // GODOT_JAVA_GODOT_VIEW_WRAPPER_H +#endif // JAVA_GODOT_VIEW_WRAPPER_H diff --git a/platform/iphone/SCsub b/platform/ios/SCsub index 5e10bf5646..bf12ab6dd7 100644 --- a/platform/iphone/SCsub +++ b/platform/ios/SCsub @@ -2,16 +2,16 @@ Import("env") -iphone_lib = [ - "godot_iphone.mm", - "os_iphone.mm", +ios_lib = [ + "godot_ios.mm", + "os_ios.mm", "main.m", "app_delegate.mm", "view_controller.mm", "ios.mm", - "vulkan_context_iphone.mm", - "display_server_iphone.mm", - "joypad_iphone.mm", + "vulkan_context_ios.mm", + "display_server_ios.mm", + "joypad_ios.mm", "godot_view.mm", "tts_ios.mm", "display_layer.mm", @@ -23,7 +23,7 @@ iphone_lib = [ ] env_ios = env.Clone() -ios_lib = env_ios.add_library("iphone", iphone_lib) +ios_lib = env_ios.add_library("ios", ios_lib) # (iOS) Enable module support env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) @@ -32,9 +32,9 @@ env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) def combine_libs(target=None, source=None, env=None): lib_path = target[0].srcnode().abspath if "osxcross" in env: - libtool = "$IPHONEPATH/usr/bin/${ios_triple}libtool" + libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}libtool" else: - libtool = "$IPHONEPATH/usr/bin/libtool" + libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/libtool" env.Execute( libtool + ' -static -o "' + lib_path + '" ' + " ".join([('"' + lib.srcnode().abspath + '"') for lib in source]) ) diff --git a/platform/iphone/api/api.cpp b/platform/ios/api/api.cpp index f2e6fd7a7a..00c76a9256 100644 --- a/platform/iphone/api/api.cpp +++ b/platform/ios/api/api.cpp @@ -30,19 +30,19 @@ #include "api.h" -#if defined(IPHONE_ENABLED) +#if defined(IOS_ENABLED) -void register_iphone_api() { +void register_ios_api() { godot_ios_plugins_initialize(); } -void unregister_iphone_api() { +void unregister_ios_api() { godot_ios_plugins_deinitialize(); } #else -void register_iphone_api() {} -void unregister_iphone_api() {} +void register_ios_api() {} +void unregister_ios_api() {} #endif diff --git a/platform/iphone/api/api.h b/platform/ios/api/api.h index ece91a9f1a..c7fd4ce77b 100644 --- a/platform/iphone/api/api.h +++ b/platform/ios/api/api.h @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef IPHONE_API_H -#define IPHONE_API_H +#ifndef IOS_API_H +#define IOS_API_H -#if defined(IPHONE_ENABLED) +#if defined(IOS_ENABLED) extern void godot_ios_plugins_initialize(); extern void godot_ios_plugins_deinitialize(); #endif -void register_iphone_api(); -void unregister_iphone_api(); +void register_ios_api(); +void unregister_ios_api(); -#endif // IPHONE_API_H +#endif // IOS_API_H diff --git a/platform/iphone/app_delegate.h b/platform/ios/app_delegate.h index 0ec1dc071b..0ec1dc071b 100644 --- a/platform/iphone/app_delegate.h +++ b/platform/ios/app_delegate.h diff --git a/platform/iphone/app_delegate.mm b/platform/ios/app_delegate.mm index c5c9b5a5f9..fb183d52d4 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/ios/app_delegate.mm @@ -34,7 +34,7 @@ #include "drivers/coreaudio/audio_driver_coreaudio.h" #import "godot_view.h" #include "main/main.h" -#include "os_iphone.h" +#include "os_ios.h" #import "view_controller.h" #import <AVFoundation/AVFoundation.h> @@ -45,8 +45,8 @@ extern int gargc; extern char **gargv; -extern int iphone_main(int, char **, String, String); -extern void iphone_finish(); +extern int ios_main(int, char **, String, String); +extern void ios_finish(); @implementation AppDelegate @@ -71,7 +71,7 @@ static ViewController *mainViewController = nil; paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *cacheDirectory = [paths objectAtIndex:0]; - int err = iphone_main(gargc, gargv, String::utf8([documentsDirectory UTF8String]), String::utf8([cacheDirectory UTF8String])); + int err = ios_main(gargc, gargv, String::utf8([documentsDirectory UTF8String]), String::utf8([cacheDirectory UTF8String])); if (err != 0) { // bail, things did not go very well for us, should probably output a message on screen with our error code... @@ -106,10 +106,10 @@ static ViewController *mainViewController = nil; if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) { if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) { NSLog(@"Audio interruption began"); - OSIPhone::get_singleton()->on_focus_out(); + OS_IOS::get_singleton()->on_focus_out(); } else if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeEnded]]) { NSLog(@"Audio interruption ended"); - OSIPhone::get_singleton()->on_focus_in(); + OS_IOS::get_singleton()->on_focus_in(); } } } @@ -121,7 +121,7 @@ static ViewController *mainViewController = nil; } - (void)applicationWillTerminate:(UIApplication *)application { - iphone_finish(); + ios_finish(); } // When application goes to background (e.g. user switches to another app or presses Home), @@ -135,11 +135,11 @@ static ViewController *mainViewController = nil; // notification panel by swiping from the upper part of the screen. - (void)applicationWillResignActive:(UIApplication *)application { - OSIPhone::get_singleton()->on_focus_out(); + OS_IOS::get_singleton()->on_focus_out(); } - (void)applicationDidBecomeActive:(UIApplication *)application { - OSIPhone::get_singleton()->on_focus_in(); + OS_IOS::get_singleton()->on_focus_in(); } - (void)dealloc { diff --git a/platform/iphone/detect.py b/platform/ios/detect.py index 862f1fe50b..67c90b10a0 100644 --- a/platform/iphone/detect.py +++ b/platform/ios/detect.py @@ -23,11 +23,11 @@ def get_opts(): return [ ( - "IPHONEPATH", - "Path to iPhone toolchain", + "IOS_TOOLCHAIN_PATH", + "Path to iOS toolchain", "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain", ), - ("IPHONESDK", "Path to the iPhone SDK", ""), + ("IOS_SDK_PATH", "Path to the iOS SDK", ""), BoolVariable("ios_simulator", "Build for iOS Simulator", False), BoolVariable("ios_exceptions", "Enable exceptions", False), ("ios_triple", "Triple for ios toolchain", ""), @@ -75,10 +75,10 @@ def configure(env): if "OSXCROSS_IOS" in os.environ: env["osxcross"] = True - env["ENV"]["PATH"] = env["IPHONEPATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"] + env["ENV"]["PATH"] = env["IOS_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"] - compiler_path = "$IPHONEPATH/usr/bin/${ios_triple}" - s_compiler_path = "$IPHONEPATH/Developer/usr/bin/" + compiler_path = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}" + s_compiler_path = "$IOS_TOOLCHAIN_PATH/Developer/usr/bin/" ccache_path = os.environ.get("CCACHE") if ccache_path is None: @@ -97,12 +97,12 @@ def configure(env): ## Compile flags if env["ios_simulator"]: - detect_darwin_sdk_path("iphonesimulator", env) + detect_darwin_sdk_path("iossimulator", env) env.Append(ASFLAGS=["-mios-simulator-version-min=13.0"]) env.Append(CCFLAGS=["-mios-simulator-version-min=13.0"]) env.extra_suffix = ".simulator" + env.extra_suffix else: - detect_darwin_sdk_path("iphone", env) + detect_darwin_sdk_path("ios", env) env.Append(ASFLAGS=["-miphoneos-version-min=11.0"]) env.Append(CCFLAGS=["-miphoneos-version-min=11.0"]) @@ -112,7 +112,7 @@ def configure(env): CCFLAGS=( "-fobjc-arc -arch x86_64" " -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks" - " -fasm-blocks -isysroot $IPHONESDK" + " -fasm-blocks -isysroot $IOS_SDK_PATH" ).split() ) env.Append(ASFLAGS=["-arch", "x86_64"]) @@ -122,7 +122,7 @@ def configure(env): "-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing" " -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits" " -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies" - " -isysroot $IPHONESDK".split() + " -isysroot $IOS_SDK_PATH".split() ) ) env.Append(ASFLAGS=["-arch", "arm64"]) @@ -135,18 +135,18 @@ def configure(env): else: env.Append(CCFLAGS=["-fno-exceptions"]) - # Temp fix for ABS/MAX/MIN macros in iPhone SDK blocking compilation + # Temp fix for ABS/MAX/MIN macros in iOS SDK blocking compilation env.Append(CCFLAGS=["-Wno-ambiguous-macro"]) env.Prepend( CPPPATH=[ - "$IPHONESDK/usr/include", - "$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers", + "$IOS_SDK_PATH/usr/include", + "$IOS_SDK_PATH/System/Library/Frameworks/AudioUnit.framework/Headers", ] ) - env.Prepend(CPPPATH=["#platform/iphone"]) - env.Append(CPPDEFINES=["IPHONE_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"]) + env.Prepend(CPPPATH=["#platform/ios"]) + env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"]) if env["vulkan"]: env.Append(CPPDEFINES=["VULKAN_ENABLED"]) diff --git a/platform/iphone/device_metrics.h b/platform/ios/device_metrics.h index b9fb9b2fd9..b9fb9b2fd9 100644 --- a/platform/iphone/device_metrics.h +++ b/platform/ios/device_metrics.h diff --git a/platform/iphone/device_metrics.m b/platform/ios/device_metrics.m index ec4dd8130d..ec4dd8130d 100644 --- a/platform/iphone/device_metrics.m +++ b/platform/ios/device_metrics.m diff --git a/platform/iphone/display_layer.h b/platform/ios/display_layer.h index a17c75dba1..a17c75dba1 100644 --- a/platform/iphone/display_layer.h +++ b/platform/ios/display_layer.h diff --git a/platform/iphone/display_layer.mm b/platform/ios/display_layer.mm index 92e81448ac..7c83494768 100644 --- a/platform/iphone/display_layer.mm +++ b/platform/ios/display_layer.mm @@ -32,9 +32,9 @@ #include "core/config/project_settings.h" #include "core/os/keyboard.h" -#include "display_server_iphone.h" +#include "display_server_ios.h" #include "main/main.h" -#include "os_iphone.h" +#include "os_ios.h" #include "servers/audio_server.h" #import <AudioToolbox/AudioServices.h> diff --git a/platform/iphone/display_server_iphone.h b/platform/ios/display_server_ios.h index 7af222e3f8..5dd4d177ea 100644 --- a/platform/iphone/display_server_iphone.h +++ b/platform/ios/display_server_ios.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* display_server_iphone.h */ +/* display_server_ios.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef display_server_iphone_h -#define display_server_iphone_h +#ifndef DISPLAY_SERVER_IOS_H +#define DISPLAY_SERVER_IOS_H #include "core/input/input.h" #include "servers/display_server.h" @@ -38,7 +38,7 @@ #include "drivers/vulkan/rendering_device_vulkan.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" -#include "vulkan_context_iphone.h" +#include "vulkan_context_ios.h" #import <QuartzCore/CAMetalLayer.h> #ifdef USE_VOLK @@ -48,13 +48,13 @@ #endif #endif -class DisplayServerIPhone : public DisplayServer { - GDCLASS(DisplayServerIPhone, DisplayServer) +class DisplayServerIOS : public DisplayServer { + GDCLASS(DisplayServerIOS, DisplayServer) _THREAD_SAFE_CLASS_ #if defined(VULKAN_ENABLED) - VulkanContextIPhone *context_vulkan = nullptr; + VulkanContextIOS *context_vulkan = nullptr; RenderingDeviceVulkan *rendering_device_vulkan = nullptr; #endif @@ -73,15 +73,15 @@ class DisplayServerIPhone : public DisplayServer { void perform_event(const Ref<InputEvent> &p_event); - DisplayServerIPhone(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); - ~DisplayServerIPhone(); + DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); + ~DisplayServerIOS(); public: String rendering_driver; - static DisplayServerIPhone *get_singleton(); + static DisplayServerIOS *get_singleton(); - static void register_iphone_driver(); + static void register_ios_driver(); static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); static Vector<String> get_rendering_drivers_func(); @@ -214,4 +214,4 @@ public: void resize_window(CGSize size); }; -#endif /* display_server_iphone_h */ +#endif // DISPLAY_SERVER_IOS_H diff --git a/platform/iphone/display_server_iphone.mm b/platform/ios/display_server_ios.mm index 28ffc9595e..73d4a2a427 100644 --- a/platform/iphone/display_server_iphone.mm +++ b/platform/ios/display_server_ios.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* display_server_iphone.mm */ +/* display_server_ios.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "display_server_iphone.h" +#include "display_server_ios.h" #import "app_delegate.h" #include "core/config/project_settings.h" @@ -37,20 +37,20 @@ #import "godot_view.h" #include "ios.h" #import "keyboard_input_view.h" -#include "os_iphone.h" +#include "os_ios.h" #include "tts_ios.h" #import "view_controller.h" #import <Foundation/Foundation.h> #import <sys/utsname.h> -static const float kDisplayServerIPhoneAcceleration = 1; +static const float kDisplayServerIOSAcceleration = 1.f; -DisplayServerIPhone *DisplayServerIPhone::get_singleton() { - return (DisplayServerIPhone *)DisplayServer::get_singleton(); +DisplayServerIOS *DisplayServerIOS::get_singleton() { + return (DisplayServerIOS *)DisplayServer::get_singleton(); } -DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { +DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { rendering_driver = p_rendering_driver; // Init TTS @@ -101,7 +101,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo rendering_device_vulkan = nullptr; if (rendering_driver == "vulkan") { - context_vulkan = memnew(VulkanContextIPhone); + context_vulkan = memnew(VulkanContextIOS); if (context_vulkan->initialize() != OK) { memdelete(context_vulkan); context_vulkan = nullptr; @@ -136,7 +136,7 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo r_error = OK; } -DisplayServerIPhone::~DisplayServerIPhone() { +DisplayServerIOS::~DisplayServerIOS() { #if defined(VULKAN_ENABLED) if (rendering_device_vulkan) { rendering_device_vulkan->finalize(); @@ -152,11 +152,11 @@ DisplayServerIPhone::~DisplayServerIPhone() { #endif } -DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); +DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { + return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); } -Vector<String> DisplayServerIPhone::get_rendering_drivers_func() { +Vector<String> DisplayServerIOS::get_rendering_drivers_func() { Vector<String> drivers; #if defined(VULKAN_ENABLED) @@ -169,52 +169,52 @@ Vector<String> DisplayServerIPhone::get_rendering_drivers_func() { return drivers; } -void DisplayServerIPhone::register_iphone_driver() { - register_create_function("iphone", create_func, get_rendering_drivers_func); +void DisplayServerIOS::register_ios_driver() { + register_create_function("iOS", create_func, get_rendering_drivers_func); } // MARK: Events -void DisplayServerIPhone::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerIOS::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) { window_resize_callback = p_callable; } -void DisplayServerIPhone::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerIOS::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) { window_event_callback = p_callable; } -void DisplayServerIPhone::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerIOS::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) { input_event_callback = p_callable; } -void DisplayServerIPhone::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerIOS::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) { input_text_callback = p_callable; } -void DisplayServerIPhone::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerIOS::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) { // Probably not supported for iOS } -void DisplayServerIPhone::process_events() { +void DisplayServerIOS::process_events() { Input::get_singleton()->flush_buffered_events(); } -void DisplayServerIPhone::_dispatch_input_events(const Ref<InputEvent> &p_event) { - DisplayServerIPhone::get_singleton()->send_input_event(p_event); +void DisplayServerIOS::_dispatch_input_events(const Ref<InputEvent> &p_event) { + DisplayServerIOS::get_singleton()->send_input_event(p_event); } -void DisplayServerIPhone::send_input_event(const Ref<InputEvent> &p_event) const { +void DisplayServerIOS::send_input_event(const Ref<InputEvent> &p_event) const { _window_callback(input_event_callback, p_event); } -void DisplayServerIPhone::send_input_text(const String &p_text) const { +void DisplayServerIOS::send_input_text(const String &p_text) const { _window_callback(input_text_callback, p_text); } -void DisplayServerIPhone::send_window_event(DisplayServer::WindowEvent p_event) const { +void DisplayServerIOS::send_window_event(DisplayServer::WindowEvent p_event) const { _window_callback(window_event_callback, int(p_event)); } -void DisplayServerIPhone::_window_callback(const Callable &p_callable, const Variant &p_arg) const { +void DisplayServerIOS::_window_callback(const Callable &p_callable, const Variant &p_arg) const { if (!p_callable.is_null()) { const Variant *argp = &p_arg; Variant ret; @@ -227,7 +227,7 @@ void DisplayServerIPhone::_window_callback(const Callable &p_callable, const Var // MARK: Touches -void DisplayServerIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) { +void DisplayServerIOS::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) { if (!GLOBAL_DEF("debug/disable_touch", false)) { Ref<InputEventScreenTouch> ev; ev.instantiate(); @@ -239,7 +239,7 @@ void DisplayServerIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_presse } } -void DisplayServerIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) { +void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) { if (!GLOBAL_DEF("debug/disable_touch", false)) { Ref<InputEventScreenDrag> ev; ev.instantiate(); @@ -250,17 +250,17 @@ void DisplayServerIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int } } -void DisplayServerIPhone::perform_event(const Ref<InputEvent> &p_event) { +void DisplayServerIOS::perform_event(const Ref<InputEvent> &p_event) { Input::get_singleton()->parse_input_event(p_event); } -void DisplayServerIPhone::touches_cancelled(int p_idx) { +void DisplayServerIOS::touches_cancelled(int p_idx) { touch_press(p_idx, -1, -1, false, false); } // MARK: Keyboard -void DisplayServerIPhone::key(Key p_key, bool p_pressed) { +void DisplayServerIOS::key(Key p_key, bool p_pressed) { Ref<InputEventKey> ev; ev.instantiate(); ev->set_echo(false); @@ -273,31 +273,31 @@ void DisplayServerIPhone::key(Key p_key, bool p_pressed) { // MARK: Motion -void DisplayServerIPhone::update_gravity(float p_x, float p_y, float p_z) { +void DisplayServerIOS::update_gravity(float p_x, float p_y, float p_z) { Input::get_singleton()->set_gravity(Vector3(p_x, p_y, p_z)); } -void DisplayServerIPhone::update_accelerometer(float p_x, float p_y, float p_z) { +void DisplayServerIOS::update_accelerometer(float p_x, float p_y, float p_z) { // Found out the Z should not be negated! Pass as is! Vector3 v_accelerometer = Vector3( - p_x / kDisplayServerIPhoneAcceleration, - p_y / kDisplayServerIPhoneAcceleration, - p_z / kDisplayServerIPhoneAcceleration); + p_x / kDisplayServerIOSAcceleration, + p_y / kDisplayServerIOSAcceleration, + p_z / kDisplayServerIOSAcceleration); Input::get_singleton()->set_accelerometer(v_accelerometer); } -void DisplayServerIPhone::update_magnetometer(float p_x, float p_y, float p_z) { +void DisplayServerIOS::update_magnetometer(float p_x, float p_y, float p_z) { Input::get_singleton()->set_magnetometer(Vector3(p_x, p_y, p_z)); } -void DisplayServerIPhone::update_gyroscope(float p_x, float p_y, float p_z) { +void DisplayServerIOS::update_gyroscope(float p_x, float p_y, float p_z) { Input::get_singleton()->set_gyroscope(Vector3(p_x, p_y, p_z)); } // MARK: - -bool DisplayServerIPhone::has_feature(Feature p_feature) const { +bool DisplayServerIOS::has_feature(Feature p_feature) const { switch (p_feature) { // case FEATURE_CURSOR_SHAPE: // case FEATURE_CUSTOM_CURSOR_SHAPE: @@ -322,46 +322,46 @@ bool DisplayServerIPhone::has_feature(Feature p_feature) const { } } -String DisplayServerIPhone::get_name() const { - return "iPhone"; +String DisplayServerIOS::get_name() const { + return "iOS"; } -bool DisplayServerIPhone::tts_is_speaking() const { +bool DisplayServerIOS::tts_is_speaking() const { ERR_FAIL_COND_V(!tts, false); return [tts isSpeaking]; } -bool DisplayServerIPhone::tts_is_paused() const { +bool DisplayServerIOS::tts_is_paused() const { ERR_FAIL_COND_V(!tts, false); return [tts isPaused]; } -Array DisplayServerIPhone::tts_get_voices() const { +Array DisplayServerIOS::tts_get_voices() const { ERR_FAIL_COND_V(!tts, Array()); return [tts getVoices]; } -void DisplayServerIPhone::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { +void DisplayServerIOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { ERR_FAIL_COND(!tts); [tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt]; } -void DisplayServerIPhone::tts_pause() { +void DisplayServerIOS::tts_pause() { ERR_FAIL_COND(!tts); [tts pauseSpeaking]; } -void DisplayServerIPhone::tts_resume() { +void DisplayServerIOS::tts_resume() { ERR_FAIL_COND(!tts); [tts resumeSpeaking]; } -void DisplayServerIPhone::tts_stop() { +void DisplayServerIOS::tts_stop() { ERR_FAIL_COND(!tts); [tts stopSpeaking]; } -Rect2i DisplayServerIPhone::get_display_safe_area() const { +Rect2i DisplayServerIOS::get_display_safe_area() const { if (@available(iOS 11, *)) { UIEdgeInsets insets = UIEdgeInsetsZero; UIView *view = AppDelegate.viewController.godotView; @@ -377,15 +377,15 @@ Rect2i DisplayServerIPhone::get_display_safe_area() const { } } -int DisplayServerIPhone::get_screen_count() const { +int DisplayServerIOS::get_screen_count() const { return 1; } -Point2i DisplayServerIPhone::screen_get_position(int p_screen) const { +Point2i DisplayServerIOS::screen_get_position(int p_screen) const { return Size2i(); } -Size2i DisplayServerIPhone::screen_get_size(int p_screen) const { +Size2i DisplayServerIOS::screen_get_size(int p_screen) const { CALayer *layer = AppDelegate.viewController.godotView.renderingLayer; if (!layer) { @@ -395,11 +395,11 @@ Size2i DisplayServerIPhone::screen_get_size(int p_screen) const { return Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_scale(p_screen); } -Rect2i DisplayServerIPhone::screen_get_usable_rect(int p_screen) const { +Rect2i DisplayServerIOS::screen_get_usable_rect(int p_screen) const { return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen)); } -int DisplayServerIPhone::screen_get_dpi(int p_screen) const { +int DisplayServerIOS::screen_get_dpi(int p_screen) const { struct utsname systemInfo; uname(&systemInfo); @@ -436,25 +436,25 @@ int DisplayServerIPhone::screen_get_dpi(int p_screen) const { } } -float DisplayServerIPhone::screen_get_refresh_rate(int p_screen) const { +float DisplayServerIOS::screen_get_refresh_rate(int p_screen) const { return [UIScreen mainScreen].maximumFramesPerSecond; } -float DisplayServerIPhone::screen_get_scale(int p_screen) const { +float DisplayServerIOS::screen_get_scale(int p_screen) const { return [UIScreen mainScreen].nativeScale; } -Vector<DisplayServer::WindowID> DisplayServerIPhone::get_window_list() const { +Vector<DisplayServer::WindowID> DisplayServerIOS::get_window_list() const { Vector<DisplayServer::WindowID> list; list.push_back(MAIN_WINDOW_ID); return list; } -DisplayServer::WindowID DisplayServerIPhone::get_window_at_screen_position(const Point2i &p_position) const { +DisplayServer::WindowID DisplayServerIOS::get_window_at_screen_position(const Point2i &p_position) const { return MAIN_WINDOW_ID; } -int64_t DisplayServerIPhone::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const { +int64_t DisplayServerIOS::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const { ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, 0); switch (p_handle_type) { case DISPLAY_HANDLE: { @@ -472,120 +472,120 @@ int64_t DisplayServerIPhone::window_get_native_handle(HandleType p_handle_type, } } -void DisplayServerIPhone::window_attach_instance_id(ObjectID p_instance, WindowID p_window) { +void DisplayServerIOS::window_attach_instance_id(ObjectID p_instance, WindowID p_window) { window_attached_instance_id = p_instance; } -ObjectID DisplayServerIPhone::window_get_attached_instance_id(WindowID p_window) const { +ObjectID DisplayServerIOS::window_get_attached_instance_id(WindowID p_window) const { return window_attached_instance_id; } -void DisplayServerIPhone::window_set_title(const String &p_title, WindowID p_window) { +void DisplayServerIOS::window_set_title(const String &p_title, WindowID p_window) { // Probably not supported for iOS } -int DisplayServerIPhone::window_get_current_screen(WindowID p_window) const { +int DisplayServerIOS::window_get_current_screen(WindowID p_window) const { return SCREEN_OF_MAIN_WINDOW; } -void DisplayServerIPhone::window_set_current_screen(int p_screen, WindowID p_window) { +void DisplayServerIOS::window_set_current_screen(int p_screen, WindowID p_window) { // Probably not supported for iOS } -Point2i DisplayServerIPhone::window_get_position(WindowID p_window) const { +Point2i DisplayServerIOS::window_get_position(WindowID p_window) const { return Point2i(); } -void DisplayServerIPhone::window_set_position(const Point2i &p_position, WindowID p_window) { +void DisplayServerIOS::window_set_position(const Point2i &p_position, WindowID p_window) { // Probably not supported for single window iOS app } -void DisplayServerIPhone::window_set_transient(WindowID p_window, WindowID p_parent) { +void DisplayServerIOS::window_set_transient(WindowID p_window, WindowID p_parent) { // Probably not supported for iOS } -void DisplayServerIPhone::window_set_max_size(const Size2i p_size, WindowID p_window) { +void DisplayServerIOS::window_set_max_size(const Size2i p_size, WindowID p_window) { // Probably not supported for iOS } -Size2i DisplayServerIPhone::window_get_max_size(WindowID p_window) const { +Size2i DisplayServerIOS::window_get_max_size(WindowID p_window) const { return Size2i(); } -void DisplayServerIPhone::window_set_min_size(const Size2i p_size, WindowID p_window) { +void DisplayServerIOS::window_set_min_size(const Size2i p_size, WindowID p_window) { // Probably not supported for iOS } -Size2i DisplayServerIPhone::window_get_min_size(WindowID p_window) const { +Size2i DisplayServerIOS::window_get_min_size(WindowID p_window) const { return Size2i(); } -void DisplayServerIPhone::window_set_size(const Size2i p_size, WindowID p_window) { +void DisplayServerIOS::window_set_size(const Size2i p_size, WindowID p_window) { // Probably not supported for iOS } -Size2i DisplayServerIPhone::window_get_size(WindowID p_window) const { +Size2i DisplayServerIOS::window_get_size(WindowID p_window) const { CGRect screenBounds = [UIScreen mainScreen].bounds; return Size2i(screenBounds.size.width, screenBounds.size.height) * screen_get_max_scale(); } -Size2i DisplayServerIPhone::window_get_real_size(WindowID p_window) const { +Size2i DisplayServerIOS::window_get_real_size(WindowID p_window) const { return window_get_size(p_window); } -void DisplayServerIPhone::window_set_mode(WindowMode p_mode, WindowID p_window) { +void DisplayServerIOS::window_set_mode(WindowMode p_mode, WindowID p_window) { // Probably not supported for iOS } -DisplayServer::WindowMode DisplayServerIPhone::window_get_mode(WindowID p_window) const { +DisplayServer::WindowMode DisplayServerIOS::window_get_mode(WindowID p_window) const { return WindowMode::WINDOW_MODE_FULLSCREEN; } -bool DisplayServerIPhone::window_is_maximize_allowed(WindowID p_window) const { +bool DisplayServerIOS::window_is_maximize_allowed(WindowID p_window) const { return false; } -void DisplayServerIPhone::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) { +void DisplayServerIOS::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) { // Probably not supported for iOS } -bool DisplayServerIPhone::window_get_flag(WindowFlags p_flag, WindowID p_window) const { +bool DisplayServerIOS::window_get_flag(WindowFlags p_flag, WindowID p_window) const { return false; } -void DisplayServerIPhone::window_request_attention(WindowID p_window) { +void DisplayServerIOS::window_request_attention(WindowID p_window) { // Probably not supported for iOS } -void DisplayServerIPhone::window_move_to_foreground(WindowID p_window) { +void DisplayServerIOS::window_move_to_foreground(WindowID p_window) { // Probably not supported for iOS } -float DisplayServerIPhone::screen_get_max_scale() const { +float DisplayServerIOS::screen_get_max_scale() const { return screen_get_scale(SCREEN_OF_MAIN_WINDOW); } -void DisplayServerIPhone::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) { +void DisplayServerIOS::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) { screen_orientation = p_orientation; } -DisplayServer::ScreenOrientation DisplayServerIPhone::screen_get_orientation(int p_screen) const { +DisplayServer::ScreenOrientation DisplayServerIOS::screen_get_orientation(int p_screen) const { return screen_orientation; } -bool DisplayServerIPhone::window_can_draw(WindowID p_window) const { +bool DisplayServerIOS::window_can_draw(WindowID p_window) const { return true; } -bool DisplayServerIPhone::can_any_window_draw() const { +bool DisplayServerIOS::can_any_window_draw() const { return true; } -bool DisplayServerIPhone::screen_is_touchscreen(int p_screen) const { +bool DisplayServerIOS::screen_is_touchscreen(int p_screen) const { return true; } -void DisplayServerIPhone::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) { +void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) { NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()]; [AppDelegate.viewController.keyboardView @@ -595,37 +595,37 @@ void DisplayServerIPhone::virtual_keyboard_show(const String &p_existing_text, c cursorEnd:p_cursor_end]; } -void DisplayServerIPhone::virtual_keyboard_hide() { +void DisplayServerIOS::virtual_keyboard_hide() { [AppDelegate.viewController.keyboardView resignFirstResponder]; } -void DisplayServerIPhone::virtual_keyboard_set_height(int height) { +void DisplayServerIOS::virtual_keyboard_set_height(int height) { virtual_keyboard_height = height * screen_get_max_scale(); } -int DisplayServerIPhone::virtual_keyboard_get_height() const { +int DisplayServerIOS::virtual_keyboard_get_height() const { return virtual_keyboard_height; } -void DisplayServerIPhone::clipboard_set(const String &p_text) { +void DisplayServerIOS::clipboard_set(const String &p_text) { [UIPasteboard generalPasteboard].string = [NSString stringWithUTF8String:p_text.utf8()]; } -String DisplayServerIPhone::clipboard_get() const { +String DisplayServerIOS::clipboard_get() const { NSString *text = [UIPasteboard generalPasteboard].string; return String::utf8([text UTF8String]); } -void DisplayServerIPhone::screen_set_keep_on(bool p_enable) { +void DisplayServerIOS::screen_set_keep_on(bool p_enable) { [UIApplication sharedApplication].idleTimerDisabled = p_enable; } -bool DisplayServerIPhone::screen_is_kept_on() const { +bool DisplayServerIOS::screen_is_kept_on() const { return [UIApplication sharedApplication].idleTimerDisabled; } -void DisplayServerIPhone::resize_window(CGSize viewSize) { +void DisplayServerIOS::resize_window(CGSize viewSize) { Size2i size = Size2i(viewSize.width, viewSize.height) * screen_get_max_scale(); #if defined(VULKAN_ENABLED) @@ -638,14 +638,14 @@ void DisplayServerIPhone::resize_window(CGSize viewSize) { _window_callback(window_resize_callback, resize_rect); } -void DisplayServerIPhone::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { +void DisplayServerIOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { _THREAD_SAFE_METHOD_ #if defined(VULKAN_ENABLED) context_vulkan->set_vsync_mode(p_window, p_vsync_mode); #endif } -DisplayServer::VSyncMode DisplayServerIPhone::window_get_vsync_mode(WindowID p_window) const { +DisplayServer::VSyncMode DisplayServerIOS::window_get_vsync_mode(WindowID p_window) const { _THREAD_SAFE_METHOD_ #if defined(VULKAN_ENABLED) return context_vulkan->get_vsync_mode(p_window); diff --git a/platform/iphone/export/export.cpp b/platform/ios/export/export.cpp index 3b02e661c1..6024db2f2c 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/ios/export/export.cpp @@ -30,9 +30,10 @@ #include "export.h" +#include "editor/export/editor_export.h" #include "export_plugin.h" -void register_iphone_exporter() { +void register_ios_exporter() { Ref<EditorExportPlatformIOS> platform; platform.instantiate(); diff --git a/platform/osx/export/export.h b/platform/ios/export/export.h index b386337a09..756a1356ea 100644 --- a/platform/osx/export/export.h +++ b/platform/ios/export/export.h @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OSX_EXPORT_H -#define OSX_EXPORT_H +#ifndef IOS_EXPORT_H +#define IOS_EXPORT_H -void register_osx_exporter(); +void register_ios_exporter(); -#endif // OSX_EXPORT_H +#endif // IOS_EXPORT_H diff --git a/platform/iphone/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index 3b92bd19be..a2e80d33fd 100644 --- a/platform/iphone/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -418,7 +418,7 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ } // !BAS! I'm assuming the 9 in the original code was a typo. I've added -1 or else it seems to also be adding our terminating zero... - // should apply the same fix in our OSX export. + // should apply the same fix in our macOS export. CharString cs = strnew.utf8(); pfile.resize(cs.size() - 1); for (int i = 0; i < cs.size() - 1; i++) { @@ -1394,7 +1394,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p if (src_pkg_name.is_empty()) { String err; - src_pkg_name = find_export_template("iphone.zip", &err); + src_pkg_name = find_export_template("ios.zip", &err); if (src_pkg_name.is_empty()) { add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found.")); return ERR_FILE_NOT_FOUND; @@ -1444,7 +1444,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p return ERR_SKIP; } - String library_to_use = "libgodot.iphone." + String(p_debug ? "debug" : "release") + ".xcframework"; + String library_to_use = "libgodot.ios." + String(p_debug ? "debug" : "release") + ".xcframework"; print_line("Static framework: " + library_to_use); String pkg_name; @@ -1502,7 +1502,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p int ret = unzGoToFirstFile(src_pkg_zip); Vector<uint8_t> project_file_data; while (ret == UNZ_OK) { -#if defined(OSX_ENABLED) || defined(X11_ENABLED) +#if defined(MACOS_ENABLED) || defined(X11_ENABLED) bool is_execute = false; #endif @@ -1527,17 +1527,17 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p //write - file = file.replace_first("iphone/", ""); + file = file.replace_first("ios/", ""); if (files_to_parse.has(file)) { _fix_config_file(p_preset, data, config_data, p_debug); - } else if (file.begins_with("libgodot.iphone")) { + } else if (file.begins_with("libgodot.ios")) { if (!file.begins_with(library_to_use) || file.ends_with(String("/empty"))) { ret = unzGoToNextFile(src_pkg_zip); continue; //ignore! } found_library = true; -#if defined(OSX_ENABLED) || defined(X11_ENABLED) +#if defined(MACOS_ENABLED) || defined(X11_ENABLED) is_execute = true; #endif file = file.replace(library_to_use, binary_name + ".xcframework"); @@ -1580,7 +1580,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p f->store_buffer(data.ptr(), data.size()); } -#if defined(OSX_ENABLED) || defined(X11_ENABLED) +#if defined(MACOS_ENABLED) || defined(X11_ENABLED) if (is_execute) { // we need execute rights on this file chmod(file.utf8().get_data(), 0755); @@ -1725,7 +1725,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p f->store_buffer(project_file_data.ptr(), project_file_data.size()); } -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED { if (ep.step("Code-signing dylibs", 2)) { return ERR_SKIP; @@ -1790,7 +1790,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset // Look for export templates (first official, and if defined custom templates). - bool dvalid = exists_export_template("iphone.zip", &err); + bool dvalid = exists_export_template("ios.zip", &err); bool rvalid = dvalid; // Both in the same ZIP. if (p_preset->get("custom_template/debug") != "") { @@ -1838,7 +1838,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset } EditorExportPlatformIOS::EditorExportPlatformIOS() { - logo = ImageTexture::create_from_image(memnew(Image(_iphone_logo))); + logo = ImageTexture::create_from_image(memnew(Image(_ios_logo))); plugins_changed.set(); check_for_changes_thread.start(_check_for_changes_poll_thread, this); } diff --git a/platform/iphone/export/export_plugin.h b/platform/ios/export/export_plugin.h index 1db7418e3f..ce470bba78 100644 --- a/platform/iphone/export/export_plugin.h +++ b/platform/ios/export/export_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef IPHONE_EXPORT_PLUGIN_H -#define IPHONE_EXPORT_PLUGIN_H +#ifndef IOS_EXPORT_PLUGIN_H +#define IOS_EXPORT_PLUGIN_H #include "core/config/project_settings.h" #include "core/io/file_access.h" @@ -40,10 +40,10 @@ #include "core/os/os.h" #include "core/templates/safe_refcount.h" #include "core/version.h" -#include "editor/editor_export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export_platform.h" #include "main/splash.gen.h" -#include "platform/iphone/logo.gen.h" +#include "platform/ios/logo.gen.h" #include "string.h" #include "godot_plugin_config.h" @@ -290,4 +290,4 @@ public: } }; -#endif +#endif // IOS_EXPORT_PLUGIN_H diff --git a/platform/iphone/export/godot_plugin_config.cpp b/platform/ios/export/godot_plugin_config.cpp index 9118b95337..9118b95337 100644 --- a/platform/iphone/export/godot_plugin_config.cpp +++ b/platform/ios/export/godot_plugin_config.cpp diff --git a/platform/iphone/export/godot_plugin_config.h b/platform/ios/export/godot_plugin_config.h index 9ef8aa8c6d..5ca8b05b42 100644 --- a/platform/iphone/export/godot_plugin_config.h +++ b/platform/ios/export/godot_plugin_config.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef IPHONE_GODOT_PLUGIN_CONFIG_H -#define IPHONE_GODOT_PLUGIN_CONFIG_H +#ifndef IOS_GODOT_PLUGIN_CONFIG_H +#define IOS_GODOT_PLUGIN_CONFIG_H #include "core/error/error_list.h" #include "core/io/config_file.h" @@ -129,4 +129,4 @@ struct PluginConfigIOS { static PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, const String &path); }; -#endif // GODOT_PLUGIN_CONFIG_H +#endif // IOS_GODOT_PLUGIN_CONFIG_H diff --git a/platform/iphone/godot_app_delegate.h b/platform/ios/godot_app_delegate.h index 703a906bda..703a906bda 100644 --- a/platform/iphone/godot_app_delegate.h +++ b/platform/ios/godot_app_delegate.h diff --git a/platform/iphone/godot_app_delegate.m b/platform/ios/godot_app_delegate.m index 84347f9a30..84347f9a30 100644 --- a/platform/iphone/godot_app_delegate.m +++ b/platform/ios/godot_app_delegate.m diff --git a/platform/iphone/godot_iphone.mm b/platform/ios/godot_ios.mm index 59fdfa9dcd..5f3e786b8a 100644 --- a/platform/iphone/godot_iphone.mm +++ b/platform/ios/godot_ios.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* godot_iphone.mm */ +/* godot_ios.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -30,17 +30,17 @@ #include "core/string/ustring.h" #include "main/main.h" -#include "os_iphone.h" +#include "os_ios.h" #include <stdio.h> #include <string.h> #include <unistd.h> -static OSIPhone *os = nullptr; +static OS_IOS *os = nullptr; int add_path(int, char **); int add_cmdline(int, char **); -int iphone_main(int, char **, String); +int ios_main(int, char **, String); int add_path(int p_argc, char **p_args) { NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"]; @@ -74,7 +74,7 @@ int add_cmdline(int p_argc, char **p_args) { return p_argc; } -int iphone_main(int argc, char **argv, String data_dir, String cache_dir) { +int ios_main(int argc, char **argv, String data_dir, String cache_dir) { size_t len = strlen(argv[0]); while (len--) { @@ -91,11 +91,11 @@ int iphone_main(int argc, char **argv, String data_dir, String cache_dir) { chdir(path); } - printf("godot_iphone %s\n", argv[0]); + printf("godot_ios %s\n", argv[0]); char cwd[512]; getcwd(cwd, sizeof(cwd)); printf("cwd %s\n", cwd); - os = new OSIPhone(data_dir, cache_dir); + os = new OS_IOS(data_dir, cache_dir); // We must override main when testing is enabled TEST_MAIN_OVERRIDE @@ -124,8 +124,8 @@ int iphone_main(int argc, char **argv, String data_dir, String cache_dir) { return 0; } -void iphone_finish() { - printf("iphone_finish\n"); +void ios_finish() { + printf("ios_finish\n"); Main::cleanup(); delete os; } diff --git a/platform/iphone/godot_view.h b/platform/ios/godot_view.h index fcb97fa63a..fcb97fa63a 100644 --- a/platform/iphone/godot_view.h +++ b/platform/ios/godot_view.h diff --git a/platform/iphone/godot_view.mm b/platform/ios/godot_view.mm index e48dd2e507..9ed219508c 100644 --- a/platform/iphone/godot_view.mm +++ b/platform/ios/godot_view.mm @@ -33,7 +33,7 @@ #include "core/os/keyboard.h" #include "core/string/ustring.h" #import "display_layer.h" -#include "display_server_iphone.h" +#include "display_server_ios.h" #import "godot_view_gesture_recognizer.h" #import "godot_view_renderer.h" @@ -281,8 +281,8 @@ static const float earth_gravity = 9.80665; self.renderingLayer.frame = self.bounds; [self.renderingLayer layoutDisplayLayer]; - if (DisplayServerIPhone::get_singleton()) { - DisplayServerIPhone::get_singleton()->resize_window(self.bounds.size); + if (DisplayServerIOS::get_singleton()) { + DisplayServerIOS::get_singleton()->resize_window(self.bounds.size); } } @@ -348,7 +348,7 @@ static const float earth_gravity = 9.80665; int tid = [self getTouchIDForTouch:touch]; ERR_FAIL_COND(tid == -1); CGPoint touchPoint = [touch locationInView:self]; - DisplayServerIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1); + DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1); } } } @@ -362,7 +362,7 @@ static const float earth_gravity = 9.80665; ERR_FAIL_COND(tid == -1); CGPoint touchPoint = [touch locationInView:self]; CGPoint prev_point = [touch previousLocationInView:self]; - DisplayServerIPhone::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor); + DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor); } } } @@ -376,7 +376,7 @@ static const float earth_gravity = 9.80665; ERR_FAIL_COND(tid == -1); [self removeTouch:touch]; CGPoint touchPoint = [touch locationInView:self]; - DisplayServerIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false); + DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false); } } } @@ -388,7 +388,7 @@ static const float earth_gravity = 9.80665; UITouch *touch = [tlist objectAtIndex:i]; int tid = [self getTouchIDForTouch:touch]; ERR_FAIL_COND(tid == -1); - DisplayServerIPhone::get_singleton()->touches_cancelled(tid); + DisplayServerIOS::get_singleton()->touches_cancelled(tid); } } [self clearTouches]; @@ -452,28 +452,28 @@ static const float earth_gravity = 9.80665; switch (interfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: { - DisplayServerIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z); - DisplayServerIPhone::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z); - DisplayServerIPhone::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z); - DisplayServerIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z); + DisplayServerIOS::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z); + DisplayServerIOS::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z); + DisplayServerIOS::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z); + DisplayServerIOS::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z); } break; case UIInterfaceOrientationLandscapeRight: { - DisplayServerIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z); - DisplayServerIPhone::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z); - DisplayServerIPhone::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z); - DisplayServerIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z); + DisplayServerIOS::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z); + DisplayServerIOS::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z); + DisplayServerIOS::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z); + DisplayServerIOS::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z); } break; case UIInterfaceOrientationPortraitUpsideDown: { - DisplayServerIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z); - DisplayServerIPhone::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z); - DisplayServerIPhone::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z); - DisplayServerIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z); + DisplayServerIOS::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z); + DisplayServerIOS::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z); + DisplayServerIOS::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z); + DisplayServerIOS::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z); } break; default: { // assume portrait - DisplayServerIPhone::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z); - DisplayServerIPhone::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z); - DisplayServerIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z); - DisplayServerIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z); + DisplayServerIOS::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z); + DisplayServerIOS::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z); + DisplayServerIOS::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z); + DisplayServerIOS::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z); } break; } } diff --git a/platform/iphone/godot_view_gesture_recognizer.h b/platform/ios/godot_view_gesture_recognizer.h index 9fd8a6b222..9fd8a6b222 100644 --- a/platform/iphone/godot_view_gesture_recognizer.h +++ b/platform/ios/godot_view_gesture_recognizer.h diff --git a/platform/iphone/godot_view_gesture_recognizer.mm b/platform/ios/godot_view_gesture_recognizer.mm index 49a92add5e..49a92add5e 100644 --- a/platform/iphone/godot_view_gesture_recognizer.mm +++ b/platform/ios/godot_view_gesture_recognizer.mm diff --git a/platform/iphone/godot_view_renderer.h b/platform/ios/godot_view_renderer.h index b3ee23ae4f..b3ee23ae4f 100644 --- a/platform/iphone/godot_view_renderer.h +++ b/platform/ios/godot_view_renderer.h diff --git a/platform/iphone/godot_view_renderer.mm b/platform/ios/godot_view_renderer.mm index 32477ae41c..140410fbef 100644 --- a/platform/iphone/godot_view_renderer.mm +++ b/platform/ios/godot_view_renderer.mm @@ -32,9 +32,9 @@ #include "core/config/project_settings.h" #include "core/os/keyboard.h" -#import "display_server_iphone.h" +#import "display_server_ios.h" #include "main/main.h" -#include "os_iphone.h" +#include "os_ios.h" #include "servers/audio_server.h" #import <AudioToolbox/AudioServices.h> @@ -69,7 +69,7 @@ if (!self.hasStartedMain) { self.hasStartedMain = YES; - OSIPhone::get_singleton()->start(); + OS_IOS::get_singleton()->start(); return YES; } @@ -108,11 +108,11 @@ } - (void)renderOnView:(UIView *)view { - if (!OSIPhone::get_singleton()) { + if (!OS_IOS::get_singleton()) { return; } - OSIPhone::get_singleton()->iterate(); + OS_IOS::get_singleton()->iterate(); } @end diff --git a/platform/iphone/ios.h b/platform/ios/ios.h index 0607d7b395..0b3842b233 100644 --- a/platform/iphone/ios.h +++ b/platform/ios/ios.h @@ -58,4 +58,4 @@ public: iOS(); }; -#endif +#endif // IOS_H diff --git a/platform/iphone/ios.mm b/platform/ios/ios.mm index 79baae028a..79baae028a 100644 --- a/platform/iphone/ios.mm +++ b/platform/ios/ios.mm diff --git a/platform/iphone/joypad_iphone.h b/platform/ios/joypad_ios.h index 37e272a2c9..66c4b090bc 100644 --- a/platform/iphone/joypad_iphone.h +++ b/platform/ios/joypad_ios.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joypad_iphone.h */ +/* joypad_ios.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -30,7 +30,7 @@ #import <GameController/GameController.h> -@interface JoypadIPhoneObserver : NSObject +@interface JoypadIOSObserver : NSObject - (void)startObserving; - (void)startProcessing; @@ -38,13 +38,13 @@ @end -class JoypadIPhone { +class JoypadIOS { private: - JoypadIPhoneObserver *observer; + JoypadIOSObserver *observer; public: - JoypadIPhone(); - ~JoypadIPhone(); + JoypadIOS(); + ~JoypadIOS(); void start_processing(); }; diff --git a/platform/iphone/joypad_iphone.mm b/platform/ios/joypad_ios.mm index 9c2feeaaca..e147cb2527 100644 --- a/platform/iphone/joypad_iphone.mm +++ b/platform/ios/joypad_ios.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joypad_iphone.mm */ +/* joypad_ios.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#import "joypad_iphone.h" +#import "joypad_ios.h" #include "core/config/project_settings.h" #include "drivers/coreaudio/audio_driver_coreaudio.h" @@ -36,27 +36,27 @@ #import "godot_view.h" -#include "os_iphone.h" +#include "os_ios.h" -JoypadIPhone::JoypadIPhone() { - observer = [[JoypadIPhoneObserver alloc] init]; +JoypadIOS::JoypadIOS() { + observer = [[JoypadIOSObserver alloc] init]; [observer startObserving]; } -JoypadIPhone::~JoypadIPhone() { +JoypadIOS::~JoypadIOS() { if (observer) { [observer finishObserving]; observer = nil; } } -void JoypadIPhone::start_processing() { +void JoypadIOS::start_processing() { if (observer) { [observer startProcessing]; } } -@interface JoypadIPhoneObserver () +@interface JoypadIOSObserver () @property(assign, nonatomic) BOOL isObserving; @property(assign, nonatomic) BOOL isProcessing; @@ -65,7 +65,7 @@ void JoypadIPhone::start_processing() { @end -@implementation JoypadIPhoneObserver +@implementation JoypadIOSObserver - (instancetype)init { self = [super init]; diff --git a/platform/iphone/keyboard_input_view.h b/platform/ios/keyboard_input_view.h index 33fa5d571a..33fa5d571a 100644 --- a/platform/iphone/keyboard_input_view.h +++ b/platform/ios/keyboard_input_view.h diff --git a/platform/iphone/keyboard_input_view.mm b/platform/ios/keyboard_input_view.mm index f2a7b22483..76e3f23c9d 100644 --- a/platform/iphone/keyboard_input_view.mm +++ b/platform/ios/keyboard_input_view.mm @@ -31,8 +31,8 @@ #import "keyboard_input_view.h" #include "core/os/keyboard.h" -#include "display_server_iphone.h" -#include "os_iphone.h" +#include "display_server_ios.h" +#include "os_ios.h" @interface GodotKeyboardInputView () <UITextViewDelegate> @@ -115,8 +115,8 @@ - (void)deleteText:(NSInteger)charactersToDelete { for (int i = 0; i < charactersToDelete; i++) { - DisplayServerIPhone::get_singleton()->key(Key::BACKSPACE, true); - DisplayServerIPhone::get_singleton()->key(Key::BACKSPACE, false); + DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, true); + DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, false); } } @@ -138,8 +138,8 @@ break; } - DisplayServerIPhone::get_singleton()->key((Key)character, true); - DisplayServerIPhone::get_singleton()->key((Key)character, false); + DisplayServerIOS::get_singleton()->key((Key)character, true); + DisplayServerIOS::get_singleton()->key((Key)character, false); } } diff --git a/platform/iphone/logo.png b/platform/ios/logo.png Binary files differindex 966d8aa70a..966d8aa70a 100644 --- a/platform/iphone/logo.png +++ b/platform/ios/logo.png diff --git a/platform/iphone/main.m b/platform/ios/main.m index acfa7ab731..acfa7ab731 100644 --- a/platform/iphone/main.m +++ b/platform/ios/main.m diff --git a/platform/iphone/os_iphone.h b/platform/ios/os_ios.h index d03403bbb4..3b88f53b6a 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/ios/os_ios.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* os_iphone.h */ +/* os_ios.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,24 +28,24 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef IPHONE_ENABLED +#ifdef IOS_ENABLED -#ifndef OS_IPHONE_H -#define OS_IPHONE_H +#ifndef OS_IOS_H +#define OS_IOS_H #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/unix/os_unix.h" #include "ios.h" -#include "joypad_iphone.h" +#include "joypad_ios.h" #include "servers/audio_server.h" #include "servers/rendering/renderer_compositor.h" #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" -#include "platform/iphone/vulkan_context_iphone.h" +#include "platform/ios/vulkan_context_ios.h" #endif -class OSIPhone : public OS_Unix { +class OS_IOS : public OS_Unix { private: static HashMap<String, void *> dynamic_symbol_lookup_table; friend void register_dynamic_symbol(char *name, void *address); @@ -54,7 +54,7 @@ private: iOS *ios = nullptr; - JoypadIPhone *joypad_iphone = nullptr; + JoypadIOS *joypad_ios = nullptr; MainLoop *main_loop = nullptr; @@ -79,10 +79,10 @@ private: void deinitialize_modules(); public: - static OSIPhone *get_singleton(); + static OS_IOS *get_singleton(); - OSIPhone(String p_data_dir, String p_cache_dir); - ~OSIPhone(); + OS_IOS(String p_data_dir, String p_cache_dir); + ~OS_IOS(); void initialize_modules(); @@ -92,6 +92,9 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override; + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override; virtual Error close_dynamic_library(void *p_library_handle) override; virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override; @@ -119,6 +122,6 @@ public: void on_focus_in(); }; -#endif // OS_IPHONE_H +#endif // OS_IOS_H -#endif // IPHONE_ENABLED +#endif // OS_IOS_H diff --git a/platform/iphone/os_iphone.mm b/platform/ios/os_ios.mm index 95b06b728e..b9d186f355 100644 --- a/platform/iphone/os_iphone.mm +++ b/platform/ios/os_ios.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* os_iphone.mm */ +/* os_ios.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,22 +28,23 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef IPHONE_ENABLED +#ifdef IOS_ENABLED -#include "os_iphone.h" +#include "os_ios.h" #import "app_delegate.h" #include "core/config/project_settings.h" #include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/io/file_access_pack.h" -#include "display_server_iphone.h" +#include "display_server_ios.h" #include "drivers/unix/syslog_logger.h" #import "godot_view.h" #include "main/main.h" #import "view_controller.h" #import <AudioToolbox/AudioServices.h> +#import <CoreText/CoreText.h> #import <UIKit/UIKit.h> #import <dlfcn.h> #include <sys/sysctl.h> @@ -65,7 +66,7 @@ typedef void (*init_callback)(); static init_callback *ios_init_callbacks = nullptr; static int ios_init_callbacks_count = 0; static int ios_init_callbacks_capacity = 0; -HashMap<String, void *> OSIPhone::dynamic_symbol_lookup_table; +HashMap<String, void *> OS_IOS::dynamic_symbol_lookup_table; void add_ios_init_callback(init_callback cb) { if (ios_init_callbacks_count == ios_init_callbacks_capacity) { @@ -82,14 +83,14 @@ void add_ios_init_callback(init_callback cb) { } void register_dynamic_symbol(char *name, void *address) { - OSIPhone::dynamic_symbol_lookup_table[String(name)] = address; + OS_IOS::dynamic_symbol_lookup_table[String(name)] = address; } -OSIPhone *OSIPhone::get_singleton() { - return (OSIPhone *)OS::get_singleton(); +OS_IOS *OS_IOS::get_singleton() { + return (OS_IOS *)OS::get_singleton(); } -OSIPhone::OSIPhone(String p_data_dir, String p_cache_dir) { +OS_IOS::OS_IOS(String p_data_dir, String p_cache_dir) { for (int i = 0; i < ios_init_callbacks_count; ++i) { ios_init_callbacks[i](); } @@ -116,37 +117,37 @@ OSIPhone::OSIPhone(String p_data_dir, String p_cache_dir) { AudioDriverManager::add_driver(&audio_driver); - DisplayServerIPhone::register_iphone_driver(); + DisplayServerIOS::register_ios_driver(); } -OSIPhone::~OSIPhone() {} +OS_IOS::~OS_IOS() {} -void OSIPhone::alert(const String &p_alert, const String &p_title) { +void OS_IOS::alert(const String &p_alert, const String &p_title) { const CharString utf8_alert = p_alert.utf8(); const CharString utf8_title = p_title.utf8(); iOS::alert(utf8_alert.get_data(), utf8_title.get_data()); } -void OSIPhone::initialize_core() { +void OS_IOS::initialize_core() { OS_Unix::initialize_core(); set_user_data_dir(user_data_dir); } -void OSIPhone::initialize() { +void OS_IOS::initialize() { initialize_core(); } -void OSIPhone::initialize_modules() { +void OS_IOS::initialize_modules() { ios = memnew(iOS); Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", ios)); - joypad_iphone = memnew(JoypadIPhone); + joypad_ios = memnew(JoypadIOS); } -void OSIPhone::deinitialize_modules() { - if (joypad_iphone) { - memdelete(joypad_iphone); +void OS_IOS::deinitialize_modules() { + if (joypad_ios) { + memdelete(joypad_ios); } if (ios) { @@ -154,7 +155,7 @@ void OSIPhone::deinitialize_modules() { } } -void OSIPhone::set_main_loop(MainLoop *p_main_loop) { +void OS_IOS::set_main_loop(MainLoop *p_main_loop) { main_loop = p_main_loop; if (main_loop) { @@ -162,11 +163,11 @@ void OSIPhone::set_main_loop(MainLoop *p_main_loop) { } } -MainLoop *OSIPhone::get_main_loop() const { +MainLoop *OS_IOS::get_main_loop() const { return main_loop; } -void OSIPhone::delete_main_loop() { +void OS_IOS::delete_main_loop() { if (main_loop) { main_loop->finalize(); memdelete(main_loop); @@ -175,7 +176,7 @@ void OSIPhone::delete_main_loop() { main_loop = nullptr; } -bool OSIPhone::iterate() { +bool OS_IOS::iterate() { if (!main_loop) { return true; } @@ -187,15 +188,15 @@ bool OSIPhone::iterate() { return Main::iteration(); } -void OSIPhone::start() { +void OS_IOS::start() { Main::start(); - if (joypad_iphone) { - joypad_iphone->start_processing(); + if (joypad_ios) { + joypad_ios->start_processing(); } } -void OSIPhone::finalize() { +void OS_IOS::finalize() { deinitialize_modules(); // Already gets called @@ -204,7 +205,7 @@ void OSIPhone::finalize() { // MARK: Dynamic Libraries -Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { +Error OS_IOS::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { if (p_path.length() == 0) { p_library_handle = RTLD_SELF; @@ -217,16 +218,16 @@ Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handl return OS_Unix::open_dynamic_library(p_path, p_library_handle, p_also_set_library_path, r_resolved_path); } -Error OSIPhone::close_dynamic_library(void *p_library_handle) { +Error OS_IOS::close_dynamic_library(void *p_library_handle) { if (p_library_handle == RTLD_SELF) { return OK; } return OS_Unix::close_dynamic_library(p_library_handle); } -Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) { +Error OS_IOS::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) { if (p_library_handle == RTLD_SELF) { - void **ptr = OSIPhone::dynamic_symbol_lookup_table.getptr(p_name); + void **ptr = OS_IOS::dynamic_symbol_lookup_table.getptr(p_name); if (ptr) { p_symbol_handle = *ptr; return OK; @@ -235,11 +236,11 @@ Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const return OS_Unix::get_dynamic_library_symbol_handle(p_library_handle, p_name, p_symbol_handle, p_optional); } -String OSIPhone::get_name() const { +String OS_IOS::get_name() const { return "iOS"; } -String OSIPhone::get_model_name() const { +String OS_IOS::get_model_name() const { String model = ios->get_model(); if (model != "") { return model; @@ -248,7 +249,7 @@ String OSIPhone::get_model_name() const { return OS_Unix::get_model_name(); } -Error OSIPhone::shell_open(String p_uri) { +Error OS_IOS::shell_open(String p_uri) { NSString *urlPath = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()]; NSURL *url = [NSURL URLWithString:urlPath]; @@ -263,21 +264,21 @@ Error OSIPhone::shell_open(String p_uri) { return OK; } -void OSIPhone::set_user_data_dir(String p_dir) { +void OS_IOS::set_user_data_dir(String p_dir) { Ref<DirAccess> da = DirAccess::open(p_dir); user_data_dir = da->get_current_dir(); printf("setting data dir to %s from %s\n", user_data_dir.utf8().get_data(), p_dir.utf8().get_data()); } -String OSIPhone::get_user_data_dir() const { +String OS_IOS::get_user_data_dir() const { return user_data_dir; } -String OSIPhone::get_cache_path() const { +String OS_IOS::get_cache_path() const { return cache_dir; } -String OSIPhone::get_locale() const { +String OS_IOS::get_locale() const { NSString *preferedLanguage = [NSLocale preferredLanguages].firstObject; if (preferedLanguage) { @@ -288,12 +289,12 @@ String OSIPhone::get_locale() const { return String::utf8([localeIdentifier UTF8String]).replace("-", "_"); } -String OSIPhone::get_unique_id() const { +String OS_IOS::get_unique_id() const { NSString *uuid = [UIDevice currentDevice].identifierForVendor.UUIDString; return String::utf8([uuid UTF8String]); } -String OSIPhone::get_processor_name() const { +String OS_IOS::get_processor_name() const { char buffer[256]; size_t buffer_len = 256; if (sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_len, NULL, 0) == 0) { @@ -302,7 +303,81 @@ String OSIPhone::get_processor_name() const { ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string.")); } -void OSIPhone::vibrate_handheld(int p_duration_ms) { +Vector<String> OS_IOS::get_system_fonts() const { + HashSet<String> font_names; + CFArrayRef fonts = CTFontManagerCopyAvailableFontFamilyNames(); + if (fonts) { + for (CFIndex i = 0; i < CFArrayGetCount(fonts); i++) { + CFStringRef cf_name = (CFStringRef)CFArrayGetValueAtIndex(fonts, i); + if (cf_name && (CFStringGetLength(cf_name) > 0) && (CFStringCompare(cf_name, CFSTR("LastResort"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && (CFStringGetCharacterAtIndex(cf_name, 0) != '.')) { + NSString *ns_name = (__bridge NSString *)cf_name; + font_names.insert(String::utf8([ns_name UTF8String])); + } + } + CFRelease(fonts); + } + + Vector<String> ret; + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +} + +String OS_IOS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { + String ret; + + String font_name = p_font_name; + if (font_name.to_lower() == "sans-serif") { + font_name = "Helvetica"; + } else if (font_name.to_lower() == "serif") { + font_name = "Times"; + } else if (font_name.to_lower() == "monospace") { + font_name = "Courier"; + } else if (font_name.to_lower() == "fantasy") { + font_name = "Papyrus"; + } else if (font_name.to_lower() == "cursive") { + font_name = "Apple Chancery"; + }; + + CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8); + + CTFontSymbolicTraits traits = 0; + if (p_bold) { + traits |= kCTFontBoldTrait; + } + if (p_italic) { + traits |= kCTFontItalicTrait; + } + + CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits); + CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits); + + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name); + CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict); + + CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes); + if (font) { + CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(font, kCTFontURLAttribute); + if (url) { + NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]]; + ret = String::utf8([font_path UTF8String]); + CFRelease(url); + } + CFRelease(font); + } + + CFRelease(attributes); + CFRelease(traits_dict); + CFRelease(sym_traits); + CFRelease(name); + + return ret; +} + +void OS_IOS::vibrate_handheld(int p_duration_ms) { if (ios->supports_haptic_engine()) { ios->vibrate_haptic_engine((float)p_duration_ms / 1000.f); } else { @@ -311,16 +386,16 @@ void OSIPhone::vibrate_handheld(int p_duration_ms) { } } -bool OSIPhone::_check_internal_feature_support(const String &p_feature) { +bool OS_IOS::_check_internal_feature_support(const String &p_feature) { return p_feature == "mobile"; } -void OSIPhone::on_focus_out() { +void OS_IOS::on_focus_out() { if (is_focused) { is_focused = false; - if (DisplayServerIPhone::get_singleton()) { - DisplayServerIPhone::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT); + if (DisplayServerIOS::get_singleton()) { + DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT); } [AppDelegate.viewController.godotView stopRendering]; @@ -329,12 +404,12 @@ void OSIPhone::on_focus_out() { } } -void OSIPhone::on_focus_in() { +void OS_IOS::on_focus_in() { if (!is_focused) { is_focused = true; - if (DisplayServerIPhone::get_singleton()) { - DisplayServerIPhone::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN); + if (DisplayServerIOS::get_singleton()) { + DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN); } [AppDelegate.viewController.godotView startRendering]; @@ -343,4 +418,4 @@ void OSIPhone::on_focus_in() { } } -#endif // IPHONE_ENABLED +#endif // IOS_ENABLED diff --git a/platform/iphone/platform_config.h b/platform/ios/platform_config.h index fed77d8932..fed77d8932 100644 --- a/platform/iphone/platform_config.h +++ b/platform/ios/platform_config.h diff --git a/platform/iphone/tts_ios.h b/platform/ios/tts_ios.h index 064316b0b2..064316b0b2 100644 --- a/platform/iphone/tts_ios.h +++ b/platform/ios/tts_ios.h diff --git a/platform/iphone/tts_ios.mm b/platform/ios/tts_ios.mm index a079d02add..a079d02add 100644 --- a/platform/iphone/tts_ios.mm +++ b/platform/ios/tts_ios.mm diff --git a/platform/iphone/view_controller.h b/platform/ios/view_controller.h index c8b37a4d11..c8b37a4d11 100644 --- a/platform/iphone/view_controller.h +++ b/platform/ios/view_controller.h diff --git a/platform/iphone/view_controller.mm b/platform/ios/view_controller.mm index 4f4ef4f046..43669d3f94 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/ios/view_controller.mm @@ -30,11 +30,11 @@ #import "view_controller.h" #include "core/config/project_settings.h" -#include "display_server_iphone.h" +#include "display_server_ios.h" #import "godot_view.h" #import "godot_view_renderer.h" #import "keyboard_input_view.h" -#include "os_iphone.h" +#include "os_ios.h" #import <AVFoundation/AVFoundation.h> #import <GameController/GameController.h> @@ -168,11 +168,11 @@ } - (BOOL)shouldAutorotate { - if (!DisplayServerIPhone::get_singleton()) { + if (!DisplayServerIOS::get_singleton()) { return NO; } - switch (DisplayServerIPhone::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) { + switch (DisplayServerIOS::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) { case DisplayServer::SCREEN_SENSOR: case DisplayServer::SCREEN_SENSOR_LANDSCAPE: case DisplayServer::SCREEN_SENSOR_PORTRAIT: @@ -183,11 +183,11 @@ } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - if (!DisplayServerIPhone::get_singleton()) { + if (!DisplayServerIOS::get_singleton()) { return UIInterfaceOrientationMaskAll; } - switch (DisplayServerIPhone::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) { + switch (DisplayServerIOS::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) { case DisplayServer::SCREEN_PORTRAIT: return UIInterfaceOrientationMaskPortrait; case DisplayServer::SCREEN_REVERSE_LANDSCAPE: @@ -226,14 +226,14 @@ CGRect rawFrame = [value CGRectValue]; CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil]; - if (DisplayServerIPhone::get_singleton()) { - DisplayServerIPhone::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height); + if (DisplayServerIOS::get_singleton()) { + DisplayServerIOS::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height); } } - (void)keyboardHidden:(NSNotification *)notification { - if (DisplayServerIPhone::get_singleton()) { - DisplayServerIPhone::get_singleton()->virtual_keyboard_set_height(0); + if (DisplayServerIOS::get_singleton()) { + DisplayServerIOS::get_singleton()->virtual_keyboard_set_height(0); } } diff --git a/platform/iphone/vulkan_context_iphone.h b/platform/ios/vulkan_context_ios.h index 7576525755..e9c09e087a 100644 --- a/platform/iphone/vulkan_context_iphone.h +++ b/platform/ios/vulkan_context_ios.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* vulkan_context_iphone.h */ +/* vulkan_context_ios.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VULKAN_CONTEXT_IPHONE_H -#define VULKAN_CONTEXT_IPHONE_H +#ifndef VULKAN_CONTEXT_IOS_H +#define VULKAN_CONTEXT_IOS_H #include "drivers/vulkan/vulkan_context.h" #import <UIKit/UIKit.h> -class VulkanContextIPhone : public VulkanContext { +class VulkanContextIOS : public VulkanContext { virtual const char *_get_platform_surface_extension() const; public: Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height); - VulkanContextIPhone(); - ~VulkanContextIPhone(); + VulkanContextIOS(); + ~VulkanContextIOS(); }; -#endif // VULKAN_CONTEXT_IPHONE_H +#endif // VULKAN_CONTEXT_IOS_H diff --git a/platform/iphone/vulkan_context_iphone.mm b/platform/ios/vulkan_context_ios.mm index 17cb0f6009..09cd369aa5 100644 --- a/platform/iphone/vulkan_context_iphone.mm +++ b/platform/ios/vulkan_context_ios.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* vulkan_context_iphone.mm */ +/* vulkan_context_ios.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "vulkan_context_iphone.h" +#include "vulkan_context_ios.h" #ifdef USE_VOLK #include <volk.h> #else #include <vulkan/vulkan.h> #endif -const char *VulkanContextIPhone::_get_platform_surface_extension() const { +const char *VulkanContextIOS::_get_platform_surface_extension() const { return VK_MVK_IOS_SURFACE_EXTENSION_NAME; } -Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) { +Error VulkanContextIOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, CALayer *p_metal_layer, int p_width, int p_height) { VkIOSSurfaceCreateInfoMVK createInfo; createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; createInfo.pNext = nullptr; @@ -54,6 +54,6 @@ Error VulkanContextIPhone::window_create(DisplayServer::WindowID p_window_id, Di return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height); } -VulkanContextIPhone::VulkanContextIPhone() {} +VulkanContextIOS::VulkanContextIOS() {} -VulkanContextIPhone::~VulkanContextIPhone() {} +VulkanContextIOS::~VulkanContextIOS() {} diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h index b7b0b3ac96..807e2f936b 100644 --- a/platform/javascript/audio_driver_javascript.h +++ b/platform/javascript/audio_driver_javascript.h @@ -158,4 +158,4 @@ public: }; #endif -#endif +#endif // AUDIO_DRIVER_JAVASCRIPT_H diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h index 41cc66cfb8..29c335ed0e 100644 --- a/platform/javascript/export/export.h +++ b/platform/javascript/export/export.h @@ -33,4 +33,4 @@ void register_javascript_exporter(); -#endif +#endif // JAVASCRIPT_EXPORT_H diff --git a/platform/javascript/export/export_plugin.h b/platform/javascript/export/export_plugin.h index 1aaec5454d..e6ca5976df 100644 --- a/platform/javascript/export/export_plugin.h +++ b/platform/javascript/export/export_plugin.h @@ -36,8 +36,8 @@ #include "core/io/stream_peer_ssl.h" #include "core/io/tcp_server.h" #include "core/io/zip_io.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" +#include "editor/export/editor_export_platform.h" #include "main/splash.gen.h" #include "platform/javascript/logo.gen.h" #include "platform/javascript/run_icon.gen.h" @@ -144,4 +144,4 @@ public: ~EditorExportPlatformJavaScript(); }; -#endif +#endif // JAVASCRIPT_EXPORT_PLUGIN_H diff --git a/platform/javascript/export/export_server.h b/platform/javascript/export/export_server.h index a831b76076..ddbe3cca30 100644 --- a/platform/javascript/export/export_server.h +++ b/platform/javascript/export/export_server.h @@ -35,7 +35,6 @@ #include "core/io/stream_peer_ssl.h" #include "core/io/tcp_server.h" #include "core/io/zip_io.h" -#include "editor/editor_export.h" #include "editor/editor_paths.h" class EditorHTTPServer : public RefCounted { @@ -248,4 +247,4 @@ public: } }; -#endif +#endif // JAVASCRIPT_EXPORT_SERVER_H diff --git a/platform/javascript/godot_audio.h b/platform/javascript/godot_audio.h index 012f8daeb7..3855b7301e 100644 --- a/platform/javascript/godot_audio.h +++ b/platform/javascript/godot_audio.h @@ -63,4 +63,4 @@ extern void godot_audio_script_start(float *p_in_buf, int p_in_size, float *p_ou } #endif -#endif /* GODOT_AUDIO_H */ +#endif // GODOT_AUDIO_H diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h index 1a383c9799..1dce8035a6 100644 --- a/platform/javascript/godot_js.h +++ b/platform/javascript/godot_js.h @@ -58,6 +58,7 @@ extern void godot_js_input_mouse_move_cb(void (*p_callback)(double p_x, double p extern void godot_js_input_mouse_wheel_cb(int (*p_callback)(double p_delta_x, double p_delta_y)); extern void godot_js_input_touch_cb(void (*p_callback)(int p_type, int p_count), uint32_t *r_identifiers, double *r_coords); extern void godot_js_input_key_cb(void (*p_callback)(int p_type, int p_repeat, int p_modifiers), char r_code[32], char r_key[32]); +extern void godot_js_input_vibrate_handheld(int p_duration_ms); // Input gamepad extern void godot_js_input_gamepad_cb(void (*p_on_change)(int p_index, int p_connected, const char *p_id, const char *p_guid)); @@ -127,4 +128,4 @@ extern void godot_js_display_vk_hide(); } #endif -#endif /* GODOT_JS_H */ +#endif // GODOT_JS_H diff --git a/platform/javascript/godot_webgl2.h b/platform/javascript/godot_webgl2.h index 7c357ff66d..968b70f84b 100644 --- a/platform/javascript/godot_webgl2.h +++ b/platform/javascript/godot_webgl2.h @@ -34,4 +34,4 @@ #include "GLES3/gl3.h" #include "webgl/webgl2.h" -#endif +#endif // GODOT_WEBGL2_H diff --git a/platform/javascript/http_client_javascript.h b/platform/javascript/http_client_javascript.h index 096aa6a153..fcd225ffc9 100644 --- a/platform/javascript/http_client_javascript.h +++ b/platform/javascript/http_client_javascript.h @@ -105,4 +105,5 @@ public: HTTPClientJavaScript(); ~HTTPClientJavaScript(); }; + #endif // HTTP_CLIENT_JAVASCRIPT_H diff --git a/platform/javascript/js/libs/library_godot_input.js b/platform/javascript/js/libs/library_godot_input.js index 1e64c260f8..51571d64a2 100644 --- a/platform/javascript/js/libs/library_godot_input.js +++ b/platform/javascript/js/libs/library_godot_input.js @@ -534,6 +534,15 @@ const GodotInput = { GodotRuntime.free(ptr); }, false); }, + + godot_js_input_vibrate_handheld__sig: 'vi', + godot_js_input_vibrate_handheld: function (p_duration_ms) { + if (typeof navigator.vibrate !== 'function') { + GodotRuntime.print('This browser does not support vibration.'); + } else { + navigator.vibrate(p_duration_ms); + } + }, }; autoAddDeps(GodotInput, '$GodotInput'); diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 1686353229..dc81b8b4b6 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -177,6 +177,10 @@ String OS_JavaScript::get_name() const { return "HTML5"; } +void OS_JavaScript::vibrate_handheld(int p_duration_ms) { + godot_js_input_vibrate_handheld(p_duration_ms); +} + String OS_JavaScript::get_user_data_dir() const { return "/userfs"; } diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 0c672111cc..35e13c94fc 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -90,6 +90,8 @@ public: // Implemented in javascript_main.cpp loop callback instead. void add_frame_delay(bool p_can_draw) override {} + void vibrate_handheld(int p_duration_ms) override; + String get_cache_path() const override; String get_config_path() const override; String get_data_path() const override; @@ -107,4 +109,4 @@ public: OS_JavaScript(); }; -#endif +#endif // OS_JAVASCRIPT_H diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub index 09a432eae2..6fbaa1c383 100644 --- a/platform/linuxbsd/SCsub +++ b/platform/linuxbsd/SCsub @@ -12,7 +12,7 @@ common_linuxbsd = [ "freedesktop_screensaver.cpp", ] -if "x11" in env and env["x11"]: +if env["x11"]: common_linuxbsd += [ "gl_manager_x11.cpp", "detect_prime_x11.cpp", @@ -20,13 +20,16 @@ if "x11" in env and env["x11"]: "key_mapping_x11.cpp", ] -if "speechd" in env and env["speechd"]: + if env["vulkan"]: + common_linuxbsd.append("vulkan_context_x11.cpp") + +if env["speechd"]: common_linuxbsd.append(["speechd-so_wrap.c", "tts_linux.cpp"]) -if "vulkan" in env and env["vulkan"]: - common_linuxbsd.append("vulkan_context_x11.cpp") +if env["fontconfig"]: + common_linuxbsd.append("fontconfig-so_wrap.c") -if "udev" in env and env["udev"]: +if env["udev"]: common_linuxbsd.append("libudev-so_wrap.c") prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_linuxbsd) diff --git a/platform/linuxbsd/crash_handler_linuxbsd.h b/platform/linuxbsd/crash_handler_linuxbsd.h index 2e44476c3f..1b77352cca 100644 --- a/platform/linuxbsd/crash_handler_linuxbsd.h +++ b/platform/linuxbsd/crash_handler_linuxbsd.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CRASH_HANDLER_X11_H -#define CRASH_HANDLER_X11_H +#ifndef CRASH_HANDLER_LINUXBSD_H +#define CRASH_HANDLER_LINUXBSD_H class CrashHandler { bool disabled; @@ -44,4 +44,4 @@ public: ~CrashHandler(); }; -#endif // CRASH_HANDLER_X11_H +#endif // CRASH_HANDLER_LINUXBSD_H diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 19cf341c85..1c75e1c443 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -1,6 +1,7 @@ import os import platform import sys +from methods import get_compiler_version, using_gcc def is_active(): @@ -15,47 +16,11 @@ def can_build(): if os.name != "posix" or sys.platform == "darwin": return False - # Check the minimal dependencies - x11_error = os.system("pkg-config --version > /dev/null") - if x11_error: + pkgconf_error = os.system("pkg-config --version > /dev/null") + if pkgconf_error: print("Error: pkg-config not found. Aborting.") return False - x11_error = os.system("pkg-config x11 --modversion > /dev/null") - if x11_error: - print("Error: X11 libraries not found. Aborting.") - return False - - x11_error = os.system("pkg-config xcursor --modversion > /dev/null") - if x11_error: - print("Error: Xcursor library not found. Aborting.") - return False - - x11_error = os.system("pkg-config xinerama --modversion > /dev/null") - if x11_error: - print("Error: Xinerama library not found. Aborting.") - return False - - x11_error = os.system("pkg-config xext --modversion > /dev/null") - if x11_error: - print("Error: Xext library not found. Aborting.") - return False - - x11_error = os.system("pkg-config xrandr --modversion > /dev/null") - if x11_error: - print("Error: XrandR library not found. Aborting.") - return False - - x11_error = os.system("pkg-config xrender --modversion > /dev/null") - if x11_error: - print("Error: XRender library not found. Aborting.") - return False - - x11_error = os.system("pkg-config xi --modversion > /dev/null") - if x11_error: - print("Error: Xi library not found. Aborting.") - return False - return True @@ -63,9 +28,9 @@ def get_opts(): from SCons.Variables import BoolVariable, EnumVariable return [ + EnumVariable("linker", "Linker program", "default", ("default", "bfd", "gold", "lld", "mold")), BoolVariable("use_llvm", "Use the LLVM compiler", False), - BoolVariable("use_lld", "Use the LLD linker", False), - BoolVariable("use_thinlto", "Use ThinLTO", False), + BoolVariable("use_thinlto", "Use ThinLTO (LLVM only, requires linker=lld, implies use_lto=yes)", 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), @@ -76,6 +41,7 @@ def get_opts(): BoolVariable("pulseaudio", "Detect and use PulseAudio", True), BoolVariable("dbus", "Detect and use D-Bus to handle screensaver", True), BoolVariable("speechd", "Detect and use Speech Dispatcher for Text-to-Speech support", True), + BoolVariable("fontconfig", "Detect and use fontconfig for system fonts support", True), BoolVariable("udev", "Use udev for gamepad connection callbacks", True), BoolVariable("x11", "Enable X11 display", True), BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True), @@ -147,15 +113,32 @@ def configure(env): env["CXX"] = "clang++" env.extra_suffix = ".llvm" + env.extra_suffix - if env["use_lld"]: - if env["use_llvm"]: - env.Append(LINKFLAGS=["-fuse-ld=lld"]) - if env["use_thinlto"]: - # A convenience so you don't need to write use_lto too when using SCons - env["use_lto"] = True + if env["linker"] != "default": + print("Using linker program: " + env["linker"]) + if env["linker"] == "mold" and using_gcc(env): # GCC < 12.1 doesn't support -fuse-ld=mold. + cc_version = get_compiler_version(env) + cc_semver = (int(cc_version["major"]), int(cc_version["minor"])) + if cc_semver < (12, 1): + found_wrapper = False + for path in ["/usr/libexec", "/usr/local/libexec", "/usr/lib", "/usr/local/lib"]: + if os.path.isfile(path + "/mold/ld"): + env.Append(LINKFLAGS=["-B" + path + "/mold"]) + found_wrapper = True + break + if not found_wrapper: + print("Couldn't locate mold installation path. Make sure it's installed in /usr or /usr/local.") + sys.exit(255) + else: + env.Append(LINKFLAGS=["-fuse-ld=mold"]) else: - print("Using LLD with GCC is not supported yet. Try compiling with 'use_llvm=yes'.") + env.Append(LINKFLAGS=["-fuse-ld=%s" % env["linker"]]) + + if env["use_thinlto"]: + if not env["use_llvm"] or env["linker"] != "lld": + print("ThinLTO is only compatible with LLVM and the LLD linker, use `use_llvm=yes linker=lld`.") sys.exit(255) + else: + env["use_lto"] = True # ThinLTO implies LTO if env["use_coverage"]: env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"]) @@ -200,33 +183,32 @@ def configure(env): env.Append(LINKFLAGS=["-fsanitize=memory"]) if env["use_lto"]: - if not env["use_llvm"] and env.GetOption("num_jobs") > 1: + if env["use_thinlto"]: + env.Append(CCFLAGS=["-flto=thin"]) + env.Append(LINKFLAGS=["-flto=thin"]) + elif not env["use_llvm"] and env.GetOption("num_jobs") > 1: env.Append(CCFLAGS=["-flto"]) env.Append(LINKFLAGS=["-flto=" + str(env.GetOption("num_jobs"))]) else: - if env["use_lld"] and env["use_thinlto"]: - env.Append(CCFLAGS=["-flto=thin"]) - env.Append(LINKFLAGS=["-flto=thin"]) - else: - env.Append(CCFLAGS=["-flto"]) - env.Append(LINKFLAGS=["-flto"]) + env.Append(CCFLAGS=["-flto"]) + env.Append(LINKFLAGS=["-flto"]) if not env["use_llvm"]: env["RANLIB"] = "gcc-ranlib" env["AR"] = "gcc-ar" env.Append(CCFLAGS=["-pipe"]) - env.Append(LINKFLAGS=["-pipe"]) ## Dependencies - env.ParseConfig("pkg-config x11 --cflags --libs") - env.ParseConfig("pkg-config xcursor --cflags --libs") - env.ParseConfig("pkg-config xinerama --cflags --libs") - env.ParseConfig("pkg-config xext --cflags --libs") - env.ParseConfig("pkg-config xrandr --cflags --libs") - env.ParseConfig("pkg-config xrender --cflags --libs") - env.ParseConfig("pkg-config xi --cflags --libs") + if env["x11"]: + env.ParseConfig("pkg-config x11 --cflags --libs") + env.ParseConfig("pkg-config xcursor --cflags --libs") + env.ParseConfig("pkg-config xinerama --cflags --libs") + env.ParseConfig("pkg-config xext --cflags --libs") + env.ParseConfig("pkg-config xrandr --cflags --libs") + env.ParseConfig("pkg-config xrender --cflags --libs") + env.ParseConfig("pkg-config xi --cflags --libs") if env["touch"]: env.Append(CPPDEFINES=["TOUCH_ENABLED"]) @@ -317,6 +299,14 @@ def configure(env): ## Flags + if env["fontconfig"]: + if os.system("pkg-config --exists fontconfig") == 0: # 0 means found + env.Append(CPPDEFINES=["FONTCONFIG_ENABLED"]) + env.ParseConfig("pkg-config fontconfig --cflags") # Only cflags, we dlopen the library. + else: + env["fontconfig"] = False + print("Warning: fontconfig libraries not found. Disabling the system fonts support.") + if os.system("pkg-config --exists alsa") == 0: # 0 means found env["alsa"] = True env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) @@ -382,8 +372,9 @@ def configure(env): # No pkgconfig file so far, hardcode expected lib name. env.Append(LIBS=["glslang", "SPIRV"]) - env.Append(CPPDEFINES=["GLES3_ENABLED"]) - env.ParseConfig("pkg-config gl --cflags --libs") + if env["opengl3"]: + env.Append(CPPDEFINES=["GLES3_ENABLED"]) + env.ParseConfig("pkg-config gl --cflags --libs") env.Append(LIBS=["pthread"]) diff --git a/platform/linuxbsd/detect_prime_x11.h b/platform/linuxbsd/detect_prime_x11.h index e60f9ebfdf..21ebaead32 100644 --- a/platform/linuxbsd/detect_prime_x11.h +++ b/platform/linuxbsd/detect_prime_x11.h @@ -34,4 +34,5 @@ int detect_prime(); #endif -#endif + +#endif // DETECT_PRIME_X11_H diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index ecd7723993..d4267d3c02 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -275,7 +275,7 @@ bool DisplayServerX11::_refresh_device_info() { xi.pen_pressure_range[dev->deviceid] = Vector2(pressure_min, pressure_max); xi.pen_tilt_x_range[dev->deviceid] = Vector2(tilt_x_min, tilt_x_max); xi.pen_tilt_y_range[dev->deviceid] = Vector2(tilt_y_min, tilt_y_max); - xi.pen_inverted_devices[dev->deviceid] = (bool)strstr(dev->name, "eraser"); + xi.pen_inverted_devices[dev->deviceid] = String(dev->name).findn("eraser") > 0; } XIFreeDeviceInfo(info); diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp index 4240e9adc0..bc1235bcec 100644 --- a/platform/linuxbsd/export/export.cpp +++ b/platform/linuxbsd/export/export.cpp @@ -30,6 +30,7 @@ #include "export.h" +#include "editor/export/editor_export.h" #include "export_plugin.h" void register_linuxbsd_exporter() { diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp index 4e14920e79..d54e07d8a5 100644 --- a/platform/linuxbsd/export/export_plugin.cpp +++ b/platform/linuxbsd/export/export_plugin.cpp @@ -84,7 +84,7 @@ void EditorExportPlatformLinuxBSD::set_extension(const String &p_extension, cons } String EditorExportPlatformLinuxBSD::get_template_file_name(const String &p_target, const String &p_arch) const { - return "linux_x11_" + p_arch + "_" + p_target; + return "linux_" + p_target + "." + p_arch; } List<String> EditorExportPlatformLinuxBSD::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { diff --git a/platform/linuxbsd/export/export_plugin.h b/platform/linuxbsd/export/export_plugin.h index e04bcc20f9..98e4616035 100644 --- a/platform/linuxbsd/export/export_plugin.h +++ b/platform/linuxbsd/export/export_plugin.h @@ -32,8 +32,8 @@ #define LINUXBSD_EXPORT_PLUGIN_H #include "core/io/file_access.h" -#include "editor/editor_export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export_platform_pc.h" #include "platform/linuxbsd/logo.gen.h" #include "scene/resources/texture.h" @@ -49,4 +49,4 @@ public: virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override; }; -#endif +#endif // LINUXBSD_EXPORT_PLUGIN_H diff --git a/platform/linuxbsd/fontconfig-so_wrap.c b/platform/linuxbsd/fontconfig-so_wrap.c new file mode 100644 index 0000000000..7845a6fe05 --- /dev/null +++ b/platform/linuxbsd/fontconfig-so_wrap.c @@ -0,0 +1,2278 @@ +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by ./generate-wrapper.py 0.3 on 2022-07-27 17:50:40 +// flags: ./generate-wrapper.py --include /usr/include/fontconfig/fontconfig.h --sys-include <fontconfig/fontconfig.h> --soname libfontconfig.so --init-name fontconfig --output-header fontconfig-so_wrap.h --output-implementation fontconfig-so_wrap.c --omit-prefix FcCharSet +// +#include <stdint.h> + +#define FcBlanksCreate FcBlanksCreate_dylibloader_orig_fontconfig +#define FcBlanksDestroy FcBlanksDestroy_dylibloader_orig_fontconfig +#define FcBlanksAdd FcBlanksAdd_dylibloader_orig_fontconfig +#define FcBlanksIsMember FcBlanksIsMember_dylibloader_orig_fontconfig +#define FcCacheDir FcCacheDir_dylibloader_orig_fontconfig +#define FcCacheCopySet FcCacheCopySet_dylibloader_orig_fontconfig +#define FcCacheSubdir FcCacheSubdir_dylibloader_orig_fontconfig +#define FcCacheNumSubdir FcCacheNumSubdir_dylibloader_orig_fontconfig +#define FcCacheNumFont FcCacheNumFont_dylibloader_orig_fontconfig +#define FcDirCacheUnlink FcDirCacheUnlink_dylibloader_orig_fontconfig +#define FcDirCacheValid FcDirCacheValid_dylibloader_orig_fontconfig +#define FcDirCacheClean FcDirCacheClean_dylibloader_orig_fontconfig +#define FcCacheCreateTagFile FcCacheCreateTagFile_dylibloader_orig_fontconfig +#define FcDirCacheCreateUUID FcDirCacheCreateUUID_dylibloader_orig_fontconfig +#define FcDirCacheDeleteUUID FcDirCacheDeleteUUID_dylibloader_orig_fontconfig +#define FcConfigHome FcConfigHome_dylibloader_orig_fontconfig +#define FcConfigEnableHome FcConfigEnableHome_dylibloader_orig_fontconfig +#define FcConfigFilename FcConfigFilename_dylibloader_orig_fontconfig +#define FcConfigCreate FcConfigCreate_dylibloader_orig_fontconfig +#define FcConfigReference FcConfigReference_dylibloader_orig_fontconfig +#define FcConfigDestroy FcConfigDestroy_dylibloader_orig_fontconfig +#define FcConfigSetCurrent FcConfigSetCurrent_dylibloader_orig_fontconfig +#define FcConfigGetCurrent FcConfigGetCurrent_dylibloader_orig_fontconfig +#define FcConfigUptoDate FcConfigUptoDate_dylibloader_orig_fontconfig +#define FcConfigBuildFonts FcConfigBuildFonts_dylibloader_orig_fontconfig +#define FcConfigGetFontDirs FcConfigGetFontDirs_dylibloader_orig_fontconfig +#define FcConfigGetConfigDirs FcConfigGetConfigDirs_dylibloader_orig_fontconfig +#define FcConfigGetConfigFiles FcConfigGetConfigFiles_dylibloader_orig_fontconfig +#define FcConfigGetCache FcConfigGetCache_dylibloader_orig_fontconfig +#define FcConfigGetBlanks FcConfigGetBlanks_dylibloader_orig_fontconfig +#define FcConfigGetCacheDirs FcConfigGetCacheDirs_dylibloader_orig_fontconfig +#define FcConfigGetRescanInterval FcConfigGetRescanInterval_dylibloader_orig_fontconfig +#define FcConfigSetRescanInterval FcConfigSetRescanInterval_dylibloader_orig_fontconfig +#define FcConfigGetFonts FcConfigGetFonts_dylibloader_orig_fontconfig +#define FcConfigAppFontAddFile FcConfigAppFontAddFile_dylibloader_orig_fontconfig +#define FcConfigAppFontAddDir FcConfigAppFontAddDir_dylibloader_orig_fontconfig +#define FcConfigAppFontClear FcConfigAppFontClear_dylibloader_orig_fontconfig +#define FcConfigSubstituteWithPat FcConfigSubstituteWithPat_dylibloader_orig_fontconfig +#define FcConfigSubstitute FcConfigSubstitute_dylibloader_orig_fontconfig +#define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_orig_fontconfig +#define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_orig_fontconfig +#define FcConfigFileInfoIterInit FcConfigFileInfoIterInit_dylibloader_orig_fontconfig +#define FcConfigFileInfoIterNext FcConfigFileInfoIterNext_dylibloader_orig_fontconfig +#define FcConfigFileInfoIterGet FcConfigFileInfoIterGet_dylibloader_orig_fontconfig +#define FcValuePrint FcValuePrint_dylibloader_orig_fontconfig +#define FcPatternPrint FcPatternPrint_dylibloader_orig_fontconfig +#define FcFontSetPrint FcFontSetPrint_dylibloader_orig_fontconfig +#define FcGetDefaultLangs FcGetDefaultLangs_dylibloader_orig_fontconfig +#define FcDefaultSubstitute FcDefaultSubstitute_dylibloader_orig_fontconfig +#define FcFileIsDir FcFileIsDir_dylibloader_orig_fontconfig +#define FcFileScan FcFileScan_dylibloader_orig_fontconfig +#define FcDirScan FcDirScan_dylibloader_orig_fontconfig +#define FcDirSave FcDirSave_dylibloader_orig_fontconfig +#define FcDirCacheLoad FcDirCacheLoad_dylibloader_orig_fontconfig +#define FcDirCacheRescan FcDirCacheRescan_dylibloader_orig_fontconfig +#define FcDirCacheRead FcDirCacheRead_dylibloader_orig_fontconfig +#define FcDirCacheLoadFile FcDirCacheLoadFile_dylibloader_orig_fontconfig +#define FcDirCacheUnload FcDirCacheUnload_dylibloader_orig_fontconfig +#define FcFreeTypeQuery FcFreeTypeQuery_dylibloader_orig_fontconfig +#define FcFreeTypeQueryAll FcFreeTypeQueryAll_dylibloader_orig_fontconfig +#define FcFontSetCreate FcFontSetCreate_dylibloader_orig_fontconfig +#define FcFontSetDestroy FcFontSetDestroy_dylibloader_orig_fontconfig +#define FcFontSetAdd FcFontSetAdd_dylibloader_orig_fontconfig +#define FcInitLoadConfig FcInitLoadConfig_dylibloader_orig_fontconfig +#define FcInitLoadConfigAndFonts FcInitLoadConfigAndFonts_dylibloader_orig_fontconfig +#define FcInit FcInit_dylibloader_orig_fontconfig +#define FcFini FcFini_dylibloader_orig_fontconfig +#define FcGetVersion FcGetVersion_dylibloader_orig_fontconfig +#define FcInitReinitialize FcInitReinitialize_dylibloader_orig_fontconfig +#define FcInitBringUptoDate FcInitBringUptoDate_dylibloader_orig_fontconfig +#define FcGetLangs FcGetLangs_dylibloader_orig_fontconfig +#define FcLangNormalize FcLangNormalize_dylibloader_orig_fontconfig +#define FcLangGetCharSet FcLangGetCharSet_dylibloader_orig_fontconfig +#define FcLangSetCreate FcLangSetCreate_dylibloader_orig_fontconfig +#define FcLangSetDestroy FcLangSetDestroy_dylibloader_orig_fontconfig +#define FcLangSetCopy FcLangSetCopy_dylibloader_orig_fontconfig +#define FcLangSetAdd FcLangSetAdd_dylibloader_orig_fontconfig +#define FcLangSetDel FcLangSetDel_dylibloader_orig_fontconfig +#define FcLangSetHasLang FcLangSetHasLang_dylibloader_orig_fontconfig +#define FcLangSetCompare FcLangSetCompare_dylibloader_orig_fontconfig +#define FcLangSetContains FcLangSetContains_dylibloader_orig_fontconfig +#define FcLangSetEqual FcLangSetEqual_dylibloader_orig_fontconfig +#define FcLangSetHash FcLangSetHash_dylibloader_orig_fontconfig +#define FcLangSetGetLangs FcLangSetGetLangs_dylibloader_orig_fontconfig +#define FcLangSetUnion FcLangSetUnion_dylibloader_orig_fontconfig +#define FcLangSetSubtract FcLangSetSubtract_dylibloader_orig_fontconfig +#define FcObjectSetCreate FcObjectSetCreate_dylibloader_orig_fontconfig +#define FcObjectSetAdd FcObjectSetAdd_dylibloader_orig_fontconfig +#define FcObjectSetDestroy FcObjectSetDestroy_dylibloader_orig_fontconfig +#define FcObjectSetVaBuild FcObjectSetVaBuild_dylibloader_orig_fontconfig +#define FcObjectSetBuild FcObjectSetBuild_dylibloader_orig_fontconfig +#define FcFontSetList FcFontSetList_dylibloader_orig_fontconfig +#define FcFontList FcFontList_dylibloader_orig_fontconfig +#define FcAtomicCreate FcAtomicCreate_dylibloader_orig_fontconfig +#define FcAtomicLock FcAtomicLock_dylibloader_orig_fontconfig +#define FcAtomicNewFile FcAtomicNewFile_dylibloader_orig_fontconfig +#define FcAtomicOrigFile FcAtomicOrigFile_dylibloader_orig_fontconfig +#define FcAtomicReplaceOrig FcAtomicReplaceOrig_dylibloader_orig_fontconfig +#define FcAtomicDeleteNew FcAtomicDeleteNew_dylibloader_orig_fontconfig +#define FcAtomicUnlock FcAtomicUnlock_dylibloader_orig_fontconfig +#define FcAtomicDestroy FcAtomicDestroy_dylibloader_orig_fontconfig +#define FcFontSetMatch FcFontSetMatch_dylibloader_orig_fontconfig +#define FcFontMatch FcFontMatch_dylibloader_orig_fontconfig +#define FcFontRenderPrepare FcFontRenderPrepare_dylibloader_orig_fontconfig +#define FcFontSetSort FcFontSetSort_dylibloader_orig_fontconfig +#define FcFontSort FcFontSort_dylibloader_orig_fontconfig +#define FcFontSetSortDestroy FcFontSetSortDestroy_dylibloader_orig_fontconfig +#define FcMatrixCopy FcMatrixCopy_dylibloader_orig_fontconfig +#define FcMatrixEqual FcMatrixEqual_dylibloader_orig_fontconfig +#define FcMatrixMultiply FcMatrixMultiply_dylibloader_orig_fontconfig +#define FcMatrixRotate FcMatrixRotate_dylibloader_orig_fontconfig +#define FcMatrixScale FcMatrixScale_dylibloader_orig_fontconfig +#define FcMatrixShear FcMatrixShear_dylibloader_orig_fontconfig +#define FcNameRegisterObjectTypes FcNameRegisterObjectTypes_dylibloader_orig_fontconfig +#define FcNameUnregisterObjectTypes FcNameUnregisterObjectTypes_dylibloader_orig_fontconfig +#define FcNameGetObjectType FcNameGetObjectType_dylibloader_orig_fontconfig +#define FcNameRegisterConstants FcNameRegisterConstants_dylibloader_orig_fontconfig +#define FcNameUnregisterConstants FcNameUnregisterConstants_dylibloader_orig_fontconfig +#define FcNameGetConstant FcNameGetConstant_dylibloader_orig_fontconfig +#define FcNameConstant FcNameConstant_dylibloader_orig_fontconfig +#define FcNameParse FcNameParse_dylibloader_orig_fontconfig +#define FcNameUnparse FcNameUnparse_dylibloader_orig_fontconfig +#define FcPatternCreate FcPatternCreate_dylibloader_orig_fontconfig +#define FcPatternDuplicate FcPatternDuplicate_dylibloader_orig_fontconfig +#define FcPatternReference FcPatternReference_dylibloader_orig_fontconfig +#define FcPatternFilter FcPatternFilter_dylibloader_orig_fontconfig +#define FcValueDestroy FcValueDestroy_dylibloader_orig_fontconfig +#define FcValueEqual FcValueEqual_dylibloader_orig_fontconfig +#define FcValueSave FcValueSave_dylibloader_orig_fontconfig +#define FcPatternDestroy FcPatternDestroy_dylibloader_orig_fontconfig +#define FcPatternObjectCount FcPatternObjectCount_dylibloader_orig_fontconfig +#define FcPatternEqual FcPatternEqual_dylibloader_orig_fontconfig +#define FcPatternEqualSubset FcPatternEqualSubset_dylibloader_orig_fontconfig +#define FcPatternHash FcPatternHash_dylibloader_orig_fontconfig +#define FcPatternAdd FcPatternAdd_dylibloader_orig_fontconfig +#define FcPatternAddWeak FcPatternAddWeak_dylibloader_orig_fontconfig +#define FcPatternGet FcPatternGet_dylibloader_orig_fontconfig +#define FcPatternGetWithBinding FcPatternGetWithBinding_dylibloader_orig_fontconfig +#define FcPatternDel FcPatternDel_dylibloader_orig_fontconfig +#define FcPatternRemove FcPatternRemove_dylibloader_orig_fontconfig +#define FcPatternAddInteger FcPatternAddInteger_dylibloader_orig_fontconfig +#define FcPatternAddDouble FcPatternAddDouble_dylibloader_orig_fontconfig +#define FcPatternAddString FcPatternAddString_dylibloader_orig_fontconfig +#define FcPatternAddMatrix FcPatternAddMatrix_dylibloader_orig_fontconfig +#define FcPatternAddCharSet FcPatternAddCharSet_dylibloader_orig_fontconfig +#define FcPatternAddBool FcPatternAddBool_dylibloader_orig_fontconfig +#define FcPatternAddLangSet FcPatternAddLangSet_dylibloader_orig_fontconfig +#define FcPatternAddRange FcPatternAddRange_dylibloader_orig_fontconfig +#define FcPatternGetInteger FcPatternGetInteger_dylibloader_orig_fontconfig +#define FcPatternGetDouble FcPatternGetDouble_dylibloader_orig_fontconfig +#define FcPatternGetString FcPatternGetString_dylibloader_orig_fontconfig +#define FcPatternGetMatrix FcPatternGetMatrix_dylibloader_orig_fontconfig +#define FcPatternGetCharSet FcPatternGetCharSet_dylibloader_orig_fontconfig +#define FcPatternGetBool FcPatternGetBool_dylibloader_orig_fontconfig +#define FcPatternGetLangSet FcPatternGetLangSet_dylibloader_orig_fontconfig +#define FcPatternGetRange FcPatternGetRange_dylibloader_orig_fontconfig +#define FcPatternVaBuild FcPatternVaBuild_dylibloader_orig_fontconfig +#define FcPatternBuild FcPatternBuild_dylibloader_orig_fontconfig +#define FcPatternFormat FcPatternFormat_dylibloader_orig_fontconfig +#define FcRangeCreateDouble FcRangeCreateDouble_dylibloader_orig_fontconfig +#define FcRangeCreateInteger FcRangeCreateInteger_dylibloader_orig_fontconfig +#define FcRangeDestroy FcRangeDestroy_dylibloader_orig_fontconfig +#define FcRangeCopy FcRangeCopy_dylibloader_orig_fontconfig +#define FcRangeGetDouble FcRangeGetDouble_dylibloader_orig_fontconfig +#define FcPatternIterStart FcPatternIterStart_dylibloader_orig_fontconfig +#define FcPatternIterNext FcPatternIterNext_dylibloader_orig_fontconfig +#define FcPatternIterEqual FcPatternIterEqual_dylibloader_orig_fontconfig +#define FcPatternFindIter FcPatternFindIter_dylibloader_orig_fontconfig +#define FcPatternIterIsValid FcPatternIterIsValid_dylibloader_orig_fontconfig +#define FcPatternIterGetObject FcPatternIterGetObject_dylibloader_orig_fontconfig +#define FcPatternIterValueCount FcPatternIterValueCount_dylibloader_orig_fontconfig +#define FcPatternIterGetValue FcPatternIterGetValue_dylibloader_orig_fontconfig +#define FcWeightFromOpenType FcWeightFromOpenType_dylibloader_orig_fontconfig +#define FcWeightFromOpenTypeDouble FcWeightFromOpenTypeDouble_dylibloader_orig_fontconfig +#define FcWeightToOpenType FcWeightToOpenType_dylibloader_orig_fontconfig +#define FcWeightToOpenTypeDouble FcWeightToOpenTypeDouble_dylibloader_orig_fontconfig +#define FcStrCopy FcStrCopy_dylibloader_orig_fontconfig +#define FcStrCopyFilename FcStrCopyFilename_dylibloader_orig_fontconfig +#define FcStrPlus FcStrPlus_dylibloader_orig_fontconfig +#define FcStrFree FcStrFree_dylibloader_orig_fontconfig +#define FcStrDowncase FcStrDowncase_dylibloader_orig_fontconfig +#define FcStrCmpIgnoreCase FcStrCmpIgnoreCase_dylibloader_orig_fontconfig +#define FcStrCmp FcStrCmp_dylibloader_orig_fontconfig +#define FcStrStrIgnoreCase FcStrStrIgnoreCase_dylibloader_orig_fontconfig +#define FcStrStr FcStrStr_dylibloader_orig_fontconfig +#define FcUtf8ToUcs4 FcUtf8ToUcs4_dylibloader_orig_fontconfig +#define FcUtf8Len FcUtf8Len_dylibloader_orig_fontconfig +#define FcUcs4ToUtf8 FcUcs4ToUtf8_dylibloader_orig_fontconfig +#define FcUtf16ToUcs4 FcUtf16ToUcs4_dylibloader_orig_fontconfig +#define FcUtf16Len FcUtf16Len_dylibloader_orig_fontconfig +#define FcStrDirname FcStrDirname_dylibloader_orig_fontconfig +#define FcStrBasename FcStrBasename_dylibloader_orig_fontconfig +#define FcStrSetCreate FcStrSetCreate_dylibloader_orig_fontconfig +#define FcStrSetMember FcStrSetMember_dylibloader_orig_fontconfig +#define FcStrSetEqual FcStrSetEqual_dylibloader_orig_fontconfig +#define FcStrSetAdd FcStrSetAdd_dylibloader_orig_fontconfig +#define FcStrSetAddFilename FcStrSetAddFilename_dylibloader_orig_fontconfig +#define FcStrSetDel FcStrSetDel_dylibloader_orig_fontconfig +#define FcStrSetDestroy FcStrSetDestroy_dylibloader_orig_fontconfig +#define FcStrListCreate FcStrListCreate_dylibloader_orig_fontconfig +#define FcStrListFirst FcStrListFirst_dylibloader_orig_fontconfig +#define FcStrListNext FcStrListNext_dylibloader_orig_fontconfig +#define FcStrListDone FcStrListDone_dylibloader_orig_fontconfig +#define FcConfigParseAndLoad FcConfigParseAndLoad_dylibloader_orig_fontconfig +#define FcConfigParseAndLoadFromMemory FcConfigParseAndLoadFromMemory_dylibloader_orig_fontconfig +#include <fontconfig/fontconfig.h> +#undef FcBlanksCreate +#undef FcBlanksDestroy +#undef FcBlanksAdd +#undef FcBlanksIsMember +#undef FcCacheDir +#undef FcCacheCopySet +#undef FcCacheSubdir +#undef FcCacheNumSubdir +#undef FcCacheNumFont +#undef FcDirCacheUnlink +#undef FcDirCacheValid +#undef FcDirCacheClean +#undef FcCacheCreateTagFile +#undef FcDirCacheCreateUUID +#undef FcDirCacheDeleteUUID +#undef FcConfigHome +#undef FcConfigEnableHome +#undef FcConfigFilename +#undef FcConfigCreate +#undef FcConfigReference +#undef FcConfigDestroy +#undef FcConfigSetCurrent +#undef FcConfigGetCurrent +#undef FcConfigUptoDate +#undef FcConfigBuildFonts +#undef FcConfigGetFontDirs +#undef FcConfigGetConfigDirs +#undef FcConfigGetConfigFiles +#undef FcConfigGetCache +#undef FcConfigGetBlanks +#undef FcConfigGetCacheDirs +#undef FcConfigGetRescanInterval +#undef FcConfigSetRescanInterval +#undef FcConfigGetFonts +#undef FcConfigAppFontAddFile +#undef FcConfigAppFontAddDir +#undef FcConfigAppFontClear +#undef FcConfigSubstituteWithPat +#undef FcConfigSubstitute +#undef FcConfigGetSysRoot +#undef FcConfigSetSysRoot +#undef FcConfigFileInfoIterInit +#undef FcConfigFileInfoIterNext +#undef FcConfigFileInfoIterGet +#undef FcValuePrint +#undef FcPatternPrint +#undef FcFontSetPrint +#undef FcGetDefaultLangs +#undef FcDefaultSubstitute +#undef FcFileIsDir +#undef FcFileScan +#undef FcDirScan +#undef FcDirSave +#undef FcDirCacheLoad +#undef FcDirCacheRescan +#undef FcDirCacheRead +#undef FcDirCacheLoadFile +#undef FcDirCacheUnload +#undef FcFreeTypeQuery +#undef FcFreeTypeQueryAll +#undef FcFontSetCreate +#undef FcFontSetDestroy +#undef FcFontSetAdd +#undef FcInitLoadConfig +#undef FcInitLoadConfigAndFonts +#undef FcInit +#undef FcFini +#undef FcGetVersion +#undef FcInitReinitialize +#undef FcInitBringUptoDate +#undef FcGetLangs +#undef FcLangNormalize +#undef FcLangGetCharSet +#undef FcLangSetCreate +#undef FcLangSetDestroy +#undef FcLangSetCopy +#undef FcLangSetAdd +#undef FcLangSetDel +#undef FcLangSetHasLang +#undef FcLangSetCompare +#undef FcLangSetContains +#undef FcLangSetEqual +#undef FcLangSetHash +#undef FcLangSetGetLangs +#undef FcLangSetUnion +#undef FcLangSetSubtract +#undef FcObjectSetCreate +#undef FcObjectSetAdd +#undef FcObjectSetDestroy +#undef FcObjectSetVaBuild +#undef FcObjectSetBuild +#undef FcFontSetList +#undef FcFontList +#undef FcAtomicCreate +#undef FcAtomicLock +#undef FcAtomicNewFile +#undef FcAtomicOrigFile +#undef FcAtomicReplaceOrig +#undef FcAtomicDeleteNew +#undef FcAtomicUnlock +#undef FcAtomicDestroy +#undef FcFontSetMatch +#undef FcFontMatch +#undef FcFontRenderPrepare +#undef FcFontSetSort +#undef FcFontSort +#undef FcFontSetSortDestroy +#undef FcMatrixCopy +#undef FcMatrixEqual +#undef FcMatrixMultiply +#undef FcMatrixRotate +#undef FcMatrixScale +#undef FcMatrixShear +#undef FcNameRegisterObjectTypes +#undef FcNameUnregisterObjectTypes +#undef FcNameGetObjectType +#undef FcNameRegisterConstants +#undef FcNameUnregisterConstants +#undef FcNameGetConstant +#undef FcNameConstant +#undef FcNameParse +#undef FcNameUnparse +#undef FcPatternCreate +#undef FcPatternDuplicate +#undef FcPatternReference +#undef FcPatternFilter +#undef FcValueDestroy +#undef FcValueEqual +#undef FcValueSave +#undef FcPatternDestroy +#undef FcPatternObjectCount +#undef FcPatternEqual +#undef FcPatternEqualSubset +#undef FcPatternHash +#undef FcPatternAdd +#undef FcPatternAddWeak +#undef FcPatternGet +#undef FcPatternGetWithBinding +#undef FcPatternDel +#undef FcPatternRemove +#undef FcPatternAddInteger +#undef FcPatternAddDouble +#undef FcPatternAddString +#undef FcPatternAddMatrix +#undef FcPatternAddCharSet +#undef FcPatternAddBool +#undef FcPatternAddLangSet +#undef FcPatternAddRange +#undef FcPatternGetInteger +#undef FcPatternGetDouble +#undef FcPatternGetString +#undef FcPatternGetMatrix +#undef FcPatternGetCharSet +#undef FcPatternGetBool +#undef FcPatternGetLangSet +#undef FcPatternGetRange +#undef FcPatternVaBuild +#undef FcPatternBuild +#undef FcPatternFormat +#undef FcRangeCreateDouble +#undef FcRangeCreateInteger +#undef FcRangeDestroy +#undef FcRangeCopy +#undef FcRangeGetDouble +#undef FcPatternIterStart +#undef FcPatternIterNext +#undef FcPatternIterEqual +#undef FcPatternFindIter +#undef FcPatternIterIsValid +#undef FcPatternIterGetObject +#undef FcPatternIterValueCount +#undef FcPatternIterGetValue +#undef FcWeightFromOpenType +#undef FcWeightFromOpenTypeDouble +#undef FcWeightToOpenType +#undef FcWeightToOpenTypeDouble +#undef FcStrCopy +#undef FcStrCopyFilename +#undef FcStrPlus +#undef FcStrFree +#undef FcStrDowncase +#undef FcStrCmpIgnoreCase +#undef FcStrCmp +#undef FcStrStrIgnoreCase +#undef FcStrStr +#undef FcUtf8ToUcs4 +#undef FcUtf8Len +#undef FcUcs4ToUtf8 +#undef FcUtf16ToUcs4 +#undef FcUtf16Len +#undef FcStrDirname +#undef FcStrBasename +#undef FcStrSetCreate +#undef FcStrSetMember +#undef FcStrSetEqual +#undef FcStrSetAdd +#undef FcStrSetAddFilename +#undef FcStrSetDel +#undef FcStrSetDestroy +#undef FcStrListCreate +#undef FcStrListFirst +#undef FcStrListNext +#undef FcStrListDone +#undef FcConfigParseAndLoad +#undef FcConfigParseAndLoadFromMemory +#include <dlfcn.h> +#include <stdio.h> +FcBlanks* (*FcBlanksCreate_dylibloader_wrapper_fontconfig)( void); +void (*FcBlanksDestroy_dylibloader_wrapper_fontconfig)( FcBlanks*); +FcBool (*FcBlanksAdd_dylibloader_wrapper_fontconfig)( FcBlanks*, FcChar32); +FcBool (*FcBlanksIsMember_dylibloader_wrapper_fontconfig)( FcBlanks*, FcChar32); +const FcChar8* (*FcCacheDir_dylibloader_wrapper_fontconfig)(const FcCache*); +FcFontSet* (*FcCacheCopySet_dylibloader_wrapper_fontconfig)(const FcCache*); +const FcChar8* (*FcCacheSubdir_dylibloader_wrapper_fontconfig)(const FcCache*, int); +int (*FcCacheNumSubdir_dylibloader_wrapper_fontconfig)(const FcCache*); +int (*FcCacheNumFont_dylibloader_wrapper_fontconfig)(const FcCache*); +FcBool (*FcDirCacheUnlink_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +FcBool (*FcDirCacheValid_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcBool (*FcDirCacheClean_dylibloader_wrapper_fontconfig)(const FcChar8*, FcBool); +void (*FcCacheCreateTagFile_dylibloader_wrapper_fontconfig)(const FcConfig*); +FcBool (*FcDirCacheCreateUUID_dylibloader_wrapper_fontconfig)( FcChar8*, FcBool, FcConfig*); +FcBool (*FcDirCacheDeleteUUID_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +FcChar8* (*FcConfigHome_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcConfigEnableHome_dylibloader_wrapper_fontconfig)( FcBool); +FcChar8* (*FcConfigFilename_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcConfig* (*FcConfigCreate_dylibloader_wrapper_fontconfig)( void); +FcConfig* (*FcConfigReference_dylibloader_wrapper_fontconfig)( FcConfig*); +void (*FcConfigDestroy_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBool (*FcConfigSetCurrent_dylibloader_wrapper_fontconfig)( FcConfig*); +FcConfig* (*FcConfigGetCurrent_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcConfigUptoDate_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBool (*FcConfigBuildFonts_dylibloader_wrapper_fontconfig)( FcConfig*); +FcStrList* (*FcConfigGetFontDirs_dylibloader_wrapper_fontconfig)( FcConfig*); +FcStrList* (*FcConfigGetConfigDirs_dylibloader_wrapper_fontconfig)( FcConfig*); +FcStrList* (*FcConfigGetConfigFiles_dylibloader_wrapper_fontconfig)( FcConfig*); +FcChar8* (*FcConfigGetCache_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBlanks* (*FcConfigGetBlanks_dylibloader_wrapper_fontconfig)( FcConfig*); +FcStrList* (*FcConfigGetCacheDirs_dylibloader_wrapper_fontconfig)(const FcConfig*); +int (*FcConfigGetRescanInterval_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBool (*FcConfigSetRescanInterval_dylibloader_wrapper_fontconfig)( FcConfig*, int); +FcFontSet* (*FcConfigGetFonts_dylibloader_wrapper_fontconfig)( FcConfig*, FcSetName); +FcBool (*FcConfigAppFontAddFile_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +FcBool (*FcConfigAppFontAddDir_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +void (*FcConfigAppFontClear_dylibloader_wrapper_fontconfig)( FcConfig*); +FcBool (*FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcPattern*, FcMatchKind); +FcBool (*FcConfigSubstitute_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcMatchKind); +const FcChar8* (*FcConfigGetSysRoot_dylibloader_wrapper_fontconfig)(const FcConfig*); +void (*FcConfigSetSysRoot_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +void (*FcConfigFileInfoIterInit_dylibloader_wrapper_fontconfig)( FcConfig*, FcConfigFileInfoIter*); +FcBool (*FcConfigFileInfoIterNext_dylibloader_wrapper_fontconfig)( FcConfig*, FcConfigFileInfoIter*); +FcBool (*FcConfigFileInfoIterGet_dylibloader_wrapper_fontconfig)( FcConfig*, FcConfigFileInfoIter*, FcChar8**, FcChar8**, FcBool*); +void (*FcValuePrint_dylibloader_wrapper_fontconfig)(const FcValue); +void (*FcPatternPrint_dylibloader_wrapper_fontconfig)(const FcPattern*); +void (*FcFontSetPrint_dylibloader_wrapper_fontconfig)(const FcFontSet*); +FcStrSet* (*FcGetDefaultLangs_dylibloader_wrapper_fontconfig)( void); +void (*FcDefaultSubstitute_dylibloader_wrapper_fontconfig)( FcPattern*); +FcBool (*FcFileIsDir_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcBool (*FcFileScan_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*, FcFileCache*, FcBlanks*,const FcChar8*, FcBool); +FcBool (*FcDirScan_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*, FcFileCache*, FcBlanks*,const FcChar8*, FcBool); +FcBool (*FcDirSave_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*,const FcChar8*); +FcCache* (*FcDirCacheLoad_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*, FcChar8**); +FcCache* (*FcDirCacheRescan_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +FcCache* (*FcDirCacheRead_dylibloader_wrapper_fontconfig)(const FcChar8*, FcBool, FcConfig*); +FcCache* (*FcDirCacheLoadFile_dylibloader_wrapper_fontconfig)(const FcChar8*,struct stat*); +void (*FcDirCacheUnload_dylibloader_wrapper_fontconfig)( FcCache*); +FcPattern* (*FcFreeTypeQuery_dylibloader_wrapper_fontconfig)(const FcChar8*, unsigned int, FcBlanks*, int*); +unsigned int (*FcFreeTypeQueryAll_dylibloader_wrapper_fontconfig)(const FcChar8*, unsigned int, FcBlanks*, int*, FcFontSet*); +FcFontSet* (*FcFontSetCreate_dylibloader_wrapper_fontconfig)( void); +void (*FcFontSetDestroy_dylibloader_wrapper_fontconfig)( FcFontSet*); +FcBool (*FcFontSetAdd_dylibloader_wrapper_fontconfig)( FcFontSet*, FcPattern*); +FcConfig* (*FcInitLoadConfig_dylibloader_wrapper_fontconfig)( void); +FcConfig* (*FcInitLoadConfigAndFonts_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcInit_dylibloader_wrapper_fontconfig)( void); +void (*FcFini_dylibloader_wrapper_fontconfig)( void); +int (*FcGetVersion_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcInitReinitialize_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcInitBringUptoDate_dylibloader_wrapper_fontconfig)( void); +FcStrSet* (*FcGetLangs_dylibloader_wrapper_fontconfig)( void); +FcChar8* (*FcLangNormalize_dylibloader_wrapper_fontconfig)(const FcChar8*); +const FcCharSet* (*FcLangGetCharSet_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcLangSet* (*FcLangSetCreate_dylibloader_wrapper_fontconfig)( void); +void (*FcLangSetDestroy_dylibloader_wrapper_fontconfig)( FcLangSet*); +FcLangSet* (*FcLangSetCopy_dylibloader_wrapper_fontconfig)(const FcLangSet*); +FcBool (*FcLangSetAdd_dylibloader_wrapper_fontconfig)( FcLangSet*,const FcChar8*); +FcBool (*FcLangSetDel_dylibloader_wrapper_fontconfig)( FcLangSet*,const FcChar8*); +FcLangResult (*FcLangSetHasLang_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcChar8*); +FcLangResult (*FcLangSetCompare_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcBool (*FcLangSetContains_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcBool (*FcLangSetEqual_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcChar32 (*FcLangSetHash_dylibloader_wrapper_fontconfig)(const FcLangSet*); +FcStrSet* (*FcLangSetGetLangs_dylibloader_wrapper_fontconfig)(const FcLangSet*); +FcLangSet* (*FcLangSetUnion_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcLangSet* (*FcLangSetSubtract_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +FcObjectSet* (*FcObjectSetCreate_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcObjectSetAdd_dylibloader_wrapper_fontconfig)( FcObjectSet*,const char*); +void (*FcObjectSetDestroy_dylibloader_wrapper_fontconfig)( FcObjectSet*); +FcObjectSet* (*FcObjectSetVaBuild_dylibloader_wrapper_fontconfig)(const char*, va_list); +FcObjectSet* (*FcObjectSetBuild_dylibloader_wrapper_fontconfig)(const char*,...); +FcFontSet* (*FcFontSetList_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcObjectSet*); +FcFontSet* (*FcFontList_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcObjectSet*); +FcAtomic* (*FcAtomicCreate_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcBool (*FcAtomicLock_dylibloader_wrapper_fontconfig)( FcAtomic*); +FcChar8* (*FcAtomicNewFile_dylibloader_wrapper_fontconfig)( FcAtomic*); +FcChar8* (*FcAtomicOrigFile_dylibloader_wrapper_fontconfig)( FcAtomic*); +FcBool (*FcAtomicReplaceOrig_dylibloader_wrapper_fontconfig)( FcAtomic*); +void (*FcAtomicDeleteNew_dylibloader_wrapper_fontconfig)( FcAtomic*); +void (*FcAtomicUnlock_dylibloader_wrapper_fontconfig)( FcAtomic*); +void (*FcAtomicDestroy_dylibloader_wrapper_fontconfig)( FcAtomic*); +FcPattern* (*FcFontSetMatch_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcResult*); +FcPattern* (*FcFontMatch_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcResult*); +FcPattern* (*FcFontRenderPrepare_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcPattern*); +FcFontSet* (*FcFontSetSort_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcBool, FcCharSet**, FcResult*); +FcFontSet* (*FcFontSort_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcBool, FcCharSet**, FcResult*); +void (*FcFontSetSortDestroy_dylibloader_wrapper_fontconfig)( FcFontSet*); +FcMatrix* (*FcMatrixCopy_dylibloader_wrapper_fontconfig)(const FcMatrix*); +FcBool (*FcMatrixEqual_dylibloader_wrapper_fontconfig)(const FcMatrix*,const FcMatrix*); +void (*FcMatrixMultiply_dylibloader_wrapper_fontconfig)( FcMatrix*,const FcMatrix*,const FcMatrix*); +void (*FcMatrixRotate_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +void (*FcMatrixScale_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +void (*FcMatrixShear_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +FcBool (*FcNameRegisterObjectTypes_dylibloader_wrapper_fontconfig)(const FcObjectType*, int); +FcBool (*FcNameUnregisterObjectTypes_dylibloader_wrapper_fontconfig)(const FcObjectType*, int); +const FcObjectType* (*FcNameGetObjectType_dylibloader_wrapper_fontconfig)(const char*); +FcBool (*FcNameRegisterConstants_dylibloader_wrapper_fontconfig)(const FcConstant*, int); +FcBool (*FcNameUnregisterConstants_dylibloader_wrapper_fontconfig)(const FcConstant*, int); +const FcConstant* (*FcNameGetConstant_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcBool (*FcNameConstant_dylibloader_wrapper_fontconfig)(const FcChar8*, int*); +FcPattern* (*FcNameParse_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcChar8* (*FcNameUnparse_dylibloader_wrapper_fontconfig)( FcPattern*); +FcPattern* (*FcPatternCreate_dylibloader_wrapper_fontconfig)( void); +FcPattern* (*FcPatternDuplicate_dylibloader_wrapper_fontconfig)(const FcPattern*); +void (*FcPatternReference_dylibloader_wrapper_fontconfig)( FcPattern*); +FcPattern* (*FcPatternFilter_dylibloader_wrapper_fontconfig)( FcPattern*,const FcObjectSet*); +void (*FcValueDestroy_dylibloader_wrapper_fontconfig)( FcValue); +FcBool (*FcValueEqual_dylibloader_wrapper_fontconfig)( FcValue, FcValue); +FcValue (*FcValueSave_dylibloader_wrapper_fontconfig)( FcValue); +void (*FcPatternDestroy_dylibloader_wrapper_fontconfig)( FcPattern*); +int (*FcPatternObjectCount_dylibloader_wrapper_fontconfig)(const FcPattern*); +FcBool (*FcPatternEqual_dylibloader_wrapper_fontconfig)(const FcPattern*,const FcPattern*); +FcBool (*FcPatternEqualSubset_dylibloader_wrapper_fontconfig)(const FcPattern*,const FcPattern*,const FcObjectSet*); +FcChar32 (*FcPatternHash_dylibloader_wrapper_fontconfig)(const FcPattern*); +FcBool (*FcPatternAdd_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcValue, FcBool); +FcBool (*FcPatternAddWeak_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcValue, FcBool); +FcResult (*FcPatternGet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcValue*); +FcResult (*FcPatternGetWithBinding_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcValue*, FcValueBinding*); +FcBool (*FcPatternDel_dylibloader_wrapper_fontconfig)( FcPattern*,const char*); +FcBool (*FcPatternRemove_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, int); +FcBool (*FcPatternAddInteger_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, int); +FcBool (*FcPatternAddDouble_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, double); +FcBool (*FcPatternAddString_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcChar8*); +FcBool (*FcPatternAddMatrix_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcMatrix*); +FcBool (*FcPatternAddCharSet_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcCharSet*); +FcBool (*FcPatternAddBool_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcBool); +FcBool (*FcPatternAddLangSet_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcLangSet*); +FcBool (*FcPatternAddRange_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcRange*); +FcResult (*FcPatternGetInteger_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, int*); +FcResult (*FcPatternGetDouble_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, double*); +FcResult (*FcPatternGetString_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcChar8**); +FcResult (*FcPatternGetMatrix_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcMatrix**); +FcResult (*FcPatternGetCharSet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcCharSet**); +FcResult (*FcPatternGetBool_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcBool*); +FcResult (*FcPatternGetLangSet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcLangSet**); +FcResult (*FcPatternGetRange_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcRange**); +FcPattern* (*FcPatternVaBuild_dylibloader_wrapper_fontconfig)( FcPattern*, va_list); +FcPattern* (*FcPatternBuild_dylibloader_wrapper_fontconfig)( FcPattern*,...); +FcChar8* (*FcPatternFormat_dylibloader_wrapper_fontconfig)( FcPattern*,const FcChar8*); +FcRange* (*FcRangeCreateDouble_dylibloader_wrapper_fontconfig)( double, double); +FcRange* (*FcRangeCreateInteger_dylibloader_wrapper_fontconfig)( FcChar32, FcChar32); +void (*FcRangeDestroy_dylibloader_wrapper_fontconfig)( FcRange*); +FcRange* (*FcRangeCopy_dylibloader_wrapper_fontconfig)(const FcRange*); +FcBool (*FcRangeGetDouble_dylibloader_wrapper_fontconfig)(const FcRange*, double*, double*); +void (*FcPatternIterStart_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +FcBool (*FcPatternIterNext_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +FcBool (*FcPatternIterEqual_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*,const FcPattern*, FcPatternIter*); +FcBool (*FcPatternFindIter_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*,const char*); +FcBool (*FcPatternIterIsValid_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +const char* (*FcPatternIterGetObject_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +int (*FcPatternIterValueCount_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +FcResult (*FcPatternIterGetValue_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*, int, FcValue*, FcValueBinding*); +int (*FcWeightFromOpenType_dylibloader_wrapper_fontconfig)( int); +double (*FcWeightFromOpenTypeDouble_dylibloader_wrapper_fontconfig)( double); +int (*FcWeightToOpenType_dylibloader_wrapper_fontconfig)( int); +double (*FcWeightToOpenTypeDouble_dylibloader_wrapper_fontconfig)( double); +FcChar8* (*FcStrCopy_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcChar8* (*FcStrCopyFilename_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcChar8* (*FcStrPlus_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +void (*FcStrFree_dylibloader_wrapper_fontconfig)( FcChar8*); +FcChar8* (*FcStrDowncase_dylibloader_wrapper_fontconfig)(const FcChar8*); +int (*FcStrCmpIgnoreCase_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +int (*FcStrCmp_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +const FcChar8* (*FcStrStrIgnoreCase_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +const FcChar8* (*FcStrStr_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +int (*FcUtf8ToUcs4_dylibloader_wrapper_fontconfig)(const FcChar8*, FcChar32*, int); +FcBool (*FcUtf8Len_dylibloader_wrapper_fontconfig)(const FcChar8*, int, int*, int*); +int (*FcUcs4ToUtf8_dylibloader_wrapper_fontconfig)( FcChar32, FcChar8 [6]); +int (*FcUtf16ToUcs4_dylibloader_wrapper_fontconfig)(const FcChar8*, FcEndian, FcChar32*, int); +FcBool (*FcUtf16Len_dylibloader_wrapper_fontconfig)(const FcChar8*, FcEndian, int, int*, int*); +FcChar8* (*FcStrDirname_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcChar8* (*FcStrBasename_dylibloader_wrapper_fontconfig)(const FcChar8*); +FcStrSet* (*FcStrSetCreate_dylibloader_wrapper_fontconfig)( void); +FcBool (*FcStrSetMember_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +FcBool (*FcStrSetEqual_dylibloader_wrapper_fontconfig)( FcStrSet*, FcStrSet*); +FcBool (*FcStrSetAdd_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +FcBool (*FcStrSetAddFilename_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +FcBool (*FcStrSetDel_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +void (*FcStrSetDestroy_dylibloader_wrapper_fontconfig)( FcStrSet*); +FcStrList* (*FcStrListCreate_dylibloader_wrapper_fontconfig)( FcStrSet*); +void (*FcStrListFirst_dylibloader_wrapper_fontconfig)( FcStrList*); +FcChar8* (*FcStrListNext_dylibloader_wrapper_fontconfig)( FcStrList*); +void (*FcStrListDone_dylibloader_wrapper_fontconfig)( FcStrList*); +FcBool (*FcConfigParseAndLoad_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*, FcBool); +FcBool (*FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*, FcBool); +int initialize_fontconfig(int verbose) { + void *handle; + char *error; + handle = dlopen("libfontconfig.so", RTLD_LAZY); + if (!handle) { + if (verbose) { + fprintf(stderr, "%s\n", dlerror()); + } + return(1); + } + dlerror(); +// FcBlanksCreate + *(void **) (&FcBlanksCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcBlanksCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcBlanksDestroy + *(void **) (&FcBlanksDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcBlanksDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcBlanksAdd + *(void **) (&FcBlanksAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcBlanksAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcBlanksIsMember + *(void **) (&FcBlanksIsMember_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcBlanksIsMember"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheDir + *(void **) (&FcCacheDir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheDir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheCopySet + *(void **) (&FcCacheCopySet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheCopySet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheSubdir + *(void **) (&FcCacheSubdir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheSubdir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheNumSubdir + *(void **) (&FcCacheNumSubdir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheNumSubdir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheNumFont + *(void **) (&FcCacheNumFont_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheNumFont"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheUnlink + *(void **) (&FcDirCacheUnlink_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheUnlink"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheValid + *(void **) (&FcDirCacheValid_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheValid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheClean + *(void **) (&FcDirCacheClean_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheClean"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcCacheCreateTagFile + *(void **) (&FcCacheCreateTagFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcCacheCreateTagFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheCreateUUID + *(void **) (&FcDirCacheCreateUUID_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheCreateUUID"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheDeleteUUID + *(void **) (&FcDirCacheDeleteUUID_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheDeleteUUID"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigHome + *(void **) (&FcConfigHome_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigHome"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigEnableHome + *(void **) (&FcConfigEnableHome_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigEnableHome"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigFilename + *(void **) (&FcConfigFilename_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigFilename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigCreate + *(void **) (&FcConfigCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigReference + *(void **) (&FcConfigReference_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigReference"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigDestroy + *(void **) (&FcConfigDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSetCurrent + *(void **) (&FcConfigSetCurrent_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSetCurrent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetCurrent + *(void **) (&FcConfigGetCurrent_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetCurrent"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigUptoDate + *(void **) (&FcConfigUptoDate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigUptoDate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigBuildFonts + *(void **) (&FcConfigBuildFonts_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigBuildFonts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetFontDirs + *(void **) (&FcConfigGetFontDirs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetFontDirs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetConfigDirs + *(void **) (&FcConfigGetConfigDirs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetConfigDirs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetConfigFiles + *(void **) (&FcConfigGetConfigFiles_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetConfigFiles"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetCache + *(void **) (&FcConfigGetCache_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetCache"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetBlanks + *(void **) (&FcConfigGetBlanks_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetBlanks"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetCacheDirs + *(void **) (&FcConfigGetCacheDirs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetCacheDirs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetRescanInterval + *(void **) (&FcConfigGetRescanInterval_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetRescanInterval"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSetRescanInterval + *(void **) (&FcConfigSetRescanInterval_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSetRescanInterval"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetFonts + *(void **) (&FcConfigGetFonts_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetFonts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigAppFontAddFile + *(void **) (&FcConfigAppFontAddFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigAppFontAddFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigAppFontAddDir + *(void **) (&FcConfigAppFontAddDir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigAppFontAddDir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigAppFontClear + *(void **) (&FcConfigAppFontClear_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigAppFontClear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSubstituteWithPat + *(void **) (&FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSubstituteWithPat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSubstitute + *(void **) (&FcConfigSubstitute_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSubstitute"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigGetSysRoot + *(void **) (&FcConfigGetSysRoot_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigGetSysRoot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigSetSysRoot + *(void **) (&FcConfigSetSysRoot_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigSetSysRoot"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigFileInfoIterInit + *(void **) (&FcConfigFileInfoIterInit_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigFileInfoIterInit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigFileInfoIterNext + *(void **) (&FcConfigFileInfoIterNext_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigFileInfoIterNext"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigFileInfoIterGet + *(void **) (&FcConfigFileInfoIterGet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigFileInfoIterGet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcValuePrint + *(void **) (&FcValuePrint_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValuePrint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternPrint + *(void **) (&FcPatternPrint_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternPrint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetPrint + *(void **) (&FcFontSetPrint_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetPrint"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcGetDefaultLangs + *(void **) (&FcGetDefaultLangs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcGetDefaultLangs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDefaultSubstitute + *(void **) (&FcDefaultSubstitute_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDefaultSubstitute"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFileIsDir + *(void **) (&FcFileIsDir_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFileIsDir"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFileScan + *(void **) (&FcFileScan_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFileScan"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirScan + *(void **) (&FcDirScan_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirScan"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirSave + *(void **) (&FcDirSave_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirSave"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheLoad + *(void **) (&FcDirCacheLoad_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheLoad"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheRescan + *(void **) (&FcDirCacheRescan_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheRescan"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheRead + *(void **) (&FcDirCacheRead_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheRead"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheLoadFile + *(void **) (&FcDirCacheLoadFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheLoadFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcDirCacheUnload + *(void **) (&FcDirCacheUnload_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcDirCacheUnload"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFreeTypeQuery + *(void **) (&FcFreeTypeQuery_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFreeTypeQuery"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFreeTypeQueryAll + *(void **) (&FcFreeTypeQueryAll_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFreeTypeQueryAll"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetCreate + *(void **) (&FcFontSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetDestroy + *(void **) (&FcFontSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetAdd + *(void **) (&FcFontSetAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInitLoadConfig + *(void **) (&FcInitLoadConfig_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInitLoadConfig"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInitLoadConfigAndFonts + *(void **) (&FcInitLoadConfigAndFonts_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInitLoadConfigAndFonts"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInit + *(void **) (&FcInit_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInit"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFini + *(void **) (&FcFini_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFini"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcGetVersion + *(void **) (&FcGetVersion_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcGetVersion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInitReinitialize + *(void **) (&FcInitReinitialize_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInitReinitialize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcInitBringUptoDate + *(void **) (&FcInitBringUptoDate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcInitBringUptoDate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcGetLangs + *(void **) (&FcGetLangs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcGetLangs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangNormalize + *(void **) (&FcLangNormalize_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangNormalize"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangGetCharSet + *(void **) (&FcLangGetCharSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangGetCharSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetCreate + *(void **) (&FcLangSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetDestroy + *(void **) (&FcLangSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetCopy + *(void **) (&FcLangSetCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetAdd + *(void **) (&FcLangSetAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetDel + *(void **) (&FcLangSetDel_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetDel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetHasLang + *(void **) (&FcLangSetHasLang_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetHasLang"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetCompare + *(void **) (&FcLangSetCompare_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetCompare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetContains + *(void **) (&FcLangSetContains_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetContains"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetEqual + *(void **) (&FcLangSetEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetHash + *(void **) (&FcLangSetHash_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetHash"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetGetLangs + *(void **) (&FcLangSetGetLangs_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetGetLangs"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetUnion + *(void **) (&FcLangSetUnion_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetUnion"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcLangSetSubtract + *(void **) (&FcLangSetSubtract_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcLangSetSubtract"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetCreate + *(void **) (&FcObjectSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetAdd + *(void **) (&FcObjectSetAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetDestroy + *(void **) (&FcObjectSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetVaBuild + *(void **) (&FcObjectSetVaBuild_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetVaBuild"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcObjectSetBuild + *(void **) (&FcObjectSetBuild_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcObjectSetBuild"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetList + *(void **) (&FcFontSetList_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontList + *(void **) (&FcFontList_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontList"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicCreate + *(void **) (&FcAtomicCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicLock + *(void **) (&FcAtomicLock_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicLock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicNewFile + *(void **) (&FcAtomicNewFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicNewFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicOrigFile + *(void **) (&FcAtomicOrigFile_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicOrigFile"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicReplaceOrig + *(void **) (&FcAtomicReplaceOrig_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicReplaceOrig"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicDeleteNew + *(void **) (&FcAtomicDeleteNew_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicDeleteNew"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicUnlock + *(void **) (&FcAtomicUnlock_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicUnlock"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcAtomicDestroy + *(void **) (&FcAtomicDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcAtomicDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetMatch + *(void **) (&FcFontSetMatch_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetMatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontMatch + *(void **) (&FcFontMatch_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontMatch"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontRenderPrepare + *(void **) (&FcFontRenderPrepare_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontRenderPrepare"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetSort + *(void **) (&FcFontSetSort_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetSort"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSort + *(void **) (&FcFontSort_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSort"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcFontSetSortDestroy + *(void **) (&FcFontSetSortDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcFontSetSortDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixCopy + *(void **) (&FcMatrixCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixEqual + *(void **) (&FcMatrixEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixMultiply + *(void **) (&FcMatrixMultiply_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixMultiply"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixRotate + *(void **) (&FcMatrixRotate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixRotate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixScale + *(void **) (&FcMatrixScale_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixScale"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcMatrixShear + *(void **) (&FcMatrixShear_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcMatrixShear"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameRegisterObjectTypes + *(void **) (&FcNameRegisterObjectTypes_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameRegisterObjectTypes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameUnregisterObjectTypes + *(void **) (&FcNameUnregisterObjectTypes_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameUnregisterObjectTypes"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameGetObjectType + *(void **) (&FcNameGetObjectType_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameGetObjectType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameRegisterConstants + *(void **) (&FcNameRegisterConstants_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameRegisterConstants"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameUnregisterConstants + *(void **) (&FcNameUnregisterConstants_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameUnregisterConstants"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameGetConstant + *(void **) (&FcNameGetConstant_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameGetConstant"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameConstant + *(void **) (&FcNameConstant_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameConstant"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameParse + *(void **) (&FcNameParse_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameParse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcNameUnparse + *(void **) (&FcNameUnparse_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcNameUnparse"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternCreate + *(void **) (&FcPatternCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternDuplicate + *(void **) (&FcPatternDuplicate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternDuplicate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternReference + *(void **) (&FcPatternReference_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternReference"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternFilter + *(void **) (&FcPatternFilter_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternFilter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcValueDestroy + *(void **) (&FcValueDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValueDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcValueEqual + *(void **) (&FcValueEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValueEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcValueSave + *(void **) (&FcValueSave_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcValueSave"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternDestroy + *(void **) (&FcPatternDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternObjectCount + *(void **) (&FcPatternObjectCount_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternObjectCount"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternEqual + *(void **) (&FcPatternEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternEqualSubset + *(void **) (&FcPatternEqualSubset_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternEqualSubset"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternHash + *(void **) (&FcPatternHash_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternHash"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAdd + *(void **) (&FcPatternAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddWeak + *(void **) (&FcPatternAddWeak_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddWeak"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGet + *(void **) (&FcPatternGet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetWithBinding + *(void **) (&FcPatternGetWithBinding_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetWithBinding"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternDel + *(void **) (&FcPatternDel_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternDel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternRemove + *(void **) (&FcPatternRemove_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternRemove"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddInteger + *(void **) (&FcPatternAddInteger_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddInteger"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddDouble + *(void **) (&FcPatternAddDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddString + *(void **) (&FcPatternAddString_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddMatrix + *(void **) (&FcPatternAddMatrix_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddMatrix"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddCharSet + *(void **) (&FcPatternAddCharSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddCharSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddBool + *(void **) (&FcPatternAddBool_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddBool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddLangSet + *(void **) (&FcPatternAddLangSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddLangSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternAddRange + *(void **) (&FcPatternAddRange_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternAddRange"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetInteger + *(void **) (&FcPatternGetInteger_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetInteger"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetDouble + *(void **) (&FcPatternGetDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetString + *(void **) (&FcPatternGetString_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetString"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetMatrix + *(void **) (&FcPatternGetMatrix_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetMatrix"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetCharSet + *(void **) (&FcPatternGetCharSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetCharSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetBool + *(void **) (&FcPatternGetBool_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetBool"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetLangSet + *(void **) (&FcPatternGetLangSet_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetLangSet"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternGetRange + *(void **) (&FcPatternGetRange_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternGetRange"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternVaBuild + *(void **) (&FcPatternVaBuild_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternVaBuild"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternBuild + *(void **) (&FcPatternBuild_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternBuild"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternFormat + *(void **) (&FcPatternFormat_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternFormat"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeCreateDouble + *(void **) (&FcRangeCreateDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeCreateDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeCreateInteger + *(void **) (&FcRangeCreateInteger_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeCreateInteger"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeDestroy + *(void **) (&FcRangeDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeCopy + *(void **) (&FcRangeCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcRangeGetDouble + *(void **) (&FcRangeGetDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcRangeGetDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternIterStart + *(void **) (&FcPatternIterStart_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternIterStart"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternIterNext + *(void **) (&FcPatternIterNext_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternIterNext"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternIterEqual + *(void **) (&FcPatternIterEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternIterEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternFindIter + *(void **) (&FcPatternFindIter_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternFindIter"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternIterIsValid + *(void **) (&FcPatternIterIsValid_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternIterIsValid"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternIterGetObject + *(void **) (&FcPatternIterGetObject_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternIterGetObject"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternIterValueCount + *(void **) (&FcPatternIterValueCount_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternIterValueCount"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcPatternIterGetValue + *(void **) (&FcPatternIterGetValue_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcPatternIterGetValue"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcWeightFromOpenType + *(void **) (&FcWeightFromOpenType_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcWeightFromOpenType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcWeightFromOpenTypeDouble + *(void **) (&FcWeightFromOpenTypeDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcWeightFromOpenTypeDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcWeightToOpenType + *(void **) (&FcWeightToOpenType_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcWeightToOpenType"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcWeightToOpenTypeDouble + *(void **) (&FcWeightToOpenTypeDouble_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcWeightToOpenTypeDouble"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrCopy + *(void **) (&FcStrCopy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrCopy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrCopyFilename + *(void **) (&FcStrCopyFilename_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrCopyFilename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrPlus + *(void **) (&FcStrPlus_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrPlus"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrFree + *(void **) (&FcStrFree_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrFree"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrDowncase + *(void **) (&FcStrDowncase_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrDowncase"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrCmpIgnoreCase + *(void **) (&FcStrCmpIgnoreCase_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrCmpIgnoreCase"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrCmp + *(void **) (&FcStrCmp_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrCmp"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrStrIgnoreCase + *(void **) (&FcStrStrIgnoreCase_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrStrIgnoreCase"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrStr + *(void **) (&FcStrStr_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrStr"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUtf8ToUcs4 + *(void **) (&FcUtf8ToUcs4_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUtf8ToUcs4"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUtf8Len + *(void **) (&FcUtf8Len_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUtf8Len"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUcs4ToUtf8 + *(void **) (&FcUcs4ToUtf8_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUcs4ToUtf8"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUtf16ToUcs4 + *(void **) (&FcUtf16ToUcs4_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUtf16ToUcs4"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcUtf16Len + *(void **) (&FcUtf16Len_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcUtf16Len"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrDirname + *(void **) (&FcStrDirname_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrDirname"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrBasename + *(void **) (&FcStrBasename_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrBasename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetCreate + *(void **) (&FcStrSetCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetMember + *(void **) (&FcStrSetMember_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetMember"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetEqual + *(void **) (&FcStrSetEqual_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetEqual"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetAdd + *(void **) (&FcStrSetAdd_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetAdd"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetAddFilename + *(void **) (&FcStrSetAddFilename_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetAddFilename"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetDel + *(void **) (&FcStrSetDel_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetDel"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrSetDestroy + *(void **) (&FcStrSetDestroy_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrSetDestroy"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrListCreate + *(void **) (&FcStrListCreate_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrListCreate"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrListFirst + *(void **) (&FcStrListFirst_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrListFirst"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrListNext + *(void **) (&FcStrListNext_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrListNext"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcStrListDone + *(void **) (&FcStrListDone_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcStrListDone"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigParseAndLoad + *(void **) (&FcConfigParseAndLoad_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigParseAndLoad"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +// FcConfigParseAndLoadFromMemory + *(void **) (&FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig) = dlsym(handle, "FcConfigParseAndLoadFromMemory"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } +return 0; +} diff --git a/platform/linuxbsd/fontconfig-so_wrap.h b/platform/linuxbsd/fontconfig-so_wrap.h new file mode 100644 index 0000000000..ba9006f945 --- /dev/null +++ b/platform/linuxbsd/fontconfig-so_wrap.h @@ -0,0 +1,838 @@ +#ifndef DYLIBLOAD_WRAPPER_FONTCONFIG +#define DYLIBLOAD_WRAPPER_FONTCONFIG +// This file is generated. Do not edit! +// see https://github.com/hpvb/dynload-wrapper for details +// generated by ./generate-wrapper.py 0.3 on 2022-07-27 17:50:40 +// flags: ./generate-wrapper.py --include /usr/include/fontconfig/fontconfig.h --sys-include <fontconfig/fontconfig.h> --soname libfontconfig.so --init-name fontconfig --output-header fontconfig-so_wrap.h --output-implementation fontconfig-so_wrap.c --omit-prefix FcCharSet +// +#include <stdint.h> + +#define FcBlanksCreate FcBlanksCreate_dylibloader_orig_fontconfig +#define FcBlanksDestroy FcBlanksDestroy_dylibloader_orig_fontconfig +#define FcBlanksAdd FcBlanksAdd_dylibloader_orig_fontconfig +#define FcBlanksIsMember FcBlanksIsMember_dylibloader_orig_fontconfig +#define FcCacheDir FcCacheDir_dylibloader_orig_fontconfig +#define FcCacheCopySet FcCacheCopySet_dylibloader_orig_fontconfig +#define FcCacheSubdir FcCacheSubdir_dylibloader_orig_fontconfig +#define FcCacheNumSubdir FcCacheNumSubdir_dylibloader_orig_fontconfig +#define FcCacheNumFont FcCacheNumFont_dylibloader_orig_fontconfig +#define FcDirCacheUnlink FcDirCacheUnlink_dylibloader_orig_fontconfig +#define FcDirCacheValid FcDirCacheValid_dylibloader_orig_fontconfig +#define FcDirCacheClean FcDirCacheClean_dylibloader_orig_fontconfig +#define FcCacheCreateTagFile FcCacheCreateTagFile_dylibloader_orig_fontconfig +#define FcDirCacheCreateUUID FcDirCacheCreateUUID_dylibloader_orig_fontconfig +#define FcDirCacheDeleteUUID FcDirCacheDeleteUUID_dylibloader_orig_fontconfig +#define FcConfigHome FcConfigHome_dylibloader_orig_fontconfig +#define FcConfigEnableHome FcConfigEnableHome_dylibloader_orig_fontconfig +#define FcConfigFilename FcConfigFilename_dylibloader_orig_fontconfig +#define FcConfigCreate FcConfigCreate_dylibloader_orig_fontconfig +#define FcConfigReference FcConfigReference_dylibloader_orig_fontconfig +#define FcConfigDestroy FcConfigDestroy_dylibloader_orig_fontconfig +#define FcConfigSetCurrent FcConfigSetCurrent_dylibloader_orig_fontconfig +#define FcConfigGetCurrent FcConfigGetCurrent_dylibloader_orig_fontconfig +#define FcConfigUptoDate FcConfigUptoDate_dylibloader_orig_fontconfig +#define FcConfigBuildFonts FcConfigBuildFonts_dylibloader_orig_fontconfig +#define FcConfigGetFontDirs FcConfigGetFontDirs_dylibloader_orig_fontconfig +#define FcConfigGetConfigDirs FcConfigGetConfigDirs_dylibloader_orig_fontconfig +#define FcConfigGetConfigFiles FcConfigGetConfigFiles_dylibloader_orig_fontconfig +#define FcConfigGetCache FcConfigGetCache_dylibloader_orig_fontconfig +#define FcConfigGetBlanks FcConfigGetBlanks_dylibloader_orig_fontconfig +#define FcConfigGetCacheDirs FcConfigGetCacheDirs_dylibloader_orig_fontconfig +#define FcConfigGetRescanInterval FcConfigGetRescanInterval_dylibloader_orig_fontconfig +#define FcConfigSetRescanInterval FcConfigSetRescanInterval_dylibloader_orig_fontconfig +#define FcConfigGetFonts FcConfigGetFonts_dylibloader_orig_fontconfig +#define FcConfigAppFontAddFile FcConfigAppFontAddFile_dylibloader_orig_fontconfig +#define FcConfigAppFontAddDir FcConfigAppFontAddDir_dylibloader_orig_fontconfig +#define FcConfigAppFontClear FcConfigAppFontClear_dylibloader_orig_fontconfig +#define FcConfigSubstituteWithPat FcConfigSubstituteWithPat_dylibloader_orig_fontconfig +#define FcConfigSubstitute FcConfigSubstitute_dylibloader_orig_fontconfig +#define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_orig_fontconfig +#define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_orig_fontconfig +#define FcConfigFileInfoIterInit FcConfigFileInfoIterInit_dylibloader_orig_fontconfig +#define FcConfigFileInfoIterNext FcConfigFileInfoIterNext_dylibloader_orig_fontconfig +#define FcConfigFileInfoIterGet FcConfigFileInfoIterGet_dylibloader_orig_fontconfig +#define FcValuePrint FcValuePrint_dylibloader_orig_fontconfig +#define FcPatternPrint FcPatternPrint_dylibloader_orig_fontconfig +#define FcFontSetPrint FcFontSetPrint_dylibloader_orig_fontconfig +#define FcGetDefaultLangs FcGetDefaultLangs_dylibloader_orig_fontconfig +#define FcDefaultSubstitute FcDefaultSubstitute_dylibloader_orig_fontconfig +#define FcFileIsDir FcFileIsDir_dylibloader_orig_fontconfig +#define FcFileScan FcFileScan_dylibloader_orig_fontconfig +#define FcDirScan FcDirScan_dylibloader_orig_fontconfig +#define FcDirSave FcDirSave_dylibloader_orig_fontconfig +#define FcDirCacheLoad FcDirCacheLoad_dylibloader_orig_fontconfig +#define FcDirCacheRescan FcDirCacheRescan_dylibloader_orig_fontconfig +#define FcDirCacheRead FcDirCacheRead_dylibloader_orig_fontconfig +#define FcDirCacheLoadFile FcDirCacheLoadFile_dylibloader_orig_fontconfig +#define FcDirCacheUnload FcDirCacheUnload_dylibloader_orig_fontconfig +#define FcFreeTypeQuery FcFreeTypeQuery_dylibloader_orig_fontconfig +#define FcFreeTypeQueryAll FcFreeTypeQueryAll_dylibloader_orig_fontconfig +#define FcFontSetCreate FcFontSetCreate_dylibloader_orig_fontconfig +#define FcFontSetDestroy FcFontSetDestroy_dylibloader_orig_fontconfig +#define FcFontSetAdd FcFontSetAdd_dylibloader_orig_fontconfig +#define FcInitLoadConfig FcInitLoadConfig_dylibloader_orig_fontconfig +#define FcInitLoadConfigAndFonts FcInitLoadConfigAndFonts_dylibloader_orig_fontconfig +#define FcInit FcInit_dylibloader_orig_fontconfig +#define FcFini FcFini_dylibloader_orig_fontconfig +#define FcGetVersion FcGetVersion_dylibloader_orig_fontconfig +#define FcInitReinitialize FcInitReinitialize_dylibloader_orig_fontconfig +#define FcInitBringUptoDate FcInitBringUptoDate_dylibloader_orig_fontconfig +#define FcGetLangs FcGetLangs_dylibloader_orig_fontconfig +#define FcLangNormalize FcLangNormalize_dylibloader_orig_fontconfig +#define FcLangGetCharSet FcLangGetCharSet_dylibloader_orig_fontconfig +#define FcLangSetCreate FcLangSetCreate_dylibloader_orig_fontconfig +#define FcLangSetDestroy FcLangSetDestroy_dylibloader_orig_fontconfig +#define FcLangSetCopy FcLangSetCopy_dylibloader_orig_fontconfig +#define FcLangSetAdd FcLangSetAdd_dylibloader_orig_fontconfig +#define FcLangSetDel FcLangSetDel_dylibloader_orig_fontconfig +#define FcLangSetHasLang FcLangSetHasLang_dylibloader_orig_fontconfig +#define FcLangSetCompare FcLangSetCompare_dylibloader_orig_fontconfig +#define FcLangSetContains FcLangSetContains_dylibloader_orig_fontconfig +#define FcLangSetEqual FcLangSetEqual_dylibloader_orig_fontconfig +#define FcLangSetHash FcLangSetHash_dylibloader_orig_fontconfig +#define FcLangSetGetLangs FcLangSetGetLangs_dylibloader_orig_fontconfig +#define FcLangSetUnion FcLangSetUnion_dylibloader_orig_fontconfig +#define FcLangSetSubtract FcLangSetSubtract_dylibloader_orig_fontconfig +#define FcObjectSetCreate FcObjectSetCreate_dylibloader_orig_fontconfig +#define FcObjectSetAdd FcObjectSetAdd_dylibloader_orig_fontconfig +#define FcObjectSetDestroy FcObjectSetDestroy_dylibloader_orig_fontconfig +#define FcObjectSetVaBuild FcObjectSetVaBuild_dylibloader_orig_fontconfig +#define FcObjectSetBuild FcObjectSetBuild_dylibloader_orig_fontconfig +#define FcFontSetList FcFontSetList_dylibloader_orig_fontconfig +#define FcFontList FcFontList_dylibloader_orig_fontconfig +#define FcAtomicCreate FcAtomicCreate_dylibloader_orig_fontconfig +#define FcAtomicLock FcAtomicLock_dylibloader_orig_fontconfig +#define FcAtomicNewFile FcAtomicNewFile_dylibloader_orig_fontconfig +#define FcAtomicOrigFile FcAtomicOrigFile_dylibloader_orig_fontconfig +#define FcAtomicReplaceOrig FcAtomicReplaceOrig_dylibloader_orig_fontconfig +#define FcAtomicDeleteNew FcAtomicDeleteNew_dylibloader_orig_fontconfig +#define FcAtomicUnlock FcAtomicUnlock_dylibloader_orig_fontconfig +#define FcAtomicDestroy FcAtomicDestroy_dylibloader_orig_fontconfig +#define FcFontSetMatch FcFontSetMatch_dylibloader_orig_fontconfig +#define FcFontMatch FcFontMatch_dylibloader_orig_fontconfig +#define FcFontRenderPrepare FcFontRenderPrepare_dylibloader_orig_fontconfig +#define FcFontSetSort FcFontSetSort_dylibloader_orig_fontconfig +#define FcFontSort FcFontSort_dylibloader_orig_fontconfig +#define FcFontSetSortDestroy FcFontSetSortDestroy_dylibloader_orig_fontconfig +#define FcMatrixCopy FcMatrixCopy_dylibloader_orig_fontconfig +#define FcMatrixEqual FcMatrixEqual_dylibloader_orig_fontconfig +#define FcMatrixMultiply FcMatrixMultiply_dylibloader_orig_fontconfig +#define FcMatrixRotate FcMatrixRotate_dylibloader_orig_fontconfig +#define FcMatrixScale FcMatrixScale_dylibloader_orig_fontconfig +#define FcMatrixShear FcMatrixShear_dylibloader_orig_fontconfig +#define FcNameRegisterObjectTypes FcNameRegisterObjectTypes_dylibloader_orig_fontconfig +#define FcNameUnregisterObjectTypes FcNameUnregisterObjectTypes_dylibloader_orig_fontconfig +#define FcNameGetObjectType FcNameGetObjectType_dylibloader_orig_fontconfig +#define FcNameRegisterConstants FcNameRegisterConstants_dylibloader_orig_fontconfig +#define FcNameUnregisterConstants FcNameUnregisterConstants_dylibloader_orig_fontconfig +#define FcNameGetConstant FcNameGetConstant_dylibloader_orig_fontconfig +#define FcNameConstant FcNameConstant_dylibloader_orig_fontconfig +#define FcNameParse FcNameParse_dylibloader_orig_fontconfig +#define FcNameUnparse FcNameUnparse_dylibloader_orig_fontconfig +#define FcPatternCreate FcPatternCreate_dylibloader_orig_fontconfig +#define FcPatternDuplicate FcPatternDuplicate_dylibloader_orig_fontconfig +#define FcPatternReference FcPatternReference_dylibloader_orig_fontconfig +#define FcPatternFilter FcPatternFilter_dylibloader_orig_fontconfig +#define FcValueDestroy FcValueDestroy_dylibloader_orig_fontconfig +#define FcValueEqual FcValueEqual_dylibloader_orig_fontconfig +#define FcValueSave FcValueSave_dylibloader_orig_fontconfig +#define FcPatternDestroy FcPatternDestroy_dylibloader_orig_fontconfig +#define FcPatternObjectCount FcPatternObjectCount_dylibloader_orig_fontconfig +#define FcPatternEqual FcPatternEqual_dylibloader_orig_fontconfig +#define FcPatternEqualSubset FcPatternEqualSubset_dylibloader_orig_fontconfig +#define FcPatternHash FcPatternHash_dylibloader_orig_fontconfig +#define FcPatternAdd FcPatternAdd_dylibloader_orig_fontconfig +#define FcPatternAddWeak FcPatternAddWeak_dylibloader_orig_fontconfig +#define FcPatternGet FcPatternGet_dylibloader_orig_fontconfig +#define FcPatternGetWithBinding FcPatternGetWithBinding_dylibloader_orig_fontconfig +#define FcPatternDel FcPatternDel_dylibloader_orig_fontconfig +#define FcPatternRemove FcPatternRemove_dylibloader_orig_fontconfig +#define FcPatternAddInteger FcPatternAddInteger_dylibloader_orig_fontconfig +#define FcPatternAddDouble FcPatternAddDouble_dylibloader_orig_fontconfig +#define FcPatternAddString FcPatternAddString_dylibloader_orig_fontconfig +#define FcPatternAddMatrix FcPatternAddMatrix_dylibloader_orig_fontconfig +#define FcPatternAddCharSet FcPatternAddCharSet_dylibloader_orig_fontconfig +#define FcPatternAddBool FcPatternAddBool_dylibloader_orig_fontconfig +#define FcPatternAddLangSet FcPatternAddLangSet_dylibloader_orig_fontconfig +#define FcPatternAddRange FcPatternAddRange_dylibloader_orig_fontconfig +#define FcPatternGetInteger FcPatternGetInteger_dylibloader_orig_fontconfig +#define FcPatternGetDouble FcPatternGetDouble_dylibloader_orig_fontconfig +#define FcPatternGetString FcPatternGetString_dylibloader_orig_fontconfig +#define FcPatternGetMatrix FcPatternGetMatrix_dylibloader_orig_fontconfig +#define FcPatternGetCharSet FcPatternGetCharSet_dylibloader_orig_fontconfig +#define FcPatternGetBool FcPatternGetBool_dylibloader_orig_fontconfig +#define FcPatternGetLangSet FcPatternGetLangSet_dylibloader_orig_fontconfig +#define FcPatternGetRange FcPatternGetRange_dylibloader_orig_fontconfig +#define FcPatternVaBuild FcPatternVaBuild_dylibloader_orig_fontconfig +#define FcPatternBuild FcPatternBuild_dylibloader_orig_fontconfig +#define FcPatternFormat FcPatternFormat_dylibloader_orig_fontconfig +#define FcRangeCreateDouble FcRangeCreateDouble_dylibloader_orig_fontconfig +#define FcRangeCreateInteger FcRangeCreateInteger_dylibloader_orig_fontconfig +#define FcRangeDestroy FcRangeDestroy_dylibloader_orig_fontconfig +#define FcRangeCopy FcRangeCopy_dylibloader_orig_fontconfig +#define FcRangeGetDouble FcRangeGetDouble_dylibloader_orig_fontconfig +#define FcPatternIterStart FcPatternIterStart_dylibloader_orig_fontconfig +#define FcPatternIterNext FcPatternIterNext_dylibloader_orig_fontconfig +#define FcPatternIterEqual FcPatternIterEqual_dylibloader_orig_fontconfig +#define FcPatternFindIter FcPatternFindIter_dylibloader_orig_fontconfig +#define FcPatternIterIsValid FcPatternIterIsValid_dylibloader_orig_fontconfig +#define FcPatternIterGetObject FcPatternIterGetObject_dylibloader_orig_fontconfig +#define FcPatternIterValueCount FcPatternIterValueCount_dylibloader_orig_fontconfig +#define FcPatternIterGetValue FcPatternIterGetValue_dylibloader_orig_fontconfig +#define FcWeightFromOpenType FcWeightFromOpenType_dylibloader_orig_fontconfig +#define FcWeightFromOpenTypeDouble FcWeightFromOpenTypeDouble_dylibloader_orig_fontconfig +#define FcWeightToOpenType FcWeightToOpenType_dylibloader_orig_fontconfig +#define FcWeightToOpenTypeDouble FcWeightToOpenTypeDouble_dylibloader_orig_fontconfig +#define FcStrCopy FcStrCopy_dylibloader_orig_fontconfig +#define FcStrCopyFilename FcStrCopyFilename_dylibloader_orig_fontconfig +#define FcStrPlus FcStrPlus_dylibloader_orig_fontconfig +#define FcStrFree FcStrFree_dylibloader_orig_fontconfig +#define FcStrDowncase FcStrDowncase_dylibloader_orig_fontconfig +#define FcStrCmpIgnoreCase FcStrCmpIgnoreCase_dylibloader_orig_fontconfig +#define FcStrCmp FcStrCmp_dylibloader_orig_fontconfig +#define FcStrStrIgnoreCase FcStrStrIgnoreCase_dylibloader_orig_fontconfig +#define FcStrStr FcStrStr_dylibloader_orig_fontconfig +#define FcUtf8ToUcs4 FcUtf8ToUcs4_dylibloader_orig_fontconfig +#define FcUtf8Len FcUtf8Len_dylibloader_orig_fontconfig +#define FcUcs4ToUtf8 FcUcs4ToUtf8_dylibloader_orig_fontconfig +#define FcUtf16ToUcs4 FcUtf16ToUcs4_dylibloader_orig_fontconfig +#define FcUtf16Len FcUtf16Len_dylibloader_orig_fontconfig +#define FcStrDirname FcStrDirname_dylibloader_orig_fontconfig +#define FcStrBasename FcStrBasename_dylibloader_orig_fontconfig +#define FcStrSetCreate FcStrSetCreate_dylibloader_orig_fontconfig +#define FcStrSetMember FcStrSetMember_dylibloader_orig_fontconfig +#define FcStrSetEqual FcStrSetEqual_dylibloader_orig_fontconfig +#define FcStrSetAdd FcStrSetAdd_dylibloader_orig_fontconfig +#define FcStrSetAddFilename FcStrSetAddFilename_dylibloader_orig_fontconfig +#define FcStrSetDel FcStrSetDel_dylibloader_orig_fontconfig +#define FcStrSetDestroy FcStrSetDestroy_dylibloader_orig_fontconfig +#define FcStrListCreate FcStrListCreate_dylibloader_orig_fontconfig +#define FcStrListFirst FcStrListFirst_dylibloader_orig_fontconfig +#define FcStrListNext FcStrListNext_dylibloader_orig_fontconfig +#define FcStrListDone FcStrListDone_dylibloader_orig_fontconfig +#define FcConfigParseAndLoad FcConfigParseAndLoad_dylibloader_orig_fontconfig +#define FcConfigParseAndLoadFromMemory FcConfigParseAndLoadFromMemory_dylibloader_orig_fontconfig +#include <fontconfig/fontconfig.h> +#undef FcBlanksCreate +#undef FcBlanksDestroy +#undef FcBlanksAdd +#undef FcBlanksIsMember +#undef FcCacheDir +#undef FcCacheCopySet +#undef FcCacheSubdir +#undef FcCacheNumSubdir +#undef FcCacheNumFont +#undef FcDirCacheUnlink +#undef FcDirCacheValid +#undef FcDirCacheClean +#undef FcCacheCreateTagFile +#undef FcDirCacheCreateUUID +#undef FcDirCacheDeleteUUID +#undef FcConfigHome +#undef FcConfigEnableHome +#undef FcConfigFilename +#undef FcConfigCreate +#undef FcConfigReference +#undef FcConfigDestroy +#undef FcConfigSetCurrent +#undef FcConfigGetCurrent +#undef FcConfigUptoDate +#undef FcConfigBuildFonts +#undef FcConfigGetFontDirs +#undef FcConfigGetConfigDirs +#undef FcConfigGetConfigFiles +#undef FcConfigGetCache +#undef FcConfigGetBlanks +#undef FcConfigGetCacheDirs +#undef FcConfigGetRescanInterval +#undef FcConfigSetRescanInterval +#undef FcConfigGetFonts +#undef FcConfigAppFontAddFile +#undef FcConfigAppFontAddDir +#undef FcConfigAppFontClear +#undef FcConfigSubstituteWithPat +#undef FcConfigSubstitute +#undef FcConfigGetSysRoot +#undef FcConfigSetSysRoot +#undef FcConfigFileInfoIterInit +#undef FcConfigFileInfoIterNext +#undef FcConfigFileInfoIterGet +#undef FcValuePrint +#undef FcPatternPrint +#undef FcFontSetPrint +#undef FcGetDefaultLangs +#undef FcDefaultSubstitute +#undef FcFileIsDir +#undef FcFileScan +#undef FcDirScan +#undef FcDirSave +#undef FcDirCacheLoad +#undef FcDirCacheRescan +#undef FcDirCacheRead +#undef FcDirCacheLoadFile +#undef FcDirCacheUnload +#undef FcFreeTypeQuery +#undef FcFreeTypeQueryAll +#undef FcFontSetCreate +#undef FcFontSetDestroy +#undef FcFontSetAdd +#undef FcInitLoadConfig +#undef FcInitLoadConfigAndFonts +#undef FcInit +#undef FcFini +#undef FcGetVersion +#undef FcInitReinitialize +#undef FcInitBringUptoDate +#undef FcGetLangs +#undef FcLangNormalize +#undef FcLangGetCharSet +#undef FcLangSetCreate +#undef FcLangSetDestroy +#undef FcLangSetCopy +#undef FcLangSetAdd +#undef FcLangSetDel +#undef FcLangSetHasLang +#undef FcLangSetCompare +#undef FcLangSetContains +#undef FcLangSetEqual +#undef FcLangSetHash +#undef FcLangSetGetLangs +#undef FcLangSetUnion +#undef FcLangSetSubtract +#undef FcObjectSetCreate +#undef FcObjectSetAdd +#undef FcObjectSetDestroy +#undef FcObjectSetVaBuild +#undef FcObjectSetBuild +#undef FcFontSetList +#undef FcFontList +#undef FcAtomicCreate +#undef FcAtomicLock +#undef FcAtomicNewFile +#undef FcAtomicOrigFile +#undef FcAtomicReplaceOrig +#undef FcAtomicDeleteNew +#undef FcAtomicUnlock +#undef FcAtomicDestroy +#undef FcFontSetMatch +#undef FcFontMatch +#undef FcFontRenderPrepare +#undef FcFontSetSort +#undef FcFontSort +#undef FcFontSetSortDestroy +#undef FcMatrixCopy +#undef FcMatrixEqual +#undef FcMatrixMultiply +#undef FcMatrixRotate +#undef FcMatrixScale +#undef FcMatrixShear +#undef FcNameRegisterObjectTypes +#undef FcNameUnregisterObjectTypes +#undef FcNameGetObjectType +#undef FcNameRegisterConstants +#undef FcNameUnregisterConstants +#undef FcNameGetConstant +#undef FcNameConstant +#undef FcNameParse +#undef FcNameUnparse +#undef FcPatternCreate +#undef FcPatternDuplicate +#undef FcPatternReference +#undef FcPatternFilter +#undef FcValueDestroy +#undef FcValueEqual +#undef FcValueSave +#undef FcPatternDestroy +#undef FcPatternObjectCount +#undef FcPatternEqual +#undef FcPatternEqualSubset +#undef FcPatternHash +#undef FcPatternAdd +#undef FcPatternAddWeak +#undef FcPatternGet +#undef FcPatternGetWithBinding +#undef FcPatternDel +#undef FcPatternRemove +#undef FcPatternAddInteger +#undef FcPatternAddDouble +#undef FcPatternAddString +#undef FcPatternAddMatrix +#undef FcPatternAddCharSet +#undef FcPatternAddBool +#undef FcPatternAddLangSet +#undef FcPatternAddRange +#undef FcPatternGetInteger +#undef FcPatternGetDouble +#undef FcPatternGetString +#undef FcPatternGetMatrix +#undef FcPatternGetCharSet +#undef FcPatternGetBool +#undef FcPatternGetLangSet +#undef FcPatternGetRange +#undef FcPatternVaBuild +#undef FcPatternBuild +#undef FcPatternFormat +#undef FcRangeCreateDouble +#undef FcRangeCreateInteger +#undef FcRangeDestroy +#undef FcRangeCopy +#undef FcRangeGetDouble +#undef FcPatternIterStart +#undef FcPatternIterNext +#undef FcPatternIterEqual +#undef FcPatternFindIter +#undef FcPatternIterIsValid +#undef FcPatternIterGetObject +#undef FcPatternIterValueCount +#undef FcPatternIterGetValue +#undef FcWeightFromOpenType +#undef FcWeightFromOpenTypeDouble +#undef FcWeightToOpenType +#undef FcWeightToOpenTypeDouble +#undef FcStrCopy +#undef FcStrCopyFilename +#undef FcStrPlus +#undef FcStrFree +#undef FcStrDowncase +#undef FcStrCmpIgnoreCase +#undef FcStrCmp +#undef FcStrStrIgnoreCase +#undef FcStrStr +#undef FcUtf8ToUcs4 +#undef FcUtf8Len +#undef FcUcs4ToUtf8 +#undef FcUtf16ToUcs4 +#undef FcUtf16Len +#undef FcStrDirname +#undef FcStrBasename +#undef FcStrSetCreate +#undef FcStrSetMember +#undef FcStrSetEqual +#undef FcStrSetAdd +#undef FcStrSetAddFilename +#undef FcStrSetDel +#undef FcStrSetDestroy +#undef FcStrListCreate +#undef FcStrListFirst +#undef FcStrListNext +#undef FcStrListDone +#undef FcConfigParseAndLoad +#undef FcConfigParseAndLoadFromMemory +#ifdef __cplusplus +extern "C" { +#endif +#define FcBlanksCreate FcBlanksCreate_dylibloader_wrapper_fontconfig +#define FcBlanksDestroy FcBlanksDestroy_dylibloader_wrapper_fontconfig +#define FcBlanksAdd FcBlanksAdd_dylibloader_wrapper_fontconfig +#define FcBlanksIsMember FcBlanksIsMember_dylibloader_wrapper_fontconfig +#define FcCacheDir FcCacheDir_dylibloader_wrapper_fontconfig +#define FcCacheCopySet FcCacheCopySet_dylibloader_wrapper_fontconfig +#define FcCacheSubdir FcCacheSubdir_dylibloader_wrapper_fontconfig +#define FcCacheNumSubdir FcCacheNumSubdir_dylibloader_wrapper_fontconfig +#define FcCacheNumFont FcCacheNumFont_dylibloader_wrapper_fontconfig +#define FcDirCacheUnlink FcDirCacheUnlink_dylibloader_wrapper_fontconfig +#define FcDirCacheValid FcDirCacheValid_dylibloader_wrapper_fontconfig +#define FcDirCacheClean FcDirCacheClean_dylibloader_wrapper_fontconfig +#define FcCacheCreateTagFile FcCacheCreateTagFile_dylibloader_wrapper_fontconfig +#define FcDirCacheCreateUUID FcDirCacheCreateUUID_dylibloader_wrapper_fontconfig +#define FcDirCacheDeleteUUID FcDirCacheDeleteUUID_dylibloader_wrapper_fontconfig +#define FcConfigHome FcConfigHome_dylibloader_wrapper_fontconfig +#define FcConfigEnableHome FcConfigEnableHome_dylibloader_wrapper_fontconfig +#define FcConfigFilename FcConfigFilename_dylibloader_wrapper_fontconfig +#define FcConfigCreate FcConfigCreate_dylibloader_wrapper_fontconfig +#define FcConfigReference FcConfigReference_dylibloader_wrapper_fontconfig +#define FcConfigDestroy FcConfigDestroy_dylibloader_wrapper_fontconfig +#define FcConfigSetCurrent FcConfigSetCurrent_dylibloader_wrapper_fontconfig +#define FcConfigGetCurrent FcConfigGetCurrent_dylibloader_wrapper_fontconfig +#define FcConfigUptoDate FcConfigUptoDate_dylibloader_wrapper_fontconfig +#define FcConfigBuildFonts FcConfigBuildFonts_dylibloader_wrapper_fontconfig +#define FcConfigGetFontDirs FcConfigGetFontDirs_dylibloader_wrapper_fontconfig +#define FcConfigGetConfigDirs FcConfigGetConfigDirs_dylibloader_wrapper_fontconfig +#define FcConfigGetConfigFiles FcConfigGetConfigFiles_dylibloader_wrapper_fontconfig +#define FcConfigGetCache FcConfigGetCache_dylibloader_wrapper_fontconfig +#define FcConfigGetBlanks FcConfigGetBlanks_dylibloader_wrapper_fontconfig +#define FcConfigGetCacheDirs FcConfigGetCacheDirs_dylibloader_wrapper_fontconfig +#define FcConfigGetRescanInterval FcConfigGetRescanInterval_dylibloader_wrapper_fontconfig +#define FcConfigSetRescanInterval FcConfigSetRescanInterval_dylibloader_wrapper_fontconfig +#define FcConfigGetFonts FcConfigGetFonts_dylibloader_wrapper_fontconfig +#define FcConfigAppFontAddFile FcConfigAppFontAddFile_dylibloader_wrapper_fontconfig +#define FcConfigAppFontAddDir FcConfigAppFontAddDir_dylibloader_wrapper_fontconfig +#define FcConfigAppFontClear FcConfigAppFontClear_dylibloader_wrapper_fontconfig +#define FcConfigSubstituteWithPat FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig +#define FcConfigSubstitute FcConfigSubstitute_dylibloader_wrapper_fontconfig +#define FcConfigGetSysRoot FcConfigGetSysRoot_dylibloader_wrapper_fontconfig +#define FcConfigSetSysRoot FcConfigSetSysRoot_dylibloader_wrapper_fontconfig +#define FcConfigFileInfoIterInit FcConfigFileInfoIterInit_dylibloader_wrapper_fontconfig +#define FcConfigFileInfoIterNext FcConfigFileInfoIterNext_dylibloader_wrapper_fontconfig +#define FcConfigFileInfoIterGet FcConfigFileInfoIterGet_dylibloader_wrapper_fontconfig +#define FcValuePrint FcValuePrint_dylibloader_wrapper_fontconfig +#define FcPatternPrint FcPatternPrint_dylibloader_wrapper_fontconfig +#define FcFontSetPrint FcFontSetPrint_dylibloader_wrapper_fontconfig +#define FcGetDefaultLangs FcGetDefaultLangs_dylibloader_wrapper_fontconfig +#define FcDefaultSubstitute FcDefaultSubstitute_dylibloader_wrapper_fontconfig +#define FcFileIsDir FcFileIsDir_dylibloader_wrapper_fontconfig +#define FcFileScan FcFileScan_dylibloader_wrapper_fontconfig +#define FcDirScan FcDirScan_dylibloader_wrapper_fontconfig +#define FcDirSave FcDirSave_dylibloader_wrapper_fontconfig +#define FcDirCacheLoad FcDirCacheLoad_dylibloader_wrapper_fontconfig +#define FcDirCacheRescan FcDirCacheRescan_dylibloader_wrapper_fontconfig +#define FcDirCacheRead FcDirCacheRead_dylibloader_wrapper_fontconfig +#define FcDirCacheLoadFile FcDirCacheLoadFile_dylibloader_wrapper_fontconfig +#define FcDirCacheUnload FcDirCacheUnload_dylibloader_wrapper_fontconfig +#define FcFreeTypeQuery FcFreeTypeQuery_dylibloader_wrapper_fontconfig +#define FcFreeTypeQueryAll FcFreeTypeQueryAll_dylibloader_wrapper_fontconfig +#define FcFontSetCreate FcFontSetCreate_dylibloader_wrapper_fontconfig +#define FcFontSetDestroy FcFontSetDestroy_dylibloader_wrapper_fontconfig +#define FcFontSetAdd FcFontSetAdd_dylibloader_wrapper_fontconfig +#define FcInitLoadConfig FcInitLoadConfig_dylibloader_wrapper_fontconfig +#define FcInitLoadConfigAndFonts FcInitLoadConfigAndFonts_dylibloader_wrapper_fontconfig +#define FcInit FcInit_dylibloader_wrapper_fontconfig +#define FcFini FcFini_dylibloader_wrapper_fontconfig +#define FcGetVersion FcGetVersion_dylibloader_wrapper_fontconfig +#define FcInitReinitialize FcInitReinitialize_dylibloader_wrapper_fontconfig +#define FcInitBringUptoDate FcInitBringUptoDate_dylibloader_wrapper_fontconfig +#define FcGetLangs FcGetLangs_dylibloader_wrapper_fontconfig +#define FcLangNormalize FcLangNormalize_dylibloader_wrapper_fontconfig +#define FcLangGetCharSet FcLangGetCharSet_dylibloader_wrapper_fontconfig +#define FcLangSetCreate FcLangSetCreate_dylibloader_wrapper_fontconfig +#define FcLangSetDestroy FcLangSetDestroy_dylibloader_wrapper_fontconfig +#define FcLangSetCopy FcLangSetCopy_dylibloader_wrapper_fontconfig +#define FcLangSetAdd FcLangSetAdd_dylibloader_wrapper_fontconfig +#define FcLangSetDel FcLangSetDel_dylibloader_wrapper_fontconfig +#define FcLangSetHasLang FcLangSetHasLang_dylibloader_wrapper_fontconfig +#define FcLangSetCompare FcLangSetCompare_dylibloader_wrapper_fontconfig +#define FcLangSetContains FcLangSetContains_dylibloader_wrapper_fontconfig +#define FcLangSetEqual FcLangSetEqual_dylibloader_wrapper_fontconfig +#define FcLangSetHash FcLangSetHash_dylibloader_wrapper_fontconfig +#define FcLangSetGetLangs FcLangSetGetLangs_dylibloader_wrapper_fontconfig +#define FcLangSetUnion FcLangSetUnion_dylibloader_wrapper_fontconfig +#define FcLangSetSubtract FcLangSetSubtract_dylibloader_wrapper_fontconfig +#define FcObjectSetCreate FcObjectSetCreate_dylibloader_wrapper_fontconfig +#define FcObjectSetAdd FcObjectSetAdd_dylibloader_wrapper_fontconfig +#define FcObjectSetDestroy FcObjectSetDestroy_dylibloader_wrapper_fontconfig +#define FcObjectSetVaBuild FcObjectSetVaBuild_dylibloader_wrapper_fontconfig +#define FcObjectSetBuild FcObjectSetBuild_dylibloader_wrapper_fontconfig +#define FcFontSetList FcFontSetList_dylibloader_wrapper_fontconfig +#define FcFontList FcFontList_dylibloader_wrapper_fontconfig +#define FcAtomicCreate FcAtomicCreate_dylibloader_wrapper_fontconfig +#define FcAtomicLock FcAtomicLock_dylibloader_wrapper_fontconfig +#define FcAtomicNewFile FcAtomicNewFile_dylibloader_wrapper_fontconfig +#define FcAtomicOrigFile FcAtomicOrigFile_dylibloader_wrapper_fontconfig +#define FcAtomicReplaceOrig FcAtomicReplaceOrig_dylibloader_wrapper_fontconfig +#define FcAtomicDeleteNew FcAtomicDeleteNew_dylibloader_wrapper_fontconfig +#define FcAtomicUnlock FcAtomicUnlock_dylibloader_wrapper_fontconfig +#define FcAtomicDestroy FcAtomicDestroy_dylibloader_wrapper_fontconfig +#define FcFontSetMatch FcFontSetMatch_dylibloader_wrapper_fontconfig +#define FcFontMatch FcFontMatch_dylibloader_wrapper_fontconfig +#define FcFontRenderPrepare FcFontRenderPrepare_dylibloader_wrapper_fontconfig +#define FcFontSetSort FcFontSetSort_dylibloader_wrapper_fontconfig +#define FcFontSort FcFontSort_dylibloader_wrapper_fontconfig +#define FcFontSetSortDestroy FcFontSetSortDestroy_dylibloader_wrapper_fontconfig +#define FcMatrixCopy FcMatrixCopy_dylibloader_wrapper_fontconfig +#define FcMatrixEqual FcMatrixEqual_dylibloader_wrapper_fontconfig +#define FcMatrixMultiply FcMatrixMultiply_dylibloader_wrapper_fontconfig +#define FcMatrixRotate FcMatrixRotate_dylibloader_wrapper_fontconfig +#define FcMatrixScale FcMatrixScale_dylibloader_wrapper_fontconfig +#define FcMatrixShear FcMatrixShear_dylibloader_wrapper_fontconfig +#define FcNameRegisterObjectTypes FcNameRegisterObjectTypes_dylibloader_wrapper_fontconfig +#define FcNameUnregisterObjectTypes FcNameUnregisterObjectTypes_dylibloader_wrapper_fontconfig +#define FcNameGetObjectType FcNameGetObjectType_dylibloader_wrapper_fontconfig +#define FcNameRegisterConstants FcNameRegisterConstants_dylibloader_wrapper_fontconfig +#define FcNameUnregisterConstants FcNameUnregisterConstants_dylibloader_wrapper_fontconfig +#define FcNameGetConstant FcNameGetConstant_dylibloader_wrapper_fontconfig +#define FcNameConstant FcNameConstant_dylibloader_wrapper_fontconfig +#define FcNameParse FcNameParse_dylibloader_wrapper_fontconfig +#define FcNameUnparse FcNameUnparse_dylibloader_wrapper_fontconfig +#define FcPatternCreate FcPatternCreate_dylibloader_wrapper_fontconfig +#define FcPatternDuplicate FcPatternDuplicate_dylibloader_wrapper_fontconfig +#define FcPatternReference FcPatternReference_dylibloader_wrapper_fontconfig +#define FcPatternFilter FcPatternFilter_dylibloader_wrapper_fontconfig +#define FcValueDestroy FcValueDestroy_dylibloader_wrapper_fontconfig +#define FcValueEqual FcValueEqual_dylibloader_wrapper_fontconfig +#define FcValueSave FcValueSave_dylibloader_wrapper_fontconfig +#define FcPatternDestroy FcPatternDestroy_dylibloader_wrapper_fontconfig +#define FcPatternObjectCount FcPatternObjectCount_dylibloader_wrapper_fontconfig +#define FcPatternEqual FcPatternEqual_dylibloader_wrapper_fontconfig +#define FcPatternEqualSubset FcPatternEqualSubset_dylibloader_wrapper_fontconfig +#define FcPatternHash FcPatternHash_dylibloader_wrapper_fontconfig +#define FcPatternAdd FcPatternAdd_dylibloader_wrapper_fontconfig +#define FcPatternAddWeak FcPatternAddWeak_dylibloader_wrapper_fontconfig +#define FcPatternGet FcPatternGet_dylibloader_wrapper_fontconfig +#define FcPatternGetWithBinding FcPatternGetWithBinding_dylibloader_wrapper_fontconfig +#define FcPatternDel FcPatternDel_dylibloader_wrapper_fontconfig +#define FcPatternRemove FcPatternRemove_dylibloader_wrapper_fontconfig +#define FcPatternAddInteger FcPatternAddInteger_dylibloader_wrapper_fontconfig +#define FcPatternAddDouble FcPatternAddDouble_dylibloader_wrapper_fontconfig +#define FcPatternAddString FcPatternAddString_dylibloader_wrapper_fontconfig +#define FcPatternAddMatrix FcPatternAddMatrix_dylibloader_wrapper_fontconfig +#define FcPatternAddCharSet FcPatternAddCharSet_dylibloader_wrapper_fontconfig +#define FcPatternAddBool FcPatternAddBool_dylibloader_wrapper_fontconfig +#define FcPatternAddLangSet FcPatternAddLangSet_dylibloader_wrapper_fontconfig +#define FcPatternAddRange FcPatternAddRange_dylibloader_wrapper_fontconfig +#define FcPatternGetInteger FcPatternGetInteger_dylibloader_wrapper_fontconfig +#define FcPatternGetDouble FcPatternGetDouble_dylibloader_wrapper_fontconfig +#define FcPatternGetString FcPatternGetString_dylibloader_wrapper_fontconfig +#define FcPatternGetMatrix FcPatternGetMatrix_dylibloader_wrapper_fontconfig +#define FcPatternGetCharSet FcPatternGetCharSet_dylibloader_wrapper_fontconfig +#define FcPatternGetBool FcPatternGetBool_dylibloader_wrapper_fontconfig +#define FcPatternGetLangSet FcPatternGetLangSet_dylibloader_wrapper_fontconfig +#define FcPatternGetRange FcPatternGetRange_dylibloader_wrapper_fontconfig +#define FcPatternVaBuild FcPatternVaBuild_dylibloader_wrapper_fontconfig +#define FcPatternBuild FcPatternBuild_dylibloader_wrapper_fontconfig +#define FcPatternFormat FcPatternFormat_dylibloader_wrapper_fontconfig +#define FcRangeCreateDouble FcRangeCreateDouble_dylibloader_wrapper_fontconfig +#define FcRangeCreateInteger FcRangeCreateInteger_dylibloader_wrapper_fontconfig +#define FcRangeDestroy FcRangeDestroy_dylibloader_wrapper_fontconfig +#define FcRangeCopy FcRangeCopy_dylibloader_wrapper_fontconfig +#define FcRangeGetDouble FcRangeGetDouble_dylibloader_wrapper_fontconfig +#define FcPatternIterStart FcPatternIterStart_dylibloader_wrapper_fontconfig +#define FcPatternIterNext FcPatternIterNext_dylibloader_wrapper_fontconfig +#define FcPatternIterEqual FcPatternIterEqual_dylibloader_wrapper_fontconfig +#define FcPatternFindIter FcPatternFindIter_dylibloader_wrapper_fontconfig +#define FcPatternIterIsValid FcPatternIterIsValid_dylibloader_wrapper_fontconfig +#define FcPatternIterGetObject FcPatternIterGetObject_dylibloader_wrapper_fontconfig +#define FcPatternIterValueCount FcPatternIterValueCount_dylibloader_wrapper_fontconfig +#define FcPatternIterGetValue FcPatternIterGetValue_dylibloader_wrapper_fontconfig +#define FcWeightFromOpenType FcWeightFromOpenType_dylibloader_wrapper_fontconfig +#define FcWeightFromOpenTypeDouble FcWeightFromOpenTypeDouble_dylibloader_wrapper_fontconfig +#define FcWeightToOpenType FcWeightToOpenType_dylibloader_wrapper_fontconfig +#define FcWeightToOpenTypeDouble FcWeightToOpenTypeDouble_dylibloader_wrapper_fontconfig +#define FcStrCopy FcStrCopy_dylibloader_wrapper_fontconfig +#define FcStrCopyFilename FcStrCopyFilename_dylibloader_wrapper_fontconfig +#define FcStrPlus FcStrPlus_dylibloader_wrapper_fontconfig +#define FcStrFree FcStrFree_dylibloader_wrapper_fontconfig +#define FcStrDowncase FcStrDowncase_dylibloader_wrapper_fontconfig +#define FcStrCmpIgnoreCase FcStrCmpIgnoreCase_dylibloader_wrapper_fontconfig +#define FcStrCmp FcStrCmp_dylibloader_wrapper_fontconfig +#define FcStrStrIgnoreCase FcStrStrIgnoreCase_dylibloader_wrapper_fontconfig +#define FcStrStr FcStrStr_dylibloader_wrapper_fontconfig +#define FcUtf8ToUcs4 FcUtf8ToUcs4_dylibloader_wrapper_fontconfig +#define FcUtf8Len FcUtf8Len_dylibloader_wrapper_fontconfig +#define FcUcs4ToUtf8 FcUcs4ToUtf8_dylibloader_wrapper_fontconfig +#define FcUtf16ToUcs4 FcUtf16ToUcs4_dylibloader_wrapper_fontconfig +#define FcUtf16Len FcUtf16Len_dylibloader_wrapper_fontconfig +#define FcStrDirname FcStrDirname_dylibloader_wrapper_fontconfig +#define FcStrBasename FcStrBasename_dylibloader_wrapper_fontconfig +#define FcStrSetCreate FcStrSetCreate_dylibloader_wrapper_fontconfig +#define FcStrSetMember FcStrSetMember_dylibloader_wrapper_fontconfig +#define FcStrSetEqual FcStrSetEqual_dylibloader_wrapper_fontconfig +#define FcStrSetAdd FcStrSetAdd_dylibloader_wrapper_fontconfig +#define FcStrSetAddFilename FcStrSetAddFilename_dylibloader_wrapper_fontconfig +#define FcStrSetDel FcStrSetDel_dylibloader_wrapper_fontconfig +#define FcStrSetDestroy FcStrSetDestroy_dylibloader_wrapper_fontconfig +#define FcStrListCreate FcStrListCreate_dylibloader_wrapper_fontconfig +#define FcStrListFirst FcStrListFirst_dylibloader_wrapper_fontconfig +#define FcStrListNext FcStrListNext_dylibloader_wrapper_fontconfig +#define FcStrListDone FcStrListDone_dylibloader_wrapper_fontconfig +#define FcConfigParseAndLoad FcConfigParseAndLoad_dylibloader_wrapper_fontconfig +#define FcConfigParseAndLoadFromMemory FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig +extern FcBlanks* (*FcBlanksCreate_dylibloader_wrapper_fontconfig)( void); +extern void (*FcBlanksDestroy_dylibloader_wrapper_fontconfig)( FcBlanks*); +extern FcBool (*FcBlanksAdd_dylibloader_wrapper_fontconfig)( FcBlanks*, FcChar32); +extern FcBool (*FcBlanksIsMember_dylibloader_wrapper_fontconfig)( FcBlanks*, FcChar32); +extern const FcChar8* (*FcCacheDir_dylibloader_wrapper_fontconfig)(const FcCache*); +extern FcFontSet* (*FcCacheCopySet_dylibloader_wrapper_fontconfig)(const FcCache*); +extern const FcChar8* (*FcCacheSubdir_dylibloader_wrapper_fontconfig)(const FcCache*, int); +extern int (*FcCacheNumSubdir_dylibloader_wrapper_fontconfig)(const FcCache*); +extern int (*FcCacheNumFont_dylibloader_wrapper_fontconfig)(const FcCache*); +extern FcBool (*FcDirCacheUnlink_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +extern FcBool (*FcDirCacheValid_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcBool (*FcDirCacheClean_dylibloader_wrapper_fontconfig)(const FcChar8*, FcBool); +extern void (*FcCacheCreateTagFile_dylibloader_wrapper_fontconfig)(const FcConfig*); +extern FcBool (*FcDirCacheCreateUUID_dylibloader_wrapper_fontconfig)( FcChar8*, FcBool, FcConfig*); +extern FcBool (*FcDirCacheDeleteUUID_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +extern FcChar8* (*FcConfigHome_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcConfigEnableHome_dylibloader_wrapper_fontconfig)( FcBool); +extern FcChar8* (*FcConfigFilename_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcConfig* (*FcConfigCreate_dylibloader_wrapper_fontconfig)( void); +extern FcConfig* (*FcConfigReference_dylibloader_wrapper_fontconfig)( FcConfig*); +extern void (*FcConfigDestroy_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBool (*FcConfigSetCurrent_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcConfig* (*FcConfigGetCurrent_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcConfigUptoDate_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBool (*FcConfigBuildFonts_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcStrList* (*FcConfigGetFontDirs_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcStrList* (*FcConfigGetConfigDirs_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcStrList* (*FcConfigGetConfigFiles_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcChar8* (*FcConfigGetCache_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBlanks* (*FcConfigGetBlanks_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcStrList* (*FcConfigGetCacheDirs_dylibloader_wrapper_fontconfig)(const FcConfig*); +extern int (*FcConfigGetRescanInterval_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBool (*FcConfigSetRescanInterval_dylibloader_wrapper_fontconfig)( FcConfig*, int); +extern FcFontSet* (*FcConfigGetFonts_dylibloader_wrapper_fontconfig)( FcConfig*, FcSetName); +extern FcBool (*FcConfigAppFontAddFile_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +extern FcBool (*FcConfigAppFontAddDir_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +extern void (*FcConfigAppFontClear_dylibloader_wrapper_fontconfig)( FcConfig*); +extern FcBool (*FcConfigSubstituteWithPat_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcPattern*, FcMatchKind); +extern FcBool (*FcConfigSubstitute_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcMatchKind); +extern const FcChar8* (*FcConfigGetSysRoot_dylibloader_wrapper_fontconfig)(const FcConfig*); +extern void (*FcConfigSetSysRoot_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*); +extern void (*FcConfigFileInfoIterInit_dylibloader_wrapper_fontconfig)( FcConfig*, FcConfigFileInfoIter*); +extern FcBool (*FcConfigFileInfoIterNext_dylibloader_wrapper_fontconfig)( FcConfig*, FcConfigFileInfoIter*); +extern FcBool (*FcConfigFileInfoIterGet_dylibloader_wrapper_fontconfig)( FcConfig*, FcConfigFileInfoIter*, FcChar8**, FcChar8**, FcBool*); +extern void (*FcValuePrint_dylibloader_wrapper_fontconfig)(const FcValue); +extern void (*FcPatternPrint_dylibloader_wrapper_fontconfig)(const FcPattern*); +extern void (*FcFontSetPrint_dylibloader_wrapper_fontconfig)(const FcFontSet*); +extern FcStrSet* (*FcGetDefaultLangs_dylibloader_wrapper_fontconfig)( void); +extern void (*FcDefaultSubstitute_dylibloader_wrapper_fontconfig)( FcPattern*); +extern FcBool (*FcFileIsDir_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcBool (*FcFileScan_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*, FcFileCache*, FcBlanks*,const FcChar8*, FcBool); +extern FcBool (*FcDirScan_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*, FcFileCache*, FcBlanks*,const FcChar8*, FcBool); +extern FcBool (*FcDirSave_dylibloader_wrapper_fontconfig)( FcFontSet*, FcStrSet*,const FcChar8*); +extern FcCache* (*FcDirCacheLoad_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*, FcChar8**); +extern FcCache* (*FcDirCacheRescan_dylibloader_wrapper_fontconfig)(const FcChar8*, FcConfig*); +extern FcCache* (*FcDirCacheRead_dylibloader_wrapper_fontconfig)(const FcChar8*, FcBool, FcConfig*); +extern FcCache* (*FcDirCacheLoadFile_dylibloader_wrapper_fontconfig)(const FcChar8*,struct stat*); +extern void (*FcDirCacheUnload_dylibloader_wrapper_fontconfig)( FcCache*); +extern FcPattern* (*FcFreeTypeQuery_dylibloader_wrapper_fontconfig)(const FcChar8*, unsigned int, FcBlanks*, int*); +extern unsigned int (*FcFreeTypeQueryAll_dylibloader_wrapper_fontconfig)(const FcChar8*, unsigned int, FcBlanks*, int*, FcFontSet*); +extern FcFontSet* (*FcFontSetCreate_dylibloader_wrapper_fontconfig)( void); +extern void (*FcFontSetDestroy_dylibloader_wrapper_fontconfig)( FcFontSet*); +extern FcBool (*FcFontSetAdd_dylibloader_wrapper_fontconfig)( FcFontSet*, FcPattern*); +extern FcConfig* (*FcInitLoadConfig_dylibloader_wrapper_fontconfig)( void); +extern FcConfig* (*FcInitLoadConfigAndFonts_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcInit_dylibloader_wrapper_fontconfig)( void); +extern void (*FcFini_dylibloader_wrapper_fontconfig)( void); +extern int (*FcGetVersion_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcInitReinitialize_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcInitBringUptoDate_dylibloader_wrapper_fontconfig)( void); +extern FcStrSet* (*FcGetLangs_dylibloader_wrapper_fontconfig)( void); +extern FcChar8* (*FcLangNormalize_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern const FcCharSet* (*FcLangGetCharSet_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcLangSet* (*FcLangSetCreate_dylibloader_wrapper_fontconfig)( void); +extern void (*FcLangSetDestroy_dylibloader_wrapper_fontconfig)( FcLangSet*); +extern FcLangSet* (*FcLangSetCopy_dylibloader_wrapper_fontconfig)(const FcLangSet*); +extern FcBool (*FcLangSetAdd_dylibloader_wrapper_fontconfig)( FcLangSet*,const FcChar8*); +extern FcBool (*FcLangSetDel_dylibloader_wrapper_fontconfig)( FcLangSet*,const FcChar8*); +extern FcLangResult (*FcLangSetHasLang_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcChar8*); +extern FcLangResult (*FcLangSetCompare_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcBool (*FcLangSetContains_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcBool (*FcLangSetEqual_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcChar32 (*FcLangSetHash_dylibloader_wrapper_fontconfig)(const FcLangSet*); +extern FcStrSet* (*FcLangSetGetLangs_dylibloader_wrapper_fontconfig)(const FcLangSet*); +extern FcLangSet* (*FcLangSetUnion_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcLangSet* (*FcLangSetSubtract_dylibloader_wrapper_fontconfig)(const FcLangSet*,const FcLangSet*); +extern FcObjectSet* (*FcObjectSetCreate_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcObjectSetAdd_dylibloader_wrapper_fontconfig)( FcObjectSet*,const char*); +extern void (*FcObjectSetDestroy_dylibloader_wrapper_fontconfig)( FcObjectSet*); +extern FcObjectSet* (*FcObjectSetVaBuild_dylibloader_wrapper_fontconfig)(const char*, va_list); +extern FcObjectSet* (*FcObjectSetBuild_dylibloader_wrapper_fontconfig)(const char*,...); +extern FcFontSet* (*FcFontSetList_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcObjectSet*); +extern FcFontSet* (*FcFontList_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcObjectSet*); +extern FcAtomic* (*FcAtomicCreate_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcBool (*FcAtomicLock_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern FcChar8* (*FcAtomicNewFile_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern FcChar8* (*FcAtomicOrigFile_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern FcBool (*FcAtomicReplaceOrig_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern void (*FcAtomicDeleteNew_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern void (*FcAtomicUnlock_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern void (*FcAtomicDestroy_dylibloader_wrapper_fontconfig)( FcAtomic*); +extern FcPattern* (*FcFontSetMatch_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcResult*); +extern FcPattern* (*FcFontMatch_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcResult*); +extern FcPattern* (*FcFontRenderPrepare_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcPattern*); +extern FcFontSet* (*FcFontSetSort_dylibloader_wrapper_fontconfig)( FcConfig*, FcFontSet**, int, FcPattern*, FcBool, FcCharSet**, FcResult*); +extern FcFontSet* (*FcFontSort_dylibloader_wrapper_fontconfig)( FcConfig*, FcPattern*, FcBool, FcCharSet**, FcResult*); +extern void (*FcFontSetSortDestroy_dylibloader_wrapper_fontconfig)( FcFontSet*); +extern FcMatrix* (*FcMatrixCopy_dylibloader_wrapper_fontconfig)(const FcMatrix*); +extern FcBool (*FcMatrixEqual_dylibloader_wrapper_fontconfig)(const FcMatrix*,const FcMatrix*); +extern void (*FcMatrixMultiply_dylibloader_wrapper_fontconfig)( FcMatrix*,const FcMatrix*,const FcMatrix*); +extern void (*FcMatrixRotate_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +extern void (*FcMatrixScale_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +extern void (*FcMatrixShear_dylibloader_wrapper_fontconfig)( FcMatrix*, double, double); +extern FcBool (*FcNameRegisterObjectTypes_dylibloader_wrapper_fontconfig)(const FcObjectType*, int); +extern FcBool (*FcNameUnregisterObjectTypes_dylibloader_wrapper_fontconfig)(const FcObjectType*, int); +extern const FcObjectType* (*FcNameGetObjectType_dylibloader_wrapper_fontconfig)(const char*); +extern FcBool (*FcNameRegisterConstants_dylibloader_wrapper_fontconfig)(const FcConstant*, int); +extern FcBool (*FcNameUnregisterConstants_dylibloader_wrapper_fontconfig)(const FcConstant*, int); +extern const FcConstant* (*FcNameGetConstant_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcBool (*FcNameConstant_dylibloader_wrapper_fontconfig)(const FcChar8*, int*); +extern FcPattern* (*FcNameParse_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcChar8* (*FcNameUnparse_dylibloader_wrapper_fontconfig)( FcPattern*); +extern FcPattern* (*FcPatternCreate_dylibloader_wrapper_fontconfig)( void); +extern FcPattern* (*FcPatternDuplicate_dylibloader_wrapper_fontconfig)(const FcPattern*); +extern void (*FcPatternReference_dylibloader_wrapper_fontconfig)( FcPattern*); +extern FcPattern* (*FcPatternFilter_dylibloader_wrapper_fontconfig)( FcPattern*,const FcObjectSet*); +extern void (*FcValueDestroy_dylibloader_wrapper_fontconfig)( FcValue); +extern FcBool (*FcValueEqual_dylibloader_wrapper_fontconfig)( FcValue, FcValue); +extern FcValue (*FcValueSave_dylibloader_wrapper_fontconfig)( FcValue); +extern void (*FcPatternDestroy_dylibloader_wrapper_fontconfig)( FcPattern*); +extern int (*FcPatternObjectCount_dylibloader_wrapper_fontconfig)(const FcPattern*); +extern FcBool (*FcPatternEqual_dylibloader_wrapper_fontconfig)(const FcPattern*,const FcPattern*); +extern FcBool (*FcPatternEqualSubset_dylibloader_wrapper_fontconfig)(const FcPattern*,const FcPattern*,const FcObjectSet*); +extern FcChar32 (*FcPatternHash_dylibloader_wrapper_fontconfig)(const FcPattern*); +extern FcBool (*FcPatternAdd_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcValue, FcBool); +extern FcBool (*FcPatternAddWeak_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcValue, FcBool); +extern FcResult (*FcPatternGet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcValue*); +extern FcResult (*FcPatternGetWithBinding_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcValue*, FcValueBinding*); +extern FcBool (*FcPatternDel_dylibloader_wrapper_fontconfig)( FcPattern*,const char*); +extern FcBool (*FcPatternRemove_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, int); +extern FcBool (*FcPatternAddInteger_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, int); +extern FcBool (*FcPatternAddDouble_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, double); +extern FcBool (*FcPatternAddString_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcChar8*); +extern FcBool (*FcPatternAddMatrix_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcMatrix*); +extern FcBool (*FcPatternAddCharSet_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcCharSet*); +extern FcBool (*FcPatternAddBool_dylibloader_wrapper_fontconfig)( FcPattern*,const char*, FcBool); +extern FcBool (*FcPatternAddLangSet_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcLangSet*); +extern FcBool (*FcPatternAddRange_dylibloader_wrapper_fontconfig)( FcPattern*,const char*,const FcRange*); +extern FcResult (*FcPatternGetInteger_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, int*); +extern FcResult (*FcPatternGetDouble_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, double*); +extern FcResult (*FcPatternGetString_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcChar8**); +extern FcResult (*FcPatternGetMatrix_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcMatrix**); +extern FcResult (*FcPatternGetCharSet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcCharSet**); +extern FcResult (*FcPatternGetBool_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcBool*); +extern FcResult (*FcPatternGetLangSet_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcLangSet**); +extern FcResult (*FcPatternGetRange_dylibloader_wrapper_fontconfig)(const FcPattern*,const char*, int, FcRange**); +extern FcPattern* (*FcPatternVaBuild_dylibloader_wrapper_fontconfig)( FcPattern*, va_list); +extern FcPattern* (*FcPatternBuild_dylibloader_wrapper_fontconfig)( FcPattern*,...); +extern FcChar8* (*FcPatternFormat_dylibloader_wrapper_fontconfig)( FcPattern*,const FcChar8*); +extern FcRange* (*FcRangeCreateDouble_dylibloader_wrapper_fontconfig)( double, double); +extern FcRange* (*FcRangeCreateInteger_dylibloader_wrapper_fontconfig)( FcChar32, FcChar32); +extern void (*FcRangeDestroy_dylibloader_wrapper_fontconfig)( FcRange*); +extern FcRange* (*FcRangeCopy_dylibloader_wrapper_fontconfig)(const FcRange*); +extern FcBool (*FcRangeGetDouble_dylibloader_wrapper_fontconfig)(const FcRange*, double*, double*); +extern void (*FcPatternIterStart_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +extern FcBool (*FcPatternIterNext_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +extern FcBool (*FcPatternIterEqual_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*,const FcPattern*, FcPatternIter*); +extern FcBool (*FcPatternFindIter_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*,const char*); +extern FcBool (*FcPatternIterIsValid_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +extern const char* (*FcPatternIterGetObject_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +extern int (*FcPatternIterValueCount_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*); +extern FcResult (*FcPatternIterGetValue_dylibloader_wrapper_fontconfig)(const FcPattern*, FcPatternIter*, int, FcValue*, FcValueBinding*); +extern int (*FcWeightFromOpenType_dylibloader_wrapper_fontconfig)( int); +extern double (*FcWeightFromOpenTypeDouble_dylibloader_wrapper_fontconfig)( double); +extern int (*FcWeightToOpenType_dylibloader_wrapper_fontconfig)( int); +extern double (*FcWeightToOpenTypeDouble_dylibloader_wrapper_fontconfig)( double); +extern FcChar8* (*FcStrCopy_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcChar8* (*FcStrCopyFilename_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcChar8* (*FcStrPlus_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern void (*FcStrFree_dylibloader_wrapper_fontconfig)( FcChar8*); +extern FcChar8* (*FcStrDowncase_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern int (*FcStrCmpIgnoreCase_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern int (*FcStrCmp_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern const FcChar8* (*FcStrStrIgnoreCase_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern const FcChar8* (*FcStrStr_dylibloader_wrapper_fontconfig)(const FcChar8*,const FcChar8*); +extern int (*FcUtf8ToUcs4_dylibloader_wrapper_fontconfig)(const FcChar8*, FcChar32*, int); +extern FcBool (*FcUtf8Len_dylibloader_wrapper_fontconfig)(const FcChar8*, int, int*, int*); +extern int (*FcUcs4ToUtf8_dylibloader_wrapper_fontconfig)( FcChar32, FcChar8 [6]); +extern int (*FcUtf16ToUcs4_dylibloader_wrapper_fontconfig)(const FcChar8*, FcEndian, FcChar32*, int); +extern FcBool (*FcUtf16Len_dylibloader_wrapper_fontconfig)(const FcChar8*, FcEndian, int, int*, int*); +extern FcChar8* (*FcStrDirname_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcChar8* (*FcStrBasename_dylibloader_wrapper_fontconfig)(const FcChar8*); +extern FcStrSet* (*FcStrSetCreate_dylibloader_wrapper_fontconfig)( void); +extern FcBool (*FcStrSetMember_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +extern FcBool (*FcStrSetEqual_dylibloader_wrapper_fontconfig)( FcStrSet*, FcStrSet*); +extern FcBool (*FcStrSetAdd_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +extern FcBool (*FcStrSetAddFilename_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +extern FcBool (*FcStrSetDel_dylibloader_wrapper_fontconfig)( FcStrSet*,const FcChar8*); +extern void (*FcStrSetDestroy_dylibloader_wrapper_fontconfig)( FcStrSet*); +extern FcStrList* (*FcStrListCreate_dylibloader_wrapper_fontconfig)( FcStrSet*); +extern void (*FcStrListFirst_dylibloader_wrapper_fontconfig)( FcStrList*); +extern FcChar8* (*FcStrListNext_dylibloader_wrapper_fontconfig)( FcStrList*); +extern void (*FcStrListDone_dylibloader_wrapper_fontconfig)( FcStrList*); +extern FcBool (*FcConfigParseAndLoad_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*, FcBool); +extern FcBool (*FcConfigParseAndLoadFromMemory_dylibloader_wrapper_fontconfig)( FcConfig*,const FcChar8*, FcBool); +int initialize_fontconfig(int verbose); +#ifdef __cplusplus +} +#endif +#endif diff --git a/platform/linuxbsd/freedesktop_screensaver.h b/platform/linuxbsd/freedesktop_screensaver.h index b2303791bd..1b632b9103 100644 --- a/platform/linuxbsd/freedesktop_screensaver.h +++ b/platform/linuxbsd/freedesktop_screensaver.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef FREEDESKTOP_SCREENSAVER_H +#define FREEDESKTOP_SCREENSAVER_H + #ifdef DBUS_ENABLED #include <dbus/dbus.h> @@ -45,3 +48,5 @@ public: }; #endif // DBUS_ENABLED + +#endif // FREEDESKTOP_SCREENSAVER_H diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index b73d4dc626..e306c1054b 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -52,6 +52,10 @@ #include <sys/types.h> #include <unistd.h> +#ifdef FONTCONFIG_ENABLED +#include "fontconfig-so_wrap.h" +#endif + void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) { const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" }; @@ -327,6 +331,98 @@ uint64_t OS_LinuxBSD::get_embedded_pck_offset() const { return off; } +Vector<String> OS_LinuxBSD::get_system_fonts() const { +#ifdef FONTCONFIG_ENABLED + if (!font_config_initialized) { + ERR_FAIL_V_MSG(Vector<String>(), "Unable to load fontconfig, system font support is disabled."); + } + HashSet<String> font_names; + Vector<String> ret; + + FcConfig *config = FcInitLoadConfigAndFonts(); + ERR_FAIL_COND_V(!config, ret); + + FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, nullptr); + ERR_FAIL_COND_V(!object_set, ret); + + static const char *allowed_formats[] = { "TrueType", "CFF" }; + for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { + FcPattern *pattern = FcPatternCreate(); + ERR_CONTINUE(!pattern); + + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast<const FcChar8 *>(allowed_formats[i])); + + FcFontSet *font_set = FcFontList(config, pattern, object_set); + if (font_set) { + for (int j = 0; j < font_set->nfont; j++) { + char *family_name = nullptr; + if (FcPatternGetString(font_set->fonts[j], FC_FAMILY, 0, reinterpret_cast<FcChar8 **>(&family_name)) == FcResultMatch) { + if (family_name) { + font_names.insert(String::utf8(family_name)); + } + } + } + FcFontSetDestroy(font_set); + } + FcPatternDestroy(pattern); + } + FcObjectSetDestroy(object_set); + + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +#else + ERR_FAIL_V_MSG(Vector<String>(), "Godot was compiled without fontconfig, system font support is disabled."); +#endif +} + +String OS_LinuxBSD::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { +#ifdef FONTCONFIG_ENABLED + if (!font_config_initialized) { + ERR_FAIL_V_MSG(String(), "Unable to load fontconfig, system font support is disabled."); + } + + String ret; + + FcConfig *config = FcInitLoadConfigAndFonts(); + ERR_FAIL_COND_V(!config, ret); + + FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, FC_FILE, nullptr); + ERR_FAIL_COND_V(!object_set, ret); + + FcPattern *pattern = FcPatternCreate(); + if (pattern) { + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data())); + FcPatternAddInteger(pattern, FC_WEIGHT, p_bold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL); + FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + char *file_name = nullptr; + if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) { + if (file_name) { + ret = String::utf8(file_name); + } + } + + FcPatternDestroy(match); + } + FcPatternDestroy(pattern); + } + FcObjectSetDestroy(object_set); + return ret; +#else + ERR_FAIL_V_MSG(String(), "Godot was compiled without fontconfig, system font support is disabled."); +#endif +} + String OS_LinuxBSD::get_config_path() const { if (has_environment("XDG_CONFIG_HOME")) { if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) { @@ -644,4 +740,13 @@ OS_LinuxBSD::OS_LinuxBSD() { #ifdef X11_ENABLED DisplayServerX11::register_x11_driver(); #endif + +#ifdef FONTCONFIG_ENABLED +#ifdef DEBUG_ENABLED + int dylibloader_verbose = 1; +#else + int dylibloader_verbose = 0; +#endif + font_config_initialized = (initialize_fontconfig(dylibloader_verbose) == 0); +#endif // FONTCONFIG_ENABLED } diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index 3f97b86eae..cc4e91e885 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -45,6 +45,10 @@ class OS_LinuxBSD : public OS_Unix { bool force_quit; +#ifdef FONTCONFIG_ENABLED + bool font_config_initialized = false; +#endif + #ifdef JOYDEV_ENABLED JoypadLinux *joypad = nullptr; #endif @@ -80,6 +84,9 @@ public: virtual uint64_t get_embedded_pck_offset() const override; + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual String get_config_path() const override; virtual String get_data_path() const override; virtual String get_cache_path() const override; @@ -105,4 +112,4 @@ public: OS_LinuxBSD(); }; -#endif +#endif // OS_LINUXBSD_H diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h index a89afa2eff..0c4a6cd278 100644 --- a/platform/linuxbsd/vulkan_context_x11.h +++ b/platform/linuxbsd/vulkan_context_x11.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VULKAN_DEVICE_X11_H -#define VULKAN_DEVICE_X11_H +#ifndef VULKAN_CONTEXT_X11_H +#define VULKAN_CONTEXT_X11_H #include "drivers/vulkan/vulkan_context.h" #include <X11/Xlib.h> @@ -44,4 +44,4 @@ public: ~VulkanContextX11(); }; -#endif // VULKAN_DEVICE_X11_H +#endif // VULKAN_CONTEXT_X11_H diff --git a/platform/macos/SCsub b/platform/macos/SCsub new file mode 100644 index 0000000000..d0856c709a --- /dev/null +++ b/platform/macos/SCsub @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +Import("env") + +from platform_methods import run_in_subprocess +import platform_macos_builders + +files = [ + "os_macos.mm", + "godot_application.mm", + "godot_application_delegate.mm", + "crash_handler_macos.mm", + "macos_terminal_logger.mm", + "display_server_macos.mm", + "godot_content_view.mm", + "godot_window_delegate.mm", + "godot_window.mm", + "key_mapping_macos.mm", + "godot_main_macos.mm", + "dir_access_macos.mm", + "tts_macos.mm", + "joypad_macos.cpp", + "vulkan_context_macos.mm", + "gl_manager_macos_legacy.mm", +] + +prog = env.add_program("#bin/godot", files) + +if env["debug_symbols"] and env["separate_debug_symbols"]: + env.AddPostAction(prog, run_in_subprocess(platform_macos_builders.make_debug_macos)) diff --git a/platform/osx/crash_handler_osx.h b/platform/macos/crash_handler_macos.h index 72938e5e0a..c9b0e77dc4 100644 --- a/platform/osx/crash_handler_osx.h +++ b/platform/macos/crash_handler_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* crash_handler_osx.h */ +/* crash_handler_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CRASH_HANDLER_OSX_H -#define CRASH_HANDLER_OSX_H +#ifndef CRASH_HANDLER_MACOS_H +#define CRASH_HANDLER_MACOS_H class CrashHandler { bool disabled; @@ -44,4 +44,4 @@ public: ~CrashHandler(); }; -#endif // CRASH_HANDLER_OSX_H +#endif // CRASH_HANDLER_MACOS_H diff --git a/platform/osx/crash_handler_osx.mm b/platform/macos/crash_handler_macos.mm index a798ba3b46..74bd012f0c 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/macos/crash_handler_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* crash_handler_osx.mm */ +/* crash_handler_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "crash_handler_osx.h" +#include "crash_handler_macos.h" #include "core/config/project_settings.h" #include "core/os/os.h" diff --git a/platform/osx/detect.py b/platform/macos/detect.py index 47765cff71..20e7afa772 100644 --- a/platform/osx/detect.py +++ b/platform/macos/detect.py @@ -8,7 +8,7 @@ def is_active(): def get_name(): - return "OSX" + return "macOS" def can_build(): @@ -98,7 +98,7 @@ def configure(env): ## Architecture - # Mac OS X no longer runs on 32-bit since 10.7 which is unsupported since 2014 + # macOS no longer runs on 32-bit since 10.7 which is unsupported since 2014 # As such, we only support 64-bit env["bits"] = "64" @@ -134,7 +134,7 @@ def configure(env): env["CC"] = "clang" env["CXX"] = "clang++" - detect_darwin_sdk_path("osx", env) + detect_darwin_sdk_path("macos", env) env.Append(CCFLAGS=["-isysroot", "$MACOS_SDK_PATH"]) env.Append(LINKFLAGS=["-isysroot", "$MACOS_SDK_PATH"]) @@ -191,8 +191,10 @@ def configure(env): ## Flags - env.Prepend(CPPPATH=["#platform/osx"]) - env.Append(CPPDEFINES=["OSX_ENABLED", "UNIX_ENABLED", "APPLE_STYLE_KEYS", "COREAUDIO_ENABLED", "COREMIDI_ENABLED"]) + env.Prepend(CPPPATH=["#platform/macos"]) + env.Append( + CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED", "APPLE_STYLE_KEYS", "COREAUDIO_ENABLED", "COREMIDI_ENABLED"] + ) env.Append( LINKFLAGS=[ "-framework", diff --git a/platform/osx/dir_access_osx.h b/platform/macos/dir_access_macos.h index 3c66c81d4f..1ac1b995de 100644 --- a/platform/osx/dir_access_osx.h +++ b/platform/macos/dir_access_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* dir_access_osx.h */ +/* dir_access_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef DIR_ACCESS_OSX_H -#define DIR_ACCESS_OSX_H +#ifndef DIR_ACCESS_MACOS_H +#define DIR_ACCESS_MACOS_H #if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED) @@ -41,7 +41,7 @@ #include "core/io/dir_access.h" #include "drivers/unix/dir_access_unix.h" -class DirAccessOSX : public DirAccessUnix { +class DirAccessMacOS : public DirAccessUnix { protected: virtual String fix_unicode_name(const char *p_name) const; @@ -51,5 +51,6 @@ protected: virtual bool is_hidden(const String &p_name); }; -#endif //UNIX ENABLED -#endif +#endif // UNIX ENABLED || LIBC_FILEIO_ENABLED + +#endif // DIR_ACCESS_MACOS_H diff --git a/platform/osx/dir_access_osx.mm b/platform/macos/dir_access_macos.mm index 6bafb9470d..94d937a7dc 100644 --- a/platform/osx/dir_access_osx.mm +++ b/platform/macos/dir_access_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* dir_access_osx.mm */ +/* dir_access_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "dir_access_osx.h" +#include "dir_access_macos.h" #if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED) @@ -37,7 +37,7 @@ #import <AppKit/NSWorkspace.h> #import <Foundation/Foundation.h> -String DirAccessOSX::fix_unicode_name(const char *p_name) const { +String DirAccessMacOS::fix_unicode_name(const char *p_name) const { String fname; NSString *nsstr = [[NSString stringWithUTF8String:p_name] precomposedStringWithCanonicalMapping]; @@ -46,14 +46,14 @@ String DirAccessOSX::fix_unicode_name(const char *p_name) const { return fname; } -int DirAccessOSX::get_drive_count() { +int DirAccessMacOS::get_drive_count() { NSArray *res_keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsSystemImmutableKey, nil]; NSArray *vols = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:res_keys options:NSVolumeEnumerationSkipHiddenVolumes]; return [vols count]; } -String DirAccessOSX::get_drive(int p_drive) { +String DirAccessMacOS::get_drive(int p_drive) { NSArray *res_keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsSystemImmutableKey, nil]; NSArray *vols = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:res_keys options:NSVolumeEnumerationSkipHiddenVolumes]; int count = [vols count]; @@ -68,7 +68,7 @@ String DirAccessOSX::get_drive(int p_drive) { return volname; } -bool DirAccessOSX::is_hidden(const String &p_name) { +bool DirAccessMacOS::is_hidden(const String &p_name) { String f = get_current_dir().plus_file(p_name); NSURL *url = [NSURL fileURLWithPath:@(f.utf8().get_data())]; NSNumber *hidden = nil; @@ -78,4 +78,4 @@ bool DirAccessOSX::is_hidden(const String &p_name) { return [hidden boolValue]; } -#endif //posix_enabled +#endif // UNIX_ENABLED || LIBC_FILEIO_ENABLED diff --git a/platform/osx/display_server_osx.h b/platform/macos/display_server_macos.h index 9575cb29a2..41031ec81b 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/macos/display_server_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* display_server_osx.h */ +/* display_server_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef DISPLAY_SERVER_OSX_H -#define DISPLAY_SERVER_OSX_H +#ifndef DISPLAY_SERVER_MACOS_H +#define DISPLAY_SERVER_MACOS_H #define BitMap _QDBitMap // Suppress deprecated QuickDraw definition. @@ -37,12 +37,12 @@ #include "servers/display_server.h" #if defined(GLES3_ENABLED) -#include "gl_manager_osx_legacy.h" +#include "gl_manager_macos_legacy.h" #endif // GLES3_ENABLED #if defined(VULKAN_ENABLED) #include "drivers/vulkan/rendering_device_vulkan.h" -#include "platform/osx/vulkan_context_osx.h" +#include "platform/macos/vulkan_context_macos.h" #endif // VULKAN_ENABLED #import <AppKit/AppKit.h> @@ -54,15 +54,15 @@ #undef BitMap #undef CursorShape -class DisplayServerOSX : public DisplayServer { - GDCLASS(DisplayServerOSX, DisplayServer) +class DisplayServerMacOS : public DisplayServer { + GDCLASS(DisplayServerMacOS, DisplayServer) _THREAD_SAFE_CLASS_ public: struct KeyEvent { WindowID window_id = INVALID_WINDOW_ID; - unsigned int osx_state = false; + unsigned int macos_state = false; bool pressed = false; bool echo = false; bool raw = false; @@ -115,10 +115,10 @@ public: private: #if defined(GLES3_ENABLED) - GLManager_OSX *gl_manager = nullptr; + GLManager_MacOS *gl_manager = nullptr; #endif #if defined(VULKAN_ENABLED) - VulkanContextOSX *context_vulkan = nullptr; + VulkanContextMacOS *context_vulkan = nullptr; RenderingDeviceVulkan *rendering_device_vulkan = nullptr; #endif String rendering_driver; @@ -203,7 +203,7 @@ public: void send_event(NSEvent *p_event); void send_window_event(const WindowData &p_wd, WindowEvent p_event); void release_pressed_events(); - void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) const; + void get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const; void update_mouse_pos(WindowData &p_wd, NSPoint p_location_in_window); void push_to_key_event_buffer(const KeyEvent &p_event); void update_im_text(const Point2i &p_selection, const String &p_text); @@ -397,10 +397,10 @@ public: static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); static Vector<String> get_rendering_drivers_func(); - static void register_osx_driver(); + static void register_macos_driver(); - DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); - ~DisplayServerOSX(); + DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error); + ~DisplayServerMacOS(); }; -#endif // DISPLAY_SERVER_OSX_H +#endif // DISPLAY_SERVER_MACOS_H diff --git a/platform/osx/display_server_osx.mm b/platform/macos/display_server_macos.mm index 11474dac46..07ba5d7497 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/macos/display_server_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* display_server_osx.mm */ +/* display_server_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,16 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "display_server_osx.h" +#include "display_server_macos.h" #include "godot_content_view.h" #include "godot_menu_item.h" #include "godot_window.h" #include "godot_window_delegate.h" -#include "key_mapping_osx.h" -#include "os_osx.h" +#include "key_mapping_macos.h" +#include "os_macos.h" -#include "tts_osx.h" +#include "tts_macos.h" #include "core/io/marshalls.h" #include "core/math/geometry_2d.h" @@ -60,7 +60,7 @@ #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #endif -const NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) const { +const NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) const { const NSMenu *menu = nullptr; if (p_menu_root == "") { // Main menu. @@ -81,7 +81,7 @@ const NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) const return menu; } -NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) { +NSMenu *DisplayServerMacOS::_get_menu_root(const String &p_menu_root) { NSMenu *menu = nullptr; if (p_menu_root == "") { // Main menu. @@ -105,7 +105,7 @@ NSMenu *DisplayServerOSX::_get_menu_root(const String &p_menu_root) { return menu; } -DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) { +DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect) { WindowID id; const float scale = screen_get_max_scale(); { @@ -193,7 +193,7 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V return id; } -void DisplayServerOSX::_update_window_style(WindowData p_wd) { +void DisplayServerMacOS::_update_window_style(WindowData p_wd) { bool borderless_full = false; if (p_wd.borderless) { @@ -222,7 +222,7 @@ void DisplayServerOSX::_update_window_style(WindowData p_wd) { } } -void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) { +void DisplayServerMacOS::_set_window_per_pixel_transparency_enabled(bool p_enabled, WindowID p_window) { ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; @@ -267,7 +267,7 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled } } -void DisplayServerOSX::_update_displays_arrangement() { +void DisplayServerMacOS::_update_displays_arrangement() { origin = Point2i(); for (int i = 0; i < get_screen_count(); i++) { @@ -282,20 +282,20 @@ void DisplayServerOSX::_update_displays_arrangement() { displays_arrangement_dirty = false; } -Point2i DisplayServerOSX::_get_screens_origin() const { +Point2i DisplayServerMacOS::_get_screens_origin() const { // Returns the native top-left screen coordinate of the smallest rectangle // that encompasses all screens. Needed in get_screen_position(), // window_get_position, and window_set_position() // to convert between OS X native screen coordinates and the ones expected by Godot. if (displays_arrangement_dirty) { - const_cast<DisplayServerOSX *>(this)->_update_displays_arrangement(); + const_cast<DisplayServerMacOS *>(this)->_update_displays_arrangement(); } return origin; } -Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const { +Point2i DisplayServerMacOS::_get_native_screen_position(int p_screen) const { NSArray *screenArray = [NSScreen screens]; if ((NSUInteger)p_screen < [screenArray count]) { NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame]; @@ -306,18 +306,18 @@ Point2i DisplayServerOSX::_get_native_screen_position(int p_screen) const { return Point2i(); } -void DisplayServerOSX::_displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); +void DisplayServerMacOS::_displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplayChangeSummaryFlags flags, void *user_info) { + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { ds->displays_arrangement_dirty = true; } } -void DisplayServerOSX::_dispatch_input_events(const Ref<InputEvent> &p_event) { - ((DisplayServerOSX *)(get_singleton()))->_dispatch_input_event(p_event); +void DisplayServerMacOS::_dispatch_input_events(const Ref<InputEvent> &p_event) { + ((DisplayServerMacOS *)(get_singleton()))->_dispatch_input_event(p_event); } -void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) { +void DisplayServerMacOS::_dispatch_input_event(const Ref<InputEvent> &p_event) { _THREAD_SAFE_METHOD_ if (!in_dispatch_input_event) { in_dispatch_input_event = true; @@ -364,12 +364,12 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) { } } -void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { +void DisplayServerMacOS::_push_input(const Ref<InputEvent> &p_event) { Ref<InputEvent> ev = p_event; Input::get_singleton()->parse_input_event(ev); } -void DisplayServerOSX::_process_key_events() { +void DisplayServerMacOS::_process_key_events() { Ref<InputEventKey> k; for (int i = 0; i < key_event_pos; i++) { const KeyEvent &ke = key_event_buffer[i]; @@ -378,7 +378,7 @@ void DisplayServerOSX::_process_key_events() { k.instantiate(); k->set_window_id(ke.window_id); - get_key_modifier_state(ke.osx_state, k); + get_key_modifier_state(ke.macos_state, k); k->set_pressed(ke.pressed); k->set_echo(ke.echo); k->set_keycode(ke.keycode); @@ -392,7 +392,7 @@ void DisplayServerOSX::_process_key_events() { k.instantiate(); k->set_window_id(ke.window_id); - get_key_modifier_state(ke.osx_state, k); + get_key_modifier_state(ke.macos_state, k); k->set_pressed(ke.pressed); k->set_echo(ke.echo); k->set_keycode(Key::NONE); @@ -405,7 +405,7 @@ void DisplayServerOSX::_process_key_events() { k.instantiate(); k->set_window_id(ke.window_id); - get_key_modifier_state(ke.osx_state, k); + get_key_modifier_state(ke.macos_state, k); k->set_pressed(ke.pressed); k->set_echo(ke.echo); k->set_keycode(ke.keycode); @@ -423,7 +423,7 @@ void DisplayServerOSX::_process_key_events() { key_event_pos = 0; } -void DisplayServerOSX::_update_keyboard_layouts() { +void DisplayServerMacOS::_update_keyboard_layouts() { kbd_layouts.clear(); current_layout = 0; @@ -468,14 +468,14 @@ void DisplayServerOSX::_update_keyboard_layouts() { keyboard_layout_dirty = false; } -void DisplayServerOSX::_keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); +void DisplayServerMacOS::_keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) { + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { ds->keyboard_layout_dirty = true; } } -NSImage *DisplayServerOSX::_convert_to_nsimg(Ref<Image> &p_image) const { +NSImage *DisplayServerMacOS::_convert_to_nsimg(Ref<Image> &p_image) const { p_image->convert(Image::FORMAT_RGBA8); NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL @@ -509,7 +509,7 @@ NSImage *DisplayServerOSX::_convert_to_nsimg(Ref<Image> &p_image) const { return nsimg; } -NSCursor *DisplayServerOSX::_cursor_from_selector(SEL p_selector, SEL p_fallback) { +NSCursor *DisplayServerMacOS::_cursor_from_selector(SEL p_selector, SEL p_fallback) { if ([NSCursor respondsToSelector:p_selector]) { id object = [NSCursor performSelector:p_selector]; if ([object isKindOfClass:[NSCursor class]]) { @@ -523,11 +523,11 @@ NSCursor *DisplayServerOSX::_cursor_from_selector(SEL p_selector, SEL p_fallback return [NSCursor arrowCursor]; } -NSMenu *DisplayServerOSX::get_dock_menu() const { +NSMenu *DisplayServerMacOS::get_dock_menu() const { return dock_menu; } -void DisplayServerOSX::menu_callback(id p_sender) { +void DisplayServerMacOS::menu_callback(id p_sender) { if (![p_sender representedObject]) { return; } @@ -560,15 +560,15 @@ void DisplayServerOSX::menu_callback(id p_sender) { } } -bool DisplayServerOSX::has_window(WindowID p_window) const { +bool DisplayServerMacOS::has_window(WindowID p_window) const { return windows.has(p_window); } -DisplayServerOSX::WindowData &DisplayServerOSX::get_window(WindowID p_window) { +DisplayServerMacOS::WindowData &DisplayServerMacOS::get_window(WindowID p_window) { return windows[p_window]; } -void DisplayServerOSX::send_event(NSEvent *p_event) { +void DisplayServerMacOS::send_event(NSEvent *p_event) { // Special case handling of command-period, which is traditionally a special // shortcut in macOS and doesn't arrive at our regular keyDown handler. if ([p_event type] == NSEventTypeKeyDown) { @@ -577,7 +577,7 @@ void DisplayServerOSX::send_event(NSEvent *p_event) { k.instantiate(); get_key_modifier_state([p_event modifierFlags], k); - k->set_window_id(DisplayServerOSX::INVALID_WINDOW_ID); + k->set_window_id(DisplayServerMacOS::INVALID_WINDOW_ID); k->set_pressed(true); k->set_keycode(Key::PERIOD); k->set_physical_keycode(Key::PERIOD); @@ -588,7 +588,7 @@ void DisplayServerOSX::send_event(NSEvent *p_event) { } } -void DisplayServerOSX::send_window_event(const WindowData &wd, WindowEvent p_event) { +void DisplayServerMacOS::send_window_event(const WindowData &wd, WindowEvent p_event) { _THREAD_SAFE_METHOD_ if (!wd.event_callback.is_null()) { @@ -600,21 +600,21 @@ void DisplayServerOSX::send_window_event(const WindowData &wd, WindowEvent p_eve } } -void DisplayServerOSX::release_pressed_events() { +void DisplayServerMacOS::release_pressed_events() { _THREAD_SAFE_METHOD_ if (Input::get_singleton()) { Input::get_singleton()->release_pressed_events(); } } -void DisplayServerOSX::get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) const { - r_state->set_shift_pressed((p_osx_state & NSEventModifierFlagShift)); - r_state->set_ctrl_pressed((p_osx_state & NSEventModifierFlagControl)); - r_state->set_alt_pressed((p_osx_state & NSEventModifierFlagOption)); - r_state->set_meta_pressed((p_osx_state & NSEventModifierFlagCommand)); +void DisplayServerMacOS::get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const { + r_state->set_shift_pressed((p_macos_state & NSEventModifierFlagShift)); + r_state->set_ctrl_pressed((p_macos_state & NSEventModifierFlagControl)); + r_state->set_alt_pressed((p_macos_state & NSEventModifierFlagOption)); + r_state->set_meta_pressed((p_macos_state & NSEventModifierFlagCommand)); } -void DisplayServerOSX::update_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_location_in_window) { +void DisplayServerMacOS::update_mouse_pos(DisplayServerMacOS::WindowData &p_wd, NSPoint p_location_in_window) { const NSRect content_rect = [p_wd.window_view frame]; const float scale = screen_get_max_scale(); p_wd.mouse_pos.x = p_location_in_window.x * scale; @@ -622,33 +622,33 @@ void DisplayServerOSX::update_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPo Input::get_singleton()->set_mouse_position(p_wd.mouse_pos); } -void DisplayServerOSX::push_to_key_event_buffer(const DisplayServerOSX::KeyEvent &p_event) { +void DisplayServerMacOS::push_to_key_event_buffer(const DisplayServerMacOS::KeyEvent &p_event) { if (key_event_pos >= key_event_buffer.size()) { key_event_buffer.resize(1 + key_event_pos); } key_event_buffer.write[key_event_pos++] = p_event; } -void DisplayServerOSX::update_im_text(const Point2i &p_selection, const String &p_text) { +void DisplayServerMacOS::update_im_text(const Point2i &p_selection, const String &p_text) { im_selection = p_selection; im_text = p_text; OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE); } -void DisplayServerOSX::set_last_focused_window(WindowID p_window) { +void DisplayServerMacOS::set_last_focused_window(WindowID p_window) { last_focused_window = p_window; } -void DisplayServerOSX::set_is_resizing(bool p_is_resizing) { +void DisplayServerMacOS::set_is_resizing(bool p_is_resizing) { is_resizing = p_is_resizing; } -bool DisplayServerOSX::get_is_resizing() const { +bool DisplayServerMacOS::get_is_resizing() const { return is_resizing; } -void DisplayServerOSX::window_update(WindowID p_window) { +void DisplayServerMacOS::window_update(WindowID p_window) { #if defined(GLES3_ENABLED) if (gl_manager) { gl_manager->window_update(p_window); @@ -656,7 +656,7 @@ void DisplayServerOSX::window_update(WindowID p_window) { #endif } -void DisplayServerOSX::window_destroy(WindowID p_window) { +void DisplayServerMacOS::window_destroy(WindowID p_window) { #if defined(GLES3_ENABLED) if (gl_manager) { gl_manager->window_destroy(p_window); @@ -670,7 +670,7 @@ void DisplayServerOSX::window_destroy(WindowID p_window) { windows.erase(p_window); } -void DisplayServerOSX::window_resize(WindowID p_window, int p_width, int p_height) { +void DisplayServerMacOS::window_resize(WindowID p_window, int p_width, int p_height) { #if defined(GLES3_ENABLED) if (gl_manager) { gl_manager->window_resize(p_window, p_width, p_height); @@ -683,7 +683,7 @@ void DisplayServerOSX::window_resize(WindowID p_window, int p_width, int p_heigh #endif } -bool DisplayServerOSX::has_feature(Feature p_feature) const { +bool DisplayServerMacOS::has_feature(Feature p_feature) const { switch (p_feature) { case FEATURE_GLOBAL_MENU: case FEATURE_SUBWINDOWS: @@ -709,16 +709,16 @@ bool DisplayServerOSX::has_feature(Feature p_feature) const { return false; } -String DisplayServerOSX::get_name() const { - return "OSX"; +String DisplayServerMacOS::get_name() const { + return "macOS"; } -void DisplayServerOSX::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +void DisplayServerMacOS::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { - String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); + String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); NSMenuItem *menu_item; if (p_index != -1) { menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; @@ -731,17 +731,17 @@ void DisplayServerOSX::global_menu_add_item(const String &p_menu_root, const Str obj->checkable_type = CHECKABLE_TYPE_NONE; obj->max_states = 0; obj->state = 0; - [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)]; + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } } -void DisplayServerOSX::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +void DisplayServerMacOS::global_menu_add_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { - String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); + String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); NSMenuItem *menu_item; if (p_index != -1) { menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; @@ -754,17 +754,17 @@ void DisplayServerOSX::global_menu_add_check_item(const String &p_menu_root, con obj->checkable_type = CHECKABLE_TYPE_CHECK_BOX; obj->max_states = 0; obj->state = 0; - [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)]; + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } } -void DisplayServerOSX::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +void DisplayServerMacOS::global_menu_add_icon_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { - String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); + String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); NSMenuItem *menu_item; if (p_index != -1) { menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; @@ -786,17 +786,17 @@ void DisplayServerOSX::global_menu_add_icon_item(const String &p_menu_root, cons obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS); [menu_item setImage:_convert_to_nsimg(obj->img)]; } - [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)]; + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } } -void DisplayServerOSX::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +void DisplayServerMacOS::global_menu_add_icon_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { - String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); + String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); NSMenuItem *menu_item; if (p_index != -1) { menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; @@ -818,17 +818,17 @@ void DisplayServerOSX::global_menu_add_icon_check_item(const String &p_menu_root obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS); [menu_item setImage:_convert_to_nsimg(obj->img)]; } - [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)]; + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } } -void DisplayServerOSX::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +void DisplayServerMacOS::global_menu_add_radio_check_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { - String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); + String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); NSMenuItem *menu_item; if (p_index != -1) { menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; @@ -841,17 +841,17 @@ void DisplayServerOSX::global_menu_add_radio_check_item(const String &p_menu_roo obj->checkable_type = CHECKABLE_TYPE_RADIO_BUTTON; obj->max_states = 0; obj->state = 0; - [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)]; + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } } -void DisplayServerOSX::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +void DisplayServerMacOS::global_menu_add_icon_radio_check_item(const String &p_menu_root, const Ref<Texture2D> &p_icon, const String &p_label, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { - String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); + String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); NSMenuItem *menu_item; if (p_index != -1) { menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; @@ -873,17 +873,17 @@ void DisplayServerOSX::global_menu_add_icon_radio_check_item(const String &p_men obj->img->resize(16, 16, Image::INTERPOLATE_LANCZOS); [menu_item setImage:_convert_to_nsimg(obj->img)]; } - [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)]; + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } } -void DisplayServerOSX::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { +void DisplayServerMacOS::global_menu_add_multistate_item(const String &p_menu_root, const String &p_label, int p_max_states, int p_default_state, const Callable &p_callback, const Variant &p_tag, Key p_accel, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); if (menu) { - String keycode = KeyMappingOSX::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); + String keycode = KeyMappingMacOS::keycode_get_native_string(p_accel & KeyModifierMask::CODE_MASK); NSMenuItem *menu_item; if (p_index != -1) { menu_item = [menu insertItemWithTitle:[NSString stringWithUTF8String:p_label.utf8().get_data()] action:@selector(globalMenuCallback:) keyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()] atIndex:p_index]; @@ -896,12 +896,12 @@ void DisplayServerOSX::global_menu_add_multistate_item(const String &p_menu_root obj->checkable_type = CHECKABLE_TYPE_NONE; obj->max_states = p_max_states; obj->state = p_default_state; - [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_accel)]; + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_accel)]; [menu_item setRepresentedObject:obj]; } } -void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index) { +void DisplayServerMacOS::global_menu_add_submenu_item(const String &p_menu_root, const String &p_label, const String &p_submenu, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -926,7 +926,7 @@ void DisplayServerOSX::global_menu_add_submenu_item(const String &p_menu_root, c } } -void DisplayServerOSX::global_menu_add_separator(const String &p_menu_root, int p_index) { +void DisplayServerMacOS::global_menu_add_separator(const String &p_menu_root, int p_index) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -939,7 +939,7 @@ void DisplayServerOSX::global_menu_add_separator(const String &p_menu_root, int } } -int DisplayServerOSX::global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const { +int DisplayServerMacOS::global_menu_get_item_index_from_text(const String &p_menu_root, const String &p_text) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -950,7 +950,7 @@ int DisplayServerOSX::global_menu_get_item_index_from_text(const String &p_menu_ return -1; } -int DisplayServerOSX::global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const { +int DisplayServerMacOS::global_menu_get_item_index_from_tag(const String &p_menu_root, const Variant &p_tag) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -969,7 +969,7 @@ int DisplayServerOSX::global_menu_get_item_index_from_tag(const String &p_menu_r return -1; } -bool DisplayServerOSX::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const { +bool DisplayServerMacOS::global_menu_is_item_checked(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -982,7 +982,7 @@ bool DisplayServerOSX::global_menu_is_item_checked(const String &p_menu_root, in return false; } -bool DisplayServerOSX::global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const { +bool DisplayServerMacOS::global_menu_is_item_checkable(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -998,7 +998,7 @@ bool DisplayServerOSX::global_menu_is_item_checkable(const String &p_menu_root, return false; } -bool DisplayServerOSX::global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const { +bool DisplayServerMacOS::global_menu_is_item_radio_checkable(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1014,7 +1014,7 @@ bool DisplayServerOSX::global_menu_is_item_radio_checkable(const String &p_menu_ return false; } -Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_root, int p_idx) const { +Callable DisplayServerMacOS::global_menu_get_item_callback(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1030,7 +1030,7 @@ Callable DisplayServerOSX::global_menu_get_item_callback(const String &p_menu_ro return Callable(); } -Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const { +Variant DisplayServerMacOS::global_menu_get_item_tag(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1046,7 +1046,7 @@ Variant DisplayServerOSX::global_menu_get_item_tag(const String &p_menu_root, in return Variant(); } -String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, int p_idx) const { +String DisplayServerMacOS::global_menu_get_item_text(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1059,7 +1059,7 @@ String DisplayServerOSX::global_menu_get_item_text(const String &p_menu_root, in return String(); } -String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const { +String DisplayServerMacOS::global_menu_get_item_submenu(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1079,7 +1079,7 @@ String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root, return String(); } -Key DisplayServerOSX::global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const { +Key DisplayServerMacOS::global_menu_get_item_accelerator(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1110,7 +1110,7 @@ Key DisplayServerOSX::global_menu_get_item_accelerator(const String &p_menu_root return Key::NONE; } -bool DisplayServerOSX::global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const { +bool DisplayServerMacOS::global_menu_is_item_disabled(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1123,7 +1123,7 @@ bool DisplayServerOSX::global_menu_is_item_disabled(const String &p_menu_root, i return false; } -String DisplayServerOSX::global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const { +String DisplayServerMacOS::global_menu_get_item_tooltip(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1136,7 +1136,7 @@ String DisplayServerOSX::global_menu_get_item_tooltip(const String &p_menu_root, return String(); } -int DisplayServerOSX::global_menu_get_item_state(const String &p_menu_root, int p_idx) const { +int DisplayServerMacOS::global_menu_get_item_state(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1152,7 +1152,7 @@ int DisplayServerOSX::global_menu_get_item_state(const String &p_menu_root, int return 0; } -int DisplayServerOSX::global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const { +int DisplayServerMacOS::global_menu_get_item_max_states(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1168,7 +1168,7 @@ int DisplayServerOSX::global_menu_get_item_max_states(const String &p_menu_root, return 0; } -Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_root, int p_idx) const { +Ref<Texture2D> DisplayServerMacOS::global_menu_get_item_icon(const String &p_menu_root, int p_idx) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1186,7 +1186,7 @@ Ref<Texture2D> DisplayServerOSX::global_menu_get_item_icon(const String &p_menu_ return Ref<Texture2D>(); } -void DisplayServerOSX::global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) { +void DisplayServerMacOS::global_menu_set_item_checked(const String &p_menu_root, int p_idx, bool p_checked) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1205,7 +1205,7 @@ void DisplayServerOSX::global_menu_set_item_checked(const String &p_menu_root, i } } -void DisplayServerOSX::global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) { +void DisplayServerMacOS::global_menu_set_item_checkable(const String &p_menu_root, int p_idx, bool p_checkable) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1221,7 +1221,7 @@ void DisplayServerOSX::global_menu_set_item_checkable(const String &p_menu_root, } } -void DisplayServerOSX::global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) { +void DisplayServerMacOS::global_menu_set_item_radio_checkable(const String &p_menu_root, int p_idx, bool p_checkable) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1237,7 +1237,7 @@ void DisplayServerOSX::global_menu_set_item_radio_checkable(const String &p_menu } } -void DisplayServerOSX::global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) { +void DisplayServerMacOS::global_menu_set_item_callback(const String &p_menu_root, int p_idx, const Callable &p_callback) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1253,7 +1253,7 @@ void DisplayServerOSX::global_menu_set_item_callback(const String &p_menu_root, } } -void DisplayServerOSX::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) { +void DisplayServerMacOS::global_menu_set_item_tag(const String &p_menu_root, int p_idx, const Variant &p_tag) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1269,7 +1269,7 @@ void DisplayServerOSX::global_menu_set_item_tag(const String &p_menu_root, int p } } -void DisplayServerOSX::global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) { +void DisplayServerMacOS::global_menu_set_item_text(const String &p_menu_root, int p_idx, const String &p_text) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1284,7 +1284,7 @@ void DisplayServerOSX::global_menu_set_item_text(const String &p_menu_root, int } } -void DisplayServerOSX::global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) { +void DisplayServerMacOS::global_menu_set_item_submenu(const String &p_menu_root, int p_idx, const String &p_submenu) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1308,7 +1308,7 @@ void DisplayServerOSX::global_menu_set_item_submenu(const String &p_menu_root, i } } -void DisplayServerOSX::global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) { +void DisplayServerMacOS::global_menu_set_item_accelerator(const String &p_menu_root, int p_idx, Key p_keycode) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1318,14 +1318,14 @@ void DisplayServerOSX::global_menu_set_item_accelerator(const String &p_menu_roo } NSMenuItem *menu_item = [menu itemAtIndex:p_idx]; if (menu_item) { - [menu_item setKeyEquivalentModifierMask:KeyMappingOSX::keycode_get_native_mask(p_keycode)]; - String keycode = KeyMappingOSX::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK); + [menu_item setKeyEquivalentModifierMask:KeyMappingMacOS::keycode_get_native_mask(p_keycode)]; + String keycode = KeyMappingMacOS::keycode_get_native_string(p_keycode & KeyModifierMask::CODE_MASK); [menu_item setKeyEquivalent:[NSString stringWithUTF8String:keycode.utf8().get_data()]]; } } } -void DisplayServerOSX::global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) { +void DisplayServerMacOS::global_menu_set_item_disabled(const String &p_menu_root, int p_idx, bool p_disabled) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1340,7 +1340,7 @@ void DisplayServerOSX::global_menu_set_item_disabled(const String &p_menu_root, } } -void DisplayServerOSX::global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) { +void DisplayServerMacOS::global_menu_set_item_tooltip(const String &p_menu_root, int p_idx, const String &p_tooltip) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1355,7 +1355,7 @@ void DisplayServerOSX::global_menu_set_item_tooltip(const String &p_menu_root, i } } -void DisplayServerOSX::global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) { +void DisplayServerMacOS::global_menu_set_item_state(const String &p_menu_root, int p_idx, int p_state) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1373,7 +1373,7 @@ void DisplayServerOSX::global_menu_set_item_state(const String &p_menu_root, int } } -void DisplayServerOSX::global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) { +void DisplayServerMacOS::global_menu_set_item_max_states(const String &p_menu_root, int p_idx, int p_max_states) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1391,7 +1391,7 @@ void DisplayServerOSX::global_menu_set_item_max_states(const String &p_menu_root } } -void DisplayServerOSX::global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) { +void DisplayServerMacOS::global_menu_set_item_icon(const String &p_menu_root, int p_idx, const Ref<Texture2D> &p_icon) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1418,7 +1418,7 @@ void DisplayServerOSX::global_menu_set_item_icon(const String &p_menu_root, int } } -int DisplayServerOSX::global_menu_get_item_count(const String &p_menu_root) const { +int DisplayServerMacOS::global_menu_get_item_count(const String &p_menu_root) const { _THREAD_SAFE_METHOD_ const NSMenu *menu = _get_menu_root(p_menu_root); @@ -1429,7 +1429,7 @@ int DisplayServerOSX::global_menu_get_item_count(const String &p_menu_root) cons } } -void DisplayServerOSX::global_menu_remove_item(const String &p_menu_root, int p_idx) { +void DisplayServerMacOS::global_menu_remove_item(const String &p_menu_root, int p_idx) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1441,7 +1441,7 @@ void DisplayServerOSX::global_menu_remove_item(const String &p_menu_root, int p_ } } -void DisplayServerOSX::global_menu_clear(const String &p_menu_root) { +void DisplayServerMacOS::global_menu_clear(const String &p_menu_root) { _THREAD_SAFE_METHOD_ NSMenu *menu = _get_menu_root(p_menu_root); @@ -1455,42 +1455,42 @@ void DisplayServerOSX::global_menu_clear(const String &p_menu_root) { } } -bool DisplayServerOSX::tts_is_speaking() const { +bool DisplayServerMacOS::tts_is_speaking() const { ERR_FAIL_COND_V(!tts, false); return [tts isSpeaking]; } -bool DisplayServerOSX::tts_is_paused() const { +bool DisplayServerMacOS::tts_is_paused() const { ERR_FAIL_COND_V(!tts, false); return [tts isPaused]; } -Array DisplayServerOSX::tts_get_voices() const { +Array DisplayServerMacOS::tts_get_voices() const { ERR_FAIL_COND_V(!tts, Array()); return [tts getVoices]; } -void DisplayServerOSX::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { +void DisplayServerMacOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) { ERR_FAIL_COND(!tts); [tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt]; } -void DisplayServerOSX::tts_pause() { +void DisplayServerMacOS::tts_pause() { ERR_FAIL_COND(!tts); [tts pauseSpeaking]; } -void DisplayServerOSX::tts_resume() { +void DisplayServerMacOS::tts_resume() { ERR_FAIL_COND(!tts); [tts resumeSpeaking]; } -void DisplayServerOSX::tts_stop() { +void DisplayServerMacOS::tts_stop() { ERR_FAIL_COND(!tts); [tts stopSpeaking]; } -Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) { +Error DisplayServerMacOS::dialog_show(String p_title, String p_description, Vector<String> p_buttons, const Callable &p_callback) { _THREAD_SAFE_METHOD_ NSAlert *window = [[NSAlert alloc] init]; @@ -1528,7 +1528,7 @@ Error DisplayServerOSX::dialog_show(String p_title, String p_description, Vector return OK; } -Error DisplayServerOSX::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) { +Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) { _THREAD_SAFE_METHOD_ NSAlert *window = [[NSAlert alloc] init]; @@ -1560,7 +1560,7 @@ Error DisplayServerOSX::dialog_input_text(String p_title, String p_description, return OK; } -void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) { +void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) { _THREAD_SAFE_METHOD_ if (p_mode == mouse_mode) { @@ -1615,11 +1615,11 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) { } } -DisplayServer::MouseMode DisplayServerOSX::mouse_get_mode() const { +DisplayServer::MouseMode DisplayServerMacOS::mouse_get_mode() const { return mouse_mode; } -bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) { +bool DisplayServerMacOS::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) { _THREAD_SAFE_METHOD_ if (ignore_warp) { @@ -1641,7 +1641,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP List<WarpEvent>::Element *F = warp_events.front(); while (F) { if (F->get().timestamp < p_timestamp) { - List<DisplayServerOSX::WarpEvent>::Element *E = F; + List<DisplayServerMacOS::WarpEvent>::Element *E = F; r_delta.x -= E->get().delta.x; r_delta.y -= E->get().delta.y; F = F->next(); @@ -1669,7 +1669,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP // Save warp data. last_warp = [[NSProcessInfo processInfo] systemUptime]; - DisplayServerOSX::WarpEvent ev; + DisplayServerMacOS::WarpEvent ev; ev.timestamp = last_warp; ev.delta = r_delta; warp_events.push_back(ev); @@ -1678,7 +1678,7 @@ bool DisplayServerOSX::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSP return false; } -void DisplayServerOSX::warp_mouse(const Point2i &p_position) { +void DisplayServerMacOS::warp_mouse(const Point2i &p_position) { _THREAD_SAFE_METHOD_ if (mouse_mode != MOUSE_MODE_CAPTURED) { @@ -1705,7 +1705,7 @@ void DisplayServerOSX::warp_mouse(const Point2i &p_position) { } } -Point2i DisplayServerOSX::mouse_get_position() const { +Point2i DisplayServerMacOS::mouse_get_position() const { _THREAD_SAFE_METHOD_ const NSPoint mouse_pos = [NSEvent mouseLocation]; @@ -1724,15 +1724,15 @@ Point2i DisplayServerOSX::mouse_get_position() const { return Vector2i(); } -void DisplayServerOSX::mouse_set_button_state(MouseButton p_state) { +void DisplayServerMacOS::mouse_set_button_state(MouseButton p_state) { last_button_state = p_state; } -MouseButton DisplayServerOSX::mouse_get_button_state() const { +MouseButton DisplayServerMacOS::mouse_get_button_state() const { return last_button_state; } -void DisplayServerOSX::clipboard_set(const String &p_text) { +void DisplayServerMacOS::clipboard_set(const String &p_text) { _THREAD_SAFE_METHOD_ NSString *copiedString = [NSString stringWithUTF8String:p_text.utf8().get_data()]; @@ -1743,7 +1743,7 @@ void DisplayServerOSX::clipboard_set(const String &p_text) { [pasteboard writeObjects:copiedStringArray]; } -String DisplayServerOSX::clipboard_get() const { +String DisplayServerMacOS::clipboard_get() const { _THREAD_SAFE_METHOD_ NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; @@ -1764,14 +1764,14 @@ String DisplayServerOSX::clipboard_get() const { return ret; } -int DisplayServerOSX::get_screen_count() const { +int DisplayServerMacOS::get_screen_count() const { _THREAD_SAFE_METHOD_ NSArray *screenArray = [NSScreen screens]; return [screenArray count]; } -Point2i DisplayServerOSX::screen_get_position(int p_screen) const { +Point2i DisplayServerMacOS::screen_get_position(int p_screen) const { _THREAD_SAFE_METHOD_ if (p_screen == SCREEN_OF_MAIN_WINDOW) { @@ -1785,7 +1785,7 @@ Point2i DisplayServerOSX::screen_get_position(int p_screen) const { return position; } -Size2i DisplayServerOSX::screen_get_size(int p_screen) const { +Size2i DisplayServerMacOS::screen_get_size(int p_screen) const { _THREAD_SAFE_METHOD_ if (p_screen == SCREEN_OF_MAIN_WINDOW) { @@ -1802,7 +1802,7 @@ Size2i DisplayServerOSX::screen_get_size(int p_screen) const { return Size2i(); } -int DisplayServerOSX::screen_get_dpi(int p_screen) const { +int DisplayServerMacOS::screen_get_dpi(int p_screen) const { _THREAD_SAFE_METHOD_ if (p_screen == SCREEN_OF_MAIN_WINDOW) { @@ -1826,7 +1826,7 @@ int DisplayServerOSX::screen_get_dpi(int p_screen) const { return 72; } -float DisplayServerOSX::screen_get_scale(int p_screen) const { +float DisplayServerMacOS::screen_get_scale(int p_screen) const { _THREAD_SAFE_METHOD_ if (p_screen == SCREEN_OF_MAIN_WINDOW) { @@ -1844,14 +1844,14 @@ float DisplayServerOSX::screen_get_scale(int p_screen) const { return 1.f; } -float DisplayServerOSX::screen_get_max_scale() const { +float DisplayServerMacOS::screen_get_max_scale() const { _THREAD_SAFE_METHOD_ // Note: Do not update max display scale on screen configuration change, existing editor windows can't be rescaled on the fly. return display_max_scale; } -Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const { +Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const { _THREAD_SAFE_METHOD_ if (p_screen == SCREEN_OF_MAIN_WINDOW) { @@ -1873,7 +1873,7 @@ Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const { return Rect2i(); } -float DisplayServerOSX::screen_get_refresh_rate(int p_screen) const { +float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const { _THREAD_SAFE_METHOD_ if (p_screen == SCREEN_OF_MAIN_WINDOW) { @@ -1891,7 +1891,7 @@ float DisplayServerOSX::screen_get_refresh_rate(int p_screen) const { return SCREEN_REFRESH_RATE_FALLBACK; } -Vector<DisplayServer::WindowID> DisplayServerOSX::get_window_list() const { +Vector<DisplayServer::WindowID> DisplayServerMacOS::get_window_list() const { _THREAD_SAFE_METHOD_ Vector<int> ret; @@ -1901,7 +1901,7 @@ Vector<DisplayServer::WindowID> DisplayServerOSX::get_window_list() const { return ret; } -DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) { +DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) { _THREAD_SAFE_METHOD_ WindowID id = _create_window(p_mode, p_vsync_mode, p_rect); @@ -1914,7 +1914,7 @@ DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, V return id; } -void DisplayServerOSX::show_window(WindowID p_id) { +void DisplayServerMacOS::show_window(WindowID p_id) { WindowData &wd = windows[p_id]; popup_open(p_id); @@ -1925,7 +1925,7 @@ void DisplayServerOSX::show_window(WindowID p_id) { } } -void DisplayServerOSX::delete_sub_window(WindowID p_id) { +void DisplayServerMacOS::delete_sub_window(WindowID p_id) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_id)); @@ -1937,7 +1937,7 @@ void DisplayServerOSX::delete_sub_window(WindowID p_id) { [wd.window_object close]; } -void DisplayServerOSX::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerMacOS::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -1945,7 +1945,7 @@ void DisplayServerOSX::window_set_rect_changed_callback(const Callable &p_callab wd.rect_changed_callback = p_callable; } -void DisplayServerOSX::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerMacOS::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -1953,7 +1953,7 @@ void DisplayServerOSX::window_set_window_event_callback(const Callable &p_callab wd.event_callback = p_callable; } -void DisplayServerOSX::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerMacOS::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -1961,21 +1961,21 @@ void DisplayServerOSX::window_set_input_event_callback(const Callable &p_callabl wd.input_event_callback = p_callable; } -void DisplayServerOSX::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerMacOS::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; wd.input_text_callback = p_callable; } -void DisplayServerOSX::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) { +void DisplayServerMacOS::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; wd.drop_files_callback = p_callable; } -void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window) { +void DisplayServerMacOS::window_set_title(const String &p_title, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -1984,7 +1984,7 @@ void DisplayServerOSX::window_set_title(const String &p_title, WindowID p_window [wd.window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]]; } -void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) { +void DisplayServerMacOS::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -1993,7 +1993,7 @@ void DisplayServerOSX::window_set_mouse_passthrough(const Vector<Vector2> &p_reg wd.mpath = p_region; } -int DisplayServerOSX::window_get_current_screen(WindowID p_window) const { +int DisplayServerMacOS::window_get_current_screen(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), -1); const WindowData &wd = windows[p_window]; @@ -2002,7 +2002,7 @@ int DisplayServerOSX::window_get_current_screen(WindowID p_window) const { return (index == NSNotFound) ? 0 : index; } -void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window) { +void DisplayServerMacOS::window_set_current_screen(int p_screen, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2028,7 +2028,7 @@ void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window } } -void DisplayServerOSX::window_set_exclusive(WindowID p_window, bool p_exclusive) { +void DisplayServerMacOS::window_set_exclusive(WindowID p_window, bool p_exclusive) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; @@ -2046,7 +2046,7 @@ void DisplayServerOSX::window_set_exclusive(WindowID p_window, bool p_exclusive) } } -Point2i DisplayServerOSX::window_get_position(WindowID p_window) const { +Point2i DisplayServerMacOS::window_get_position(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Point2i()); @@ -2069,7 +2069,7 @@ Point2i DisplayServerOSX::window_get_position(WindowID p_window) const { return pos; } -void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p_window) { +void DisplayServerMacOS::window_set_position(const Point2i &p_position, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2097,7 +2097,7 @@ void DisplayServerOSX::window_set_position(const Point2i &p_position, WindowID p update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]); } -void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent) { +void DisplayServerMacOS::window_set_transient(WindowID p_window, WindowID p_parent) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(p_window == p_parent); @@ -2136,7 +2136,7 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent } } -void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_window) { +void DisplayServerMacOS::window_set_max_size(const Size2i p_size, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2156,7 +2156,7 @@ void DisplayServerOSX::window_set_max_size(const Size2i p_size, WindowID p_windo } } -Size2i DisplayServerOSX::window_get_max_size(WindowID p_window) const { +Size2i DisplayServerMacOS::window_get_max_size(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); @@ -2164,7 +2164,7 @@ Size2i DisplayServerOSX::window_get_max_size(WindowID p_window) const { return wd.max_size; } -void DisplayServerOSX::window_set_min_size(const Size2i p_size, WindowID p_window) { +void DisplayServerMacOS::window_set_min_size(const Size2i p_size, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2184,7 +2184,7 @@ void DisplayServerOSX::window_set_min_size(const Size2i p_size, WindowID p_windo } } -Size2i DisplayServerOSX::window_get_min_size(WindowID p_window) const { +Size2i DisplayServerMacOS::window_get_min_size(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); @@ -2193,7 +2193,7 @@ Size2i DisplayServerOSX::window_get_min_size(WindowID p_window) const { return wd.min_size; } -void DisplayServerOSX::window_set_size(const Size2i p_size, WindowID p_window) { +void DisplayServerMacOS::window_set_size(const Size2i p_size, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2217,7 +2217,7 @@ void DisplayServerOSX::window_set_size(const Size2i p_size, WindowID p_window) { _update_window_style(wd); } -Size2i DisplayServerOSX::window_get_size(WindowID p_window) const { +Size2i DisplayServerMacOS::window_get_size(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); @@ -2225,7 +2225,7 @@ Size2i DisplayServerOSX::window_get_size(WindowID p_window) const { return wd.size; } -Size2i DisplayServerOSX::window_get_real_size(WindowID p_window) const { +Size2i DisplayServerMacOS::window_get_real_size(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); @@ -2234,7 +2234,7 @@ Size2i DisplayServerOSX::window_get_real_size(WindowID p_window) const { return Size2i(frame.size.width, frame.size.height) * screen_get_max_scale(); } -void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) { +void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2303,7 +2303,7 @@ void DisplayServerOSX::window_set_mode(WindowMode p_mode, WindowID p_window) { } } -DisplayServer::WindowMode DisplayServerOSX::window_get_mode(WindowID p_window) const { +DisplayServer::WindowMode DisplayServerMacOS::window_get_mode(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), WINDOW_MODE_WINDOWED); @@ -2325,11 +2325,11 @@ DisplayServer::WindowMode DisplayServerOSX::window_get_mode(WindowID p_window) c return WINDOW_MODE_WINDOWED; } -bool DisplayServerOSX::window_is_maximize_allowed(WindowID p_window) const { +bool DisplayServerMacOS::window_is_maximize_allowed(WindowID p_window) const { return true; } -void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) { +void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2404,7 +2404,7 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo } } -bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) const { +bool DisplayServerMacOS::window_get_flag(WindowFlags p_flag, WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), false); @@ -2440,12 +2440,12 @@ bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) co return false; } -void DisplayServerOSX::window_request_attention(WindowID p_window) { +void DisplayServerMacOS::window_request_attention(WindowID p_window) { // It's app global, ignore window id. [NSApp requestUserAttention:NSCriticalRequest]; } -void DisplayServerOSX::window_move_to_foreground(WindowID p_window) { +void DisplayServerMacOS::window_move_to_foreground(WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2459,11 +2459,11 @@ void DisplayServerOSX::window_move_to_foreground(WindowID p_window) { } } -bool DisplayServerOSX::window_can_draw(WindowID p_window) const { +bool DisplayServerMacOS::window_can_draw(WindowID p_window) const { return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED; } -bool DisplayServerOSX::can_any_window_draw() const { +bool DisplayServerMacOS::can_any_window_draw() const { _THREAD_SAFE_METHOD_ for (const KeyValue<WindowID, WindowData> &E : windows) { @@ -2474,7 +2474,7 @@ bool DisplayServerOSX::can_any_window_draw() const { return false; } -void DisplayServerOSX::window_set_ime_active(const bool p_active, WindowID p_window) { +void DisplayServerMacOS::window_set_ime_active(const bool p_active, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2487,7 +2487,7 @@ void DisplayServerOSX::window_set_ime_active(const bool p_active, WindowID p_win } } -void DisplayServerOSX::window_set_ime_position(const Point2i &p_pos, WindowID p_window) { +void DisplayServerMacOS::window_set_ime_position(const Point2i &p_pos, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -2496,7 +2496,7 @@ void DisplayServerOSX::window_set_ime_position(const Point2i &p_pos, WindowID p_ wd.im_position = p_pos; } -DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Point2i &p_position) const { +DisplayServer::WindowID DisplayServerMacOS::get_window_at_screen_position(const Point2i &p_position) const { Point2i position = p_position; position.y *= -1; position += _get_screens_origin(); @@ -2511,7 +2511,7 @@ DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Po return INVALID_WINDOW_ID; } -int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const { +int64_t DisplayServerMacOS::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const { ERR_FAIL_COND_V(!windows.has(p_window), 0); switch (p_handle_type) { case DISPLAY_HANDLE: { @@ -2529,27 +2529,27 @@ int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, Win } } -void DisplayServerOSX::window_attach_instance_id(ObjectID p_instance, WindowID p_window) { +void DisplayServerMacOS::window_attach_instance_id(ObjectID p_instance, WindowID p_window) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); windows[p_window].instance_id = p_instance; } -ObjectID DisplayServerOSX::window_get_attached_instance_id(WindowID p_window) const { +ObjectID DisplayServerMacOS::window_get_attached_instance_id(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), ObjectID()); return windows[p_window].instance_id; } -void DisplayServerOSX::gl_window_make_current(DisplayServer::WindowID p_window_id) { +void DisplayServerMacOS::gl_window_make_current(DisplayServer::WindowID p_window_id) { #if defined(GLES3_ENABLED) gl_manager->window_make_current(p_window_id); #endif } -void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { +void DisplayServerMacOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { _THREAD_SAFE_METHOD_ #if defined(GLES3_ENABLED) if (gl_manager) { @@ -2563,7 +2563,7 @@ void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo #endif } -DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const { +DisplayServer::VSyncMode DisplayServerMacOS::window_get_vsync_mode(WindowID p_window) const { _THREAD_SAFE_METHOD_ #if defined(GLES3_ENABLED) if (gl_manager) { @@ -2578,15 +2578,15 @@ DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_wind return DisplayServer::VSYNC_ENABLED; } -Point2i DisplayServerOSX::ime_get_selection() const { +Point2i DisplayServerMacOS::ime_get_selection() const { return im_selection; } -String DisplayServerOSX::ime_get_text() const { +String DisplayServerMacOS::ime_get_text() const { return im_text; } -void DisplayServerOSX::cursor_update_shape() { +void DisplayServerMacOS::cursor_update_shape() { _THREAD_SAFE_METHOD_ if (cursors[cursor_shape] != nullptr) { @@ -2650,7 +2650,7 @@ void DisplayServerOSX::cursor_update_shape() { } } -void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) { +void DisplayServerMacOS::cursor_set_shape(CursorShape p_shape) { _THREAD_SAFE_METHOD_ ERR_FAIL_INDEX(p_shape, CURSOR_MAX); @@ -2668,11 +2668,11 @@ void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) { cursor_update_shape(); } -DisplayServerOSX::CursorShape DisplayServerOSX::cursor_get_shape() const { +DisplayServerMacOS::CursorShape DisplayServerMacOS::cursor_get_shape() const { return cursor_shape; } -void DisplayServerOSX::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { _THREAD_SAFE_METHOD_ if (p_cursor.is_valid()) { @@ -2784,20 +2784,20 @@ void DisplayServerOSX::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu } } -bool DisplayServerOSX::get_swap_cancel_ok() { +bool DisplayServerMacOS::get_swap_cancel_ok() { return false; } -int DisplayServerOSX::keyboard_get_layout_count() const { +int DisplayServerMacOS::keyboard_get_layout_count() const { if (keyboard_layout_dirty) { - const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); + const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts(); } return kbd_layouts.size(); } -void DisplayServerOSX::keyboard_set_current_layout(int p_index) { +void DisplayServerMacOS::keyboard_set_current_layout(int p_index) { if (keyboard_layout_dirty) { - const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); + const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts(); } ERR_FAIL_INDEX(p_index, kbd_layouts.size()); @@ -2825,44 +2825,44 @@ void DisplayServerOSX::keyboard_set_current_layout(int p_index) { } } -int DisplayServerOSX::keyboard_get_current_layout() const { +int DisplayServerMacOS::keyboard_get_current_layout() const { if (keyboard_layout_dirty) { - const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); + const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts(); } return current_layout; } -String DisplayServerOSX::keyboard_get_layout_language(int p_index) const { +String DisplayServerMacOS::keyboard_get_layout_language(int p_index) const { if (keyboard_layout_dirty) { - const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); + const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts(); } ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), ""); return kbd_layouts[p_index].code; } -String DisplayServerOSX::keyboard_get_layout_name(int p_index) const { +String DisplayServerMacOS::keyboard_get_layout_name(int p_index) const { if (keyboard_layout_dirty) { - const_cast<DisplayServerOSX *>(this)->_update_keyboard_layouts(); + const_cast<DisplayServerMacOS *>(this)->_update_keyboard_layouts(); } ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), ""); return kbd_layouts[p_index].name; } -Key DisplayServerOSX::keyboard_get_keycode_from_physical(Key p_keycode) const { +Key DisplayServerMacOS::keyboard_get_keycode_from_physical(Key p_keycode) const { if (p_keycode == Key::PAUSE) { return p_keycode; } Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK; Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK; - unsigned int osx_keycode = KeyMappingOSX::unmap_key((Key)keycode_no_mod); - return (Key)(KeyMappingOSX::remap_key(osx_keycode, 0) | modifiers); + unsigned int macos_keycode = KeyMappingMacOS::unmap_key((Key)keycode_no_mod); + return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0) | modifiers); } -void DisplayServerOSX::process_events() { +void DisplayServerMacOS::process_events() { _THREAD_SAFE_METHOD_ while (true) { @@ -2905,7 +2905,7 @@ void DisplayServerOSX::process_events() { } } -void DisplayServerOSX::force_process_and_drop_events() { +void DisplayServerMacOS::force_process_and_drop_events() { _THREAD_SAFE_METHOD_ drop_events = true; @@ -2913,13 +2913,13 @@ void DisplayServerOSX::force_process_and_drop_events() { drop_events = false; } -void DisplayServerOSX::release_rendering_thread() { +void DisplayServerMacOS::release_rendering_thread() { } -void DisplayServerOSX::make_rendering_thread() { +void DisplayServerMacOS::make_rendering_thread() { } -void DisplayServerOSX::swap_buffers() { +void DisplayServerMacOS::swap_buffers() { #if defined(GLES3_ENABLED) if (gl_manager) { gl_manager->swap_buffers(); @@ -2927,7 +2927,7 @@ void DisplayServerOSX::swap_buffers() { #endif } -void DisplayServerOSX::set_native_icon(const String &p_filename) { +void DisplayServerMacOS::set_native_icon(const String &p_filename) { _THREAD_SAFE_METHOD_ Ref<FileAccess> f = FileAccess::open(p_filename, FileAccess::READ); @@ -2947,7 +2947,7 @@ void DisplayServerOSX::set_native_icon(const String &p_filename) { [NSApp setApplicationIconImage:icon]; } -void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) { +void DisplayServerMacOS::set_icon(const Ref<Image> &p_icon) { _THREAD_SAFE_METHOD_ Ref<Image> img = p_icon; @@ -2986,15 +2986,15 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) { [NSApp setApplicationIconImage:nsimg]; } -DisplayServer *DisplayServerOSX::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerOSX(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); +DisplayServer *DisplayServerMacOS::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { + DisplayServer *ds = memnew(DisplayServerMacOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); if (r_error != OK) { OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.", "Unable to initialize Video driver"); } return ds; } -Vector<String> DisplayServerOSX::get_rendering_drivers_func() { +Vector<String> DisplayServerMacOS::get_rendering_drivers_func() { Vector<String> drivers; #if defined(VULKAN_ENABLED) @@ -3007,11 +3007,11 @@ Vector<String> DisplayServerOSX::get_rendering_drivers_func() { return drivers; } -void DisplayServerOSX::register_osx_driver() { - register_create_function("osx", create_func, get_rendering_drivers_func); +void DisplayServerMacOS::register_macos_driver() { + register_create_function("macos", create_func, get_rendering_drivers_func); } -DisplayServer::WindowID DisplayServerOSX::window_get_active_popup() const { +DisplayServer::WindowID DisplayServerMacOS::window_get_active_popup() const { const List<WindowID>::Element *E = popup_list.back(); if (E) { return E->get(); @@ -3020,7 +3020,7 @@ DisplayServer::WindowID DisplayServerOSX::window_get_active_popup() const { } } -void DisplayServerOSX::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) { +void DisplayServerMacOS::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND(!windows.has(p_window)); @@ -3028,7 +3028,7 @@ void DisplayServerOSX::window_set_popup_safe_rect(WindowID p_window, const Rect2 wd.parent_safe_rect = p_rect; } -Rect2i DisplayServerOSX::window_get_popup_safe_rect(WindowID p_window) const { +Rect2i DisplayServerMacOS::window_get_popup_safe_rect(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Rect2i()); @@ -3036,7 +3036,7 @@ Rect2i DisplayServerOSX::window_get_popup_safe_rect(WindowID p_window) const { return wd.parent_safe_rect; } -void DisplayServerOSX::popup_open(WindowID p_window) { +void DisplayServerMacOS::popup_open(WindowID p_window) { _THREAD_SAFE_METHOD_ WindowData &wd = windows[p_window]; @@ -3054,7 +3054,7 @@ void DisplayServerOSX::popup_open(WindowID p_window) { } } if (C) { - send_window_event(windows[C->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + send_window_event(windows[C->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST); } if (was_empty && popup_list.is_empty()) { @@ -3066,7 +3066,7 @@ void DisplayServerOSX::popup_open(WindowID p_window) { } } -void DisplayServerOSX::popup_close(WindowID p_window) { +void DisplayServerMacOS::popup_close(WindowID p_window) { _THREAD_SAFE_METHOD_ bool was_empty = popup_list.is_empty(); @@ -3076,7 +3076,7 @@ void DisplayServerOSX::popup_close(WindowID p_window) { WindowID win_id = E->get(); popup_list.erase(E); - send_window_event(windows[win_id], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + send_window_event(windows[win_id], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST); E = F; } if (!was_empty && popup_list.is_empty()) { @@ -3085,7 +3085,7 @@ void DisplayServerOSX::popup_close(WindowID p_window) { } } -bool DisplayServerOSX::mouse_process_popups(bool p_close) { +bool DisplayServerMacOS::mouse_process_popups(bool p_close) { _THREAD_SAFE_METHOD_ bool was_empty = popup_list.is_empty(); @@ -3094,7 +3094,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) { // Close all popups. List<WindowID>::Element *E = popup_list.front(); if (E) { - send_window_event(windows[E->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + send_window_event(windows[E->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST); closed = true; } if (!was_empty) { @@ -3126,7 +3126,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) { } } if (C) { - send_window_event(windows[C->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + send_window_event(windows[C->get()], DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST); closed = true; } if (!was_empty && popup_list.is_empty()) { @@ -3137,7 +3137,7 @@ bool DisplayServerOSX::mouse_process_popups(bool p_close) { return closed; } -DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { +DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); r_error = OK; @@ -3164,7 +3164,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode CGDisplayRegisterReconfigurationCallback(_displays_arrangement_changed, nullptr); // Init TTS - tts = [[TTS_OSX alloc] init]; + tts = [[TTS_MacOS alloc] init]; NSMenuItem *menu_item; NSString *title; @@ -3218,8 +3218,8 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode #if defined(GLES3_ENABLED) if (rendering_driver == "opengl3") { - GLManager_OSX::ContextType opengl_api_type = GLManager_OSX::GLES_3_0_COMPATIBLE; - gl_manager = memnew(GLManager_OSX(opengl_api_type)); + GLManager_MacOS::ContextType opengl_api_type = GLManager_MacOS::GLES_3_0_COMPATIBLE; + gl_manager = memnew(GLManager_MacOS(opengl_api_type)); if (gl_manager->initialize() != OK) { memdelete(gl_manager); gl_manager = nullptr; @@ -3231,7 +3231,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode #endif #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { - context_vulkan = memnew(VulkanContextOSX); + context_vulkan = memnew(VulkanContextMacOS); if (context_vulkan->initialize() != OK) { memdelete(context_vulkan); context_vulkan = nullptr; @@ -3268,7 +3268,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode #endif } -DisplayServerOSX::~DisplayServerOSX() { +DisplayServerMacOS::~DisplayServerMacOS() { // Destroy all windows. for (HashMap<WindowID, WindowData>::Iterator E = windows.begin(); E;) { HashMap<WindowID, WindowData>::Iterator F = E; diff --git a/platform/osx/export/codesign.cpp b/platform/macos/export/codesign.cpp index fd044c00cc..fd044c00cc 100644 --- a/platform/osx/export/codesign.cpp +++ b/platform/macos/export/codesign.cpp diff --git a/platform/osx/export/codesign.h b/platform/macos/export/codesign.h index 3a08c0ea86..fea7b117d0 100644 --- a/platform/osx/export/codesign.h +++ b/platform/macos/export/codesign.h @@ -38,8 +38,8 @@ // - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported). // - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only. -#ifndef CODESIGN_H -#define CODESIGN_H +#ifndef MACOS_CODESIGN_H +#define MACOS_CODESIGN_H #include "core/crypto/crypto_core.h" #include "core/io/dir_access.h" @@ -365,4 +365,4 @@ public: #endif // MODULE_REGEX_ENABLED -#endif // CODESIGN_H +#endif // MACOS_CODESIGN_H diff --git a/platform/osx/export/export.cpp b/platform/macos/export/export.cpp index bd35b39e9e..ff7457081f 100644 --- a/platform/osx/export/export.cpp +++ b/platform/macos/export/export.cpp @@ -32,11 +32,11 @@ #include "export_plugin.h" -void register_osx_exporter() { +void register_macos_exporter() { EDITOR_DEF("export/macos/force_builtin_codesign", false); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::BOOL, "export/macos/force_builtin_codesign", PROPERTY_HINT_NONE)); - Ref<EditorExportPlatformOSX> platform; + Ref<EditorExportPlatformMacOS> platform; platform.instantiate(); EditorExport::get_singleton()->add_export_platform(platform); diff --git a/platform/iphone/export/export.h b/platform/macos/export/export.h index adb3c23957..260c691209 100644 --- a/platform/iphone/export/export.h +++ b/platform/macos/export/export.h @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef IPHONE_EXPORT_H -#define IPHONE_EXPORT_H +#ifndef MACOS_EXPORT_H +#define MACOS_EXPORT_H -void register_iphone_exporter(); +void register_macos_exporter(); -#endif // IPHONE_EXPORT_H +#endif // MACOS_EXPORT_H diff --git a/platform/osx/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp index a22d7e5e3d..fd0781ac50 100644 --- a/platform/osx/export/export_plugin.cpp +++ b/platform/macos/export/export_plugin.cpp @@ -37,7 +37,7 @@ #include "modules/modules_enabled.gen.h" // For regex. -void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { +void EditorExportPlatformMacOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { if (p_preset->get("texture_format/s3tc")) { r_features->push_back("s3tc"); } @@ -51,7 +51,7 @@ void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> r_features->push_back("64"); } -bool EditorExportPlatformOSX::get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const { +bool EditorExportPlatformMacOS::get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const { // These options are not supported by built-in codesign, used on non macOS host. if (!OS::get_singleton()->has_feature("macos")) { if (p_option == "codesign/identity" || p_option == "codesign/timestamp" || p_option == "codesign/hardened_runtime" || p_option == "codesign/custom_options" || p_option.begins_with("notarization/")) { @@ -68,7 +68,7 @@ bool EditorExportPlatformOSX::get_export_option_visibility(const String &p_optio return true; } -void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) { +void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options) { r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); @@ -214,7 +214,7 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source, memcpy(&p_dest.write[ofs], result.ptr(), res_size); } -void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) { +void EditorExportPlatformMacOS::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) { Ref<ImageTexture> it = memnew(ImageTexture); Vector<uint8_t> data; @@ -320,7 +320,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ p_data = data; } -void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) { +void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) { String str; String strnew; str.parse_utf8((const char *)plist.ptr(), plist.size()); @@ -407,14 +407,14 @@ void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset } /** - * If we're running the OSX version of the Godot editor we'll: + * If we're running the macOS version of the Godot editor we'll: * - export our application bundle to a temporary folder * - attempt to code sign it * - and then wrap it up in a DMG */ -Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path) { -#ifdef OSX_ENABLED +Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path) { +#ifdef MACOS_ENABLED List<String> args; args.push_back("altool"); @@ -468,7 +468,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset return OK; } -Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn) { +Error EditorExportPlatformMacOS::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn) { bool force_builtin_codesign = EditorSettings::get_singleton()->get("export/macos/force_builtin_codesign"); bool ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-"); @@ -476,7 +476,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese print_verbose("using built-in codesign..."); #ifdef MODULE_REGEX_ENABLED -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED if (p_preset->get("codesign/timestamp") && p_warn) { add_message(EXPORT_MESSAGE_INFO, TTR("Code Signing"), TTR("Timestamping is not compatible with ad-hoc signature, and was disabled!")); } @@ -566,9 +566,9 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese } } -Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path, +Error EditorExportPlatformMacOS::_code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_should_error_on_non_code) { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED static Vector<String> extensions_to_sign; if (extensions_to_sign.is_empty()) { @@ -615,7 +615,7 @@ Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset return OK; } -Error EditorExportPlatformOSX::_copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path, +Error EditorExportPlatformMacOS::_copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path, const String &p_in_app_path, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path, bool p_should_error_on_non_code_sign) { @@ -644,14 +644,14 @@ Error EditorExportPlatformOSX::_copy_and_sign_files(Ref<DirAccess> &dir_access, return err; } -Error EditorExportPlatformOSX::_export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, +Error EditorExportPlatformMacOS::_export_macos_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name, Ref<DirAccess> &dir_access, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path) { Error error{ OK }; - const Vector<String> &osx_plugins{ p_editor_export_plugin->get_osx_plugin_files() }; - for (int i = 0; i < osx_plugins.size(); ++i) { - String src_path{ ProjectSettings::get_singleton()->globalize_path(osx_plugins[i]) }; + const Vector<String> &macos_plugins{ p_editor_export_plugin->get_macos_plugin_files() }; + for (int i = 0; i < macos_plugins.size(); ++i) { + String src_path{ ProjectSettings::get_singleton()->globalize_path(macos_plugins[i]) }; String path_in_app{ p_app_path_name + "/Contents/PlugIns/" + src_path.get_file() }; error = _copy_and_sign_files(dir_access, src_path, path_in_app, p_sign_enabled, p_preset, p_ent_path, false); if (error != OK) { @@ -661,7 +661,7 @@ Error EditorExportPlatformOSX::_export_osx_plugins_for(Ref<EditorExportPlugin> p return error; } -Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) { +Error EditorExportPlatformMacOS::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) { List<String> args; if (FileAccess::exists(p_dmg_path)) { @@ -697,7 +697,7 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin return OK; } -Error EditorExportPlatformOSX::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) { +Error EditorExportPlatformMacOS::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE); if (f.is_null()) { add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), vformat(TTR("Could not open file \"%s\"."), p_path)); @@ -706,19 +706,30 @@ Error EditorExportPlatformOSX::_export_debug_script(const Ref<EditorExportPreset f->store_line("#!/bin/sh"); f->store_line("echo -ne '\\033c\\033]0;" + p_app_name + "\\a'"); - f->store_line("function realpath() { python -c \"import os,sys; print(os.path.realpath(sys.argv[1]))\" \"$0\"; }"); - f->store_line("base_path=\"$(dirname \"$(realpath \"$0\")\")\""); - f->store_line("\"$base_path/" + p_pkg_name + "\" \"$@\""); + f->store_line(""); + f->store_line("function app_realpath() {"); + f->store_line(" SOURCE=$1"); + f->store_line(" while [ -h \"$SOURCE\" ]; do"); + f->store_line(" DIR=$(dirname \"$SOURCE\")"); + f->store_line(" SOURCE=$(readlink \"$SOURCE\")"); + f->store_line(" [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE"); + f->store_line(" done"); + f->store_line(" echo \"$( cd -P \"$( dirname \"$SOURCE\" )\" >/dev/null 2>&1 && pwd )\""); + f->store_line("}"); + f->store_line(""); + f->store_line("BASE_PATH=\"$(app_realpath \"${BASH_SOURCE[0]}\")\""); + f->store_line("\"$BASE_PATH/" + p_pkg_name + "\" \"$@\""); + f->store_line(""); return OK; } -Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { +Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); String src_pkg_name; - EditorProgress ep("export", "Exporting for OSX", 3, true); + EditorProgress ep("export", "Exporting for macOS", 3, true); if (p_debug) { src_pkg_name = p_preset->get("custom_template/debug"); @@ -728,7 +739,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (src_pkg_name.is_empty()) { String err; - src_pkg_name = find_export_template("osx.zip", &err); + src_pkg_name = find_export_template("macos.zip", &err); if (src_pkg_name.is_empty()) { add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found.")); return ERR_FILE_NOT_FOUND; @@ -755,7 +766,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p int ret = unzGoToFirstFile(src_pkg_zip); - String binary_to_use = "godot_osx_" + String(p_debug ? "debug" : "release") + ".64"; + String binary_to_use = "godot_macos_" + String(p_debug ? "debug" : "release") + ".universal"; String pkg_name; if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") { @@ -984,7 +995,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p unzCloseCurrentFile(src_pkg_zip); // Write. - file = file.replace_first("osx_template.app/", ""); + file = file.replace_first("macos_template.app/", ""); if (((info.external_fa >> 16L) & 0120000) == 0120000) { #ifndef UNIX_ENABLED @@ -1053,19 +1064,19 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } if (data.size() > 0) { - if (file.find("/data.mono.osx.64.release_debug/") != -1) { + if (file.find("/data.mono.macos.release_debug.universal/") != -1) { if (!p_debug) { ret = unzGoToNextFile(src_pkg_zip); continue; // skip } - file = file.replace("/data.mono.osx.64.release_debug/", "/GodotSharp/"); + file = file.replace("/data.mono.macos.release_debug.universal/", "/GodotSharp/"); } - if (file.find("/data.mono.osx.64.release/") != -1) { + if (file.find("/data.mono.macos.release.universal/") != -1) { if (p_debug) { ret = unzGoToNextFile(src_pkg_zip); continue; // skip } - file = file.replace("/data.mono.osx.64.release/", "/GodotSharp/"); + file = file.replace("/data.mono.macos.release.universal/", "/GodotSharp/"); } if (file.ends_with(".dylib")) { @@ -1299,7 +1310,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p bool ad_hoc = true; if (err == OK) { -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED String sign_identity = p_preset->get("codesign/identity"); #else String sign_identity = "-"; @@ -1330,7 +1341,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p Vector<Ref<EditorExportPlugin>> export_plugins{ EditorExport::get_singleton()->get_export_plugins() }; for (int i = 0; i < export_plugins.size(); ++i) { - err = _export_osx_plugins_for(export_plugins[i], tmp_app_path_name, da, sign_enabled, p_preset, ent_path); + err = _export_macos_plugins_for(export_plugins[i], tmp_app_path_name, da, sign_enabled, p_preset, ent_path); if (err != OK) { break; } @@ -1387,7 +1398,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } } -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool noto_enabled = p_preset->get("notarization/enable"); if (err == OK && noto_enabled) { if (export_format == "app") { @@ -1420,7 +1431,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p return err; } -void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name) { +void EditorExportPlatformMacOS::_zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name) { String dir = p_folder.is_empty() ? p_root_path : p_root_path.plus_file(p_folder); Ref<DirAccess> da = DirAccess::open(dir); @@ -1537,7 +1548,7 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String da->list_dir_end(); } -bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { +bool EditorExportPlatformMacOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { String err; bool valid = false; @@ -1560,7 +1571,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset // Look for export templates (official templates, check only is custom templates are not set). if (!dvalid || !rvalid) { - dvalid = exists_export_template("osx.zip", &err); + dvalid = exists_export_template("macos.zip", &err); rvalid = dvalid; // Both in the same ZIP. } @@ -1576,7 +1587,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset bool sign_enabled = p_preset->get("codesign/enable"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool noto_enabled = p_preset->get("notarization/enable"); bool ad_hoc = ((p_preset->get("codesign/identity") == "") || (p_preset->get("codesign/identity") == "-")); @@ -1665,9 +1676,9 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset return valid; } -EditorExportPlatformOSX::EditorExportPlatformOSX() { - logo = ImageTexture::create_from_image(memnew(Image(_osx_logo))); +EditorExportPlatformMacOS::EditorExportPlatformMacOS() { + logo = ImageTexture::create_from_image(memnew(Image(_macos_logo))); } -EditorExportPlatformOSX::~EditorExportPlatformOSX() { +EditorExportPlatformMacOS::~EditorExportPlatformMacOS() { } diff --git a/platform/osx/export/export_plugin.h b/platform/macos/export/export_plugin.h index ec97d4139f..4f4b17594c 100644 --- a/platform/osx/export/export_plugin.h +++ b/platform/macos/export/export_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OSX_EXPORT_PLUGIN_H -#define OSX_EXPORT_PLUGIN_H +#ifndef MACOS_EXPORT_PLUGIN_H +#define MACOS_EXPORT_PLUGIN_H #include "core/config/project_settings.h" #include "core/io/dir_access.h" @@ -39,14 +39,14 @@ #include "core/io/zip_io.h" #include "core/os/os.h" #include "core/version.h" -#include "editor/editor_export.h" #include "editor/editor_settings.h" -#include "platform/osx/logo.gen.h" +#include "editor/export/editor_export.h" +#include "platform/macos/logo.gen.h" #include <sys/stat.h> -class EditorExportPlatformOSX : public EditorExportPlatform { - GDCLASS(EditorExportPlatformOSX, EditorExportPlatform); +class EditorExportPlatformMacOS : public EditorExportPlatform { + GDCLASS(EditorExportPlatformMacOS, EditorExportPlatform); int version_code = 0; @@ -61,7 +61,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform { Error _copy_and_sign_files(Ref<DirAccess> &dir_access, const String &p_src_path, const String &p_in_app_path, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path, bool p_should_error_on_non_code_sign); - Error _export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name, + Error _export_macos_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name, Ref<DirAccess> &dir_access, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path); Error _create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name); @@ -69,7 +69,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform { Error _export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path); bool use_codesign() const { return true; } -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED bool use_dmg() const { return true; } #else bool use_dmg() const { return false; } @@ -130,8 +130,8 @@ public: virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override { } - EditorExportPlatformOSX(); - ~EditorExportPlatformOSX(); + EditorExportPlatformMacOS(); + ~EditorExportPlatformMacOS(); }; -#endif +#endif // MACOS_EXPORT_PLUGIN_H diff --git a/platform/osx/export/lipo.cpp b/platform/macos/export/lipo.cpp index 82baf18c52..82baf18c52 100644 --- a/platform/osx/export/lipo.cpp +++ b/platform/macos/export/lipo.cpp diff --git a/platform/osx/export/lipo.h b/platform/macos/export/lipo.h index 0e419be17e..516ef99860 100644 --- a/platform/osx/export/lipo.h +++ b/platform/macos/export/lipo.h @@ -30,8 +30,8 @@ // Universal / Universal 2 fat binary file creator and extractor. -#ifndef LIPO_H -#define LIPO_H +#ifndef MACOS_LIPO_H +#define MACOS_LIPO_H #include "core/io/file_access.h" #include "core/object/ref_counted.h" @@ -73,4 +73,4 @@ public: #endif // MODULE_REGEX_ENABLED -#endif // LIPO_H +#endif // MACOS_LIPO_H diff --git a/platform/osx/export/macho.cpp b/platform/macos/export/macho.cpp index e6e67eff06..e6e67eff06 100644 --- a/platform/osx/export/macho.cpp +++ b/platform/macos/export/macho.cpp diff --git a/platform/osx/export/macho.h b/platform/macos/export/macho.h index 6cfc3c44f5..7ef0d9067e 100644 --- a/platform/osx/export/macho.h +++ b/platform/macos/export/macho.h @@ -30,8 +30,8 @@ // Mach-O binary object file format parser and editor. -#ifndef MACHO_H -#define MACHO_H +#ifndef MACOS_MACHO_H +#define MACOS_MACHO_H #include "core/crypto/crypto.h" #include "core/crypto/crypto_core.h" @@ -212,4 +212,4 @@ public: #endif // MODULE_REGEX_ENABLED -#endif // MACHO_H +#endif // MACOS_MACHO_H diff --git a/platform/osx/export/plist.cpp b/platform/macos/export/plist.cpp index 36de9dd34b..36de9dd34b 100644 --- a/platform/osx/export/plist.cpp +++ b/platform/macos/export/plist.cpp diff --git a/platform/osx/export/plist.h b/platform/macos/export/plist.h index ba9eaec196..79cb928d0a 100644 --- a/platform/osx/export/plist.h +++ b/platform/macos/export/plist.h @@ -30,8 +30,8 @@ // Property list file format (application/x-plist) parser, property list ASN-1 serialization. -#ifndef PLIST_H -#define PLIST_H +#ifndef MACOS_PLIST_H +#define MACOS_PLIST_H #include "core/crypto/crypto_core.h" #include "core/io/file_access.h" @@ -113,4 +113,4 @@ public: #endif // MODULE_REGEX_ENABLED -#endif // PLIST_H +#endif // MACOS_PLIST_H diff --git a/platform/osx/gl_manager_osx_legacy.h b/platform/macos/gl_manager_macos_legacy.h index 2d4913a7a6..8752086551 100644 --- a/platform/osx/gl_manager_osx_legacy.h +++ b/platform/macos/gl_manager_macos_legacy.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gl_manager_osx_legacy.h */ +/* gl_manager_macos_legacy.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GL_MANAGER_OSX_LEGACY_H -#define GL_MANAGER_OSX_LEGACY_H +#ifndef GL_MANAGER_MACOS_LEGACY_H +#define GL_MANAGER_MACOS_LEGACY_H -#if defined(OSX_ENABLED) && defined(GLES3_ENABLED) +#if defined(MACOS_ENABLED) && defined(GLES3_ENABLED) #include "core/error/error_list.h" #include "core/os/os.h" @@ -42,7 +42,7 @@ #import <ApplicationServices/ApplicationServices.h> #import <CoreVideo/CoreVideo.h> -class GLManager_OSX { +class GLManager_MacOS { public: enum ContextType { GLES_3_0_COMPATIBLE, @@ -89,9 +89,10 @@ public: void set_use_vsync(bool p_use); bool is_using_vsync() const; - GLManager_OSX(ContextType p_context_type); - ~GLManager_OSX(); + GLManager_MacOS(ContextType p_context_type); + ~GLManager_MacOS(); }; -#endif // OSX_ENABLED && GLES3_ENABLED -#endif // GL_MANAGER_OSX_LEGACY_H +#endif // MACOS_ENABLED && GLES3_ENABLED + +#endif // GL_MANAGER_MACOS_LEGACY_H diff --git a/platform/osx/gl_manager_osx_legacy.mm b/platform/macos/gl_manager_macos_legacy.mm index c769d7f5c5..e6bb7aaa85 100644 --- a/platform/osx/gl_manager_osx_legacy.mm +++ b/platform/macos/gl_manager_macos_legacy.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* gl_manager_osx_legacy.mm */ +/* gl_manager_macos_legacy.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "gl_manager_osx_legacy.h" +#include "gl_manager_macos_legacy.h" -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED #ifdef GLES3_ENABLED #include <stdio.h> #include <stdlib.h> -Error GLManager_OSX::create_context(GLWindow &win) { +Error GLManager_MacOS::create_context(GLWindow &win) { NSOpenGLPixelFormatAttribute attributes[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAClosestPolicy, @@ -62,7 +62,7 @@ Error GLManager_OSX::create_context(GLWindow &win) { return OK; } -Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) { +Error GLManager_MacOS::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) { GLWindow win; win.width = p_width; win.height = p_height; @@ -78,7 +78,7 @@ Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_vie return OK; } -void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) { +void GLManager_MacOS::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) { if (!windows.has(p_window_id)) { return; } @@ -102,7 +102,7 @@ void GLManager_OSX::window_resize(DisplayServer::WindowID p_window_id, int p_wid [win.context update]; } -int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) { +int GLManager_MacOS::window_get_width(DisplayServer::WindowID p_window_id) { if (!windows.has(p_window_id)) { return 0; } @@ -111,7 +111,7 @@ int GLManager_OSX::window_get_width(DisplayServer::WindowID p_window_id) { return win.width; } -int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) { +int GLManager_MacOS::window_get_height(DisplayServer::WindowID p_window_id) { if (!windows.has(p_window_id)) { return 0; } @@ -120,7 +120,7 @@ int GLManager_OSX::window_get_height(DisplayServer::WindowID p_window_id) { return win.height; } -void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) { +void GLManager_MacOS::window_destroy(DisplayServer::WindowID p_window_id) { if (!windows.has(p_window_id)) { return; } @@ -132,7 +132,7 @@ void GLManager_OSX::window_destroy(DisplayServer::WindowID p_window_id) { windows.erase(p_window_id); } -void GLManager_OSX::release_current() { +void GLManager_MacOS::release_current() { if (current_window == DisplayServer::INVALID_WINDOW_ID) { return; } @@ -140,7 +140,7 @@ void GLManager_OSX::release_current() { [NSOpenGLContext clearCurrentContext]; } -void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) { +void GLManager_MacOS::window_make_current(DisplayServer::WindowID p_window_id) { if (current_window == p_window_id) { return; } @@ -154,7 +154,7 @@ void GLManager_OSX::window_make_current(DisplayServer::WindowID p_window_id) { current_window = p_window_id; } -void GLManager_OSX::make_current() { +void GLManager_MacOS::make_current() { if (current_window == DisplayServer::INVALID_WINDOW_ID) { return; } @@ -166,13 +166,13 @@ void GLManager_OSX::make_current() { [win.context makeCurrentContext]; } -void GLManager_OSX::swap_buffers() { +void GLManager_MacOS::swap_buffers() { for (const KeyValue<DisplayServer::WindowID, GLWindow> &E : windows) { [E.value.context flushBuffer]; } } -void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) { +void GLManager_MacOS::window_update(DisplayServer::WindowID p_window_id) { if (!windows.has(p_window_id)) { return; } @@ -181,7 +181,7 @@ void GLManager_OSX::window_update(DisplayServer::WindowID p_window_id) { [win.context update]; } -void GLManager_OSX::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) { +void GLManager_MacOS::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) { if (!windows.has(p_window_id)) { return; } @@ -197,11 +197,11 @@ void GLManager_OSX::window_set_per_pixel_transparency_enabled(DisplayServer::Win [win.context update]; } -Error GLManager_OSX::initialize() { +Error GLManager_MacOS::initialize() { return OK; } -void GLManager_OSX::set_use_vsync(bool p_use) { +void GLManager_MacOS::set_use_vsync(bool p_use) { use_vsync = p_use; CGLContextObj ctx = CGLGetCurrentContext(); @@ -212,17 +212,17 @@ void GLManager_OSX::set_use_vsync(bool p_use) { } } -bool GLManager_OSX::is_using_vsync() const { +bool GLManager_MacOS::is_using_vsync() const { return use_vsync; } -GLManager_OSX::GLManager_OSX(ContextType p_context_type) { +GLManager_MacOS::GLManager_MacOS(ContextType p_context_type) { context_type = p_context_type; } -GLManager_OSX::~GLManager_OSX() { +GLManager_MacOS::~GLManager_MacOS() { release_current(); } #endif // GLES3_ENABLED -#endif // OSX +#endif // MACOS_ENABLED diff --git a/platform/osx/godot_application.h b/platform/macos/godot_application.h index 8d48a659f3..8d48a659f3 100644 --- a/platform/osx/godot_application.h +++ b/platform/macos/godot_application.h diff --git a/platform/osx/godot_application.mm b/platform/macos/godot_application.mm index 13313a025a..3f71c77fd1 100644 --- a/platform/osx/godot_application.mm +++ b/platform/macos/godot_application.mm @@ -30,12 +30,12 @@ #include "godot_application.h" -#include "display_server_osx.h" +#include "display_server_macos.h" @implementation GodotApplication - (void)sendEvent:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { if ([event type] == NSEventTypeLeftMouseDown || [event type] == NSEventTypeRightMouseDown || [event type] == NSEventTypeOtherMouseDown) { if (ds->mouse_process_popups()) { diff --git a/platform/osx/godot_application_delegate.h b/platform/macos/godot_application_delegate.h index f5b67b580f..f5b67b580f 100644 --- a/platform/osx/godot_application_delegate.h +++ b/platform/macos/godot_application_delegate.h diff --git a/platform/osx/godot_application_delegate.mm b/platform/macos/godot_application_delegate.mm index 4d3558b273..bacdcc2bc4 100644 --- a/platform/osx/godot_application_delegate.mm +++ b/platform/macos/godot_application_delegate.mm @@ -30,8 +30,8 @@ #include "godot_application_delegate.h" -#include "display_server_osx.h" -#include "os_osx.h" +#include "display_server_macos.h" +#include "os_macos.h" @implementation GodotApplicationDelegate @@ -78,7 +78,7 @@ } - (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { - OS_OSX *os = (OS_OSX *)OS::get_singleton(); + OS_MacOS *os = (OS_MacOS *)OS::get_singleton(); if (!event || !os) { return; } @@ -114,7 +114,7 @@ } - (void)applicationDidResignActive:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { ds->mouse_process_popups(true); } @@ -130,14 +130,14 @@ } - (void)globalMenuCallback:(id)sender { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { return ds->menu_callback(sender); } } - (NSMenu *)applicationDockMenu:(NSApplication *)sender { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { return ds->get_dock_menu(); } else { @@ -146,15 +146,15 @@ } - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { - ds->send_window_event(ds->get_window(DisplayServerOSX::MAIN_WINDOW_ID), DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + ds->send_window_event(ds->get_window(DisplayServerMacOS::MAIN_WINDOW_ID), DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST); } return NSTerminateCancel; } - (void)showAbout:(id)sender { - OS_OSX *os = (OS_OSX *)OS::get_singleton(); + OS_MacOS *os = (OS_MacOS *)OS::get_singleton(); if (os && os->get_main_loop()) { os->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); } diff --git a/platform/osx/godot_content_view.h b/platform/macos/godot_content_view.h index 353305aec1..353305aec1 100644 --- a/platform/osx/godot_content_view.h +++ b/platform/macos/godot_content_view.h diff --git a/platform/osx/godot_content_view.mm b/platform/macos/godot_content_view.mm index 018b90e629..9ca7498a15 100644 --- a/platform/osx/godot_content_view.mm +++ b/platform/macos/godot_content_view.mm @@ -30,8 +30,8 @@ #include "godot_content_view.h" -#include "display_server_osx.h" -#include "key_mapping_osx.h" +#include "display_server_macos.h" +#include "key_mapping_macos.h" @implementation GodotContentView @@ -56,7 +56,7 @@ return self; } -- (void)setWindowID:(DisplayServerOSX::WindowID)wid { +- (void)setWindowID:(DisplayServerMacOS::WindowID)wid { window_id = wid; } @@ -67,7 +67,7 @@ } - (void)updateLayer { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); ds->window_update(window_id); [super updateLayer]; } @@ -106,12 +106,12 @@ return; } - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); if (wd.im_active) { ime_input_event_in_progress = true; ds->update_im_text(Point2i(selectedRange.location, selectedRange.length), String::utf8([[marked_text mutableString] UTF8String])); @@ -126,12 +126,12 @@ ime_input_event_in_progress = false; [[marked_text mutableString] setString:@""]; - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); if (wd.im_active) { ds->update_im_text(Point2i(), String()); } @@ -150,12 +150,12 @@ } - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return NSMakeRect(0, 0, 0, 0); } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); const NSRect content_rect = [wd.window_view frame]; const float scale = ds->screen_get_max_scale(); NSRect point_in_window_rect = NSMakeRect(wd.im_position.x / scale, content_rect.size.height - (wd.im_position.y / scale) - 1, 0, 0); @@ -191,7 +191,7 @@ return; } - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { [self cancelComposition]; return; @@ -210,10 +210,10 @@ continue; } - DisplayServerOSX::KeyEvent ke; + DisplayServerMacOS::KeyEvent ke; ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; + ke.macos_state = [event modifierFlags]; ke.pressed = true; ke.echo = false; ke.raw = false; // IME input event. @@ -237,12 +237,12 @@ } - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return NO; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); if (!wd.drop_files_callback.is_null()) { Vector<String> files; NSPasteboard *pboard = [sender draggingPasteboard]; @@ -276,12 +276,12 @@ // MARK: Focus - (BOOL)canBecomeKeyView { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return YES; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); return !wd.no_focus && !wd.is_popup; } @@ -292,7 +292,7 @@ // MARK: Mouse - (void)cursorUpdate:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds) { return; } @@ -301,12 +301,12 @@ } - (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index mask:(MouseButton)mask pressed:(bool)pressed { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); MouseButton last_button_state = ds->mouse_get_button_state(); if (pressed) { @@ -356,12 +356,12 @@ } - (void)mouseMoved:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); NSPoint delta = NSMakePoint([event deltaX], [event deltaY]); NSPoint mpos = [event locationInWindow]; @@ -438,38 +438,38 @@ } - (void)mouseExited:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) { - ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_EXIT); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_MOUSE_EXIT); } } - (void)mouseEntered:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) { - ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_MOUSE_ENTER); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_MOUSE_ENTER); } ds->cursor_update_shape(); } - (void)magnifyWithEvent:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); Ref<InputEventMagnifyGesture> ev; ev.instantiate(); @@ -497,12 +497,12 @@ // MARK: Keyboard - (void)keyDown:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); ignore_momentum_scroll = true; @@ -511,7 +511,7 @@ NSString *characters = [event characters]; NSUInteger length = [characters length]; - if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]))) { + if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]))) { // Fallback unicode character handler used if IME is not active. Char16String text; text.resize([characters length] + 1); @@ -523,28 +523,28 @@ for (int i = 0; i < u32text.length(); i++) { const char32_t codepoint = u32text[i]; - DisplayServerOSX::KeyEvent ke; + DisplayServerMacOS::KeyEvent ke; ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; + ke.macos_state = [event modifierFlags]; ke.pressed = true; ke.echo = [event isARepeat]; - ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]); - ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]); + ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); ke.raw = true; ke.unicode = codepoint; ds->push_to_key_event_buffer(ke); } } else { - DisplayServerOSX::KeyEvent ke; + DisplayServerMacOS::KeyEvent ke; ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; + ke.macos_state = [event modifierFlags]; ke.pressed = true; ke.echo = [event isARepeat]; - ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]); - ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]); + ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); ke.raw = false; ke.unicode = 0; @@ -559,7 +559,7 @@ } - (void)flagsChanged:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } @@ -567,7 +567,7 @@ // Ignore all input if IME input is in progress if (!ime_input_event_in_progress) { - DisplayServerOSX::KeyEvent ke; + DisplayServerMacOS::KeyEvent ke; ke.window_id = window_id; ke.echo = false; @@ -608,9 +608,9 @@ return; } - ke.osx_state = mod; - ke.keycode = KeyMappingOSX::remap_key(key, mod); - ke.physical_keycode = KeyMappingOSX::translate_key(key); + ke.macos_state = mod; + ke.keycode = KeyMappingMacOS::remap_key(key, mod); + ke.physical_keycode = KeyMappingMacOS::translate_key(key); ke.unicode = 0; ds->push_to_key_event_buffer(ke); @@ -618,12 +618,12 @@ } - (void)keyUp:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); // Ignore all input if IME input is in progress. if (!ime_input_event_in_progress) { @@ -631,7 +631,7 @@ NSUInteger length = [characters length]; // Fallback unicode character handler used if IME is not active. - if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]))) { + if (!wd.im_active && length > 0 && keycode_has_unicode(KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]))) { Char16String text; text.resize([characters length] + 1); [characters getCharacters:(unichar *)text.ptrw() range:NSMakeRange(0, [characters length])]; @@ -641,28 +641,28 @@ for (int i = 0; i < u32text.length(); i++) { const char32_t codepoint = u32text[i]; - DisplayServerOSX::KeyEvent ke; + DisplayServerMacOS::KeyEvent ke; ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; + ke.macos_state = [event modifierFlags]; ke.pressed = false; ke.echo = [event isARepeat]; - ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]); - ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]); + ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); ke.raw = true; ke.unicode = codepoint; ds->push_to_key_event_buffer(ke); } } else { - DisplayServerOSX::KeyEvent ke; + DisplayServerMacOS::KeyEvent ke; ke.window_id = window_id; - ke.osx_state = [event modifierFlags]; + ke.macos_state = [event modifierFlags]; ke.pressed = false; ke.echo = [event isARepeat]; - ke.keycode = KeyMappingOSX::remap_key([event keyCode], [event modifierFlags]); - ke.physical_keycode = KeyMappingOSX::translate_key([event keyCode]); + ke.keycode = KeyMappingMacOS::remap_key([event keyCode], [event modifierFlags]); + ke.physical_keycode = KeyMappingMacOS::translate_key([event keyCode]); ke.raw = true; ke.unicode = 0; @@ -674,12 +674,12 @@ // MARK: Scroll and pan - (void)processScrollEvent:(NSEvent *)event button:(MouseButton)button factor:(double)factor { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); MouseButton mask = mouse_button_to_mask(button); Ref<InputEventMouseButton> sc; @@ -713,12 +713,12 @@ } - (void)processPanEvent:(NSEvent *)event dx:(double)dx dy:(double)dy { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); Ref<InputEventPanGesture> pg; pg.instantiate(); @@ -732,12 +732,12 @@ } - (void)scrollWheel:(NSEvent *)event { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); ds->update_mouse_pos(wd, [event locationInWindow]); double delta_x = [event scrollingDeltaX]; diff --git a/platform/osx/godot_main_osx.mm b/platform/macos/godot_main_macos.mm index 722928ad60..66071f1404 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/macos/godot_main_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* godot_main_osx.mm */ +/* godot_main_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -30,7 +30,7 @@ #include "main/main.h" -#include "os_osx.h" +#include "os_macos.h" #include <string.h> #include <unistd.h> @@ -68,7 +68,7 @@ int main(int argc, char **argv) { printf("Current path: %s\n", cwd); #endif - OS_OSX os; + OS_MacOS os; Error err; // We must override main when testing is enabled. diff --git a/platform/osx/godot_menu_item.h b/platform/macos/godot_menu_item.h index 2c12897f10..2c12897f10 100644 --- a/platform/osx/godot_menu_item.h +++ b/platform/macos/godot_menu_item.h diff --git a/platform/osx/godot_window.h b/platform/macos/godot_window.h index 16ff101142..9fc5599e86 100644 --- a/platform/osx/godot_window.h +++ b/platform/macos/godot_window.h @@ -44,4 +44,4 @@ @end -#endif //GODOT_WINDOW_H +#endif // GODOT_WINDOW_H diff --git a/platform/osx/godot_window.mm b/platform/macos/godot_window.mm index d43853a94b..e205e7546d 100644 --- a/platform/osx/godot_window.mm +++ b/platform/macos/godot_window.mm @@ -30,7 +30,7 @@ #include "godot_window.h" -#include "display_server_osx.h" +#include "display_server_macos.h" @implementation GodotWindow @@ -40,29 +40,29 @@ return self; } -- (void)setWindowID:(DisplayServerOSX::WindowID)wid { +- (void)setWindowID:(DisplayServerMacOS::WindowID)wid { window_id = wid; } - (BOOL)canBecomeKeyWindow { // Required for NSWindowStyleMaskBorderless windows. - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return YES; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); return !wd.no_focus && !wd.is_popup; } - (BOOL)canBecomeMainWindow { // Required for NSWindowStyleMaskBorderless windows. - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return YES; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); return !wd.no_focus && !wd.is_popup; } diff --git a/platform/osx/godot_window_delegate.h b/platform/macos/godot_window_delegate.h index 8a1f681fcd..98c226aa2f 100644 --- a/platform/osx/godot_window_delegate.h +++ b/platform/macos/godot_window_delegate.h @@ -44,4 +44,4 @@ @end -#endif //GODOT_WINDOW_DELEGATE_H +#endif // GODOT_WINDOW_DELEGATE_H diff --git a/platform/osx/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm index 521127f01b..e1e88274f0 100644 --- a/platform/osx/godot_window_delegate.mm +++ b/platform/macos/godot_window_delegate.mm @@ -30,7 +30,7 @@ #include "godot_window_delegate.h" -#include "display_server_osx.h" +#include "display_server_macos.h" @implementation GodotWindowDelegate @@ -39,42 +39,42 @@ } - (BOOL)windowShouldClose:(id)sender { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return YES; } - ds->send_window_event(ds->get_window(window_id), DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + ds->send_window_event(ds->get_window(window_id), DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST); return NO; } - (void)windowWillClose:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } ds->popup_close(window_id); - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); while (wd.transient_children.size()) { - ds->window_set_transient(*wd.transient_children.begin(), DisplayServerOSX::INVALID_WINDOW_ID); + ds->window_set_transient(*wd.transient_children.begin(), DisplayServerMacOS::INVALID_WINDOW_ID); } - if (wd.transient_parent != DisplayServerOSX::INVALID_WINDOW_ID) { - ds->window_set_transient(window_id, DisplayServerOSX::INVALID_WINDOW_ID); + if (wd.transient_parent != DisplayServerMacOS::INVALID_WINDOW_ID) { + ds->window_set_transient(window_id, DisplayServerMacOS::INVALID_WINDOW_ID); } ds->window_destroy(window_id); } - (void)windowDidEnterFullScreen:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); wd.fullscreen = true; // Reset window size limits. [wd.window_object setContentMinSize:NSMakeSize(0, 0)]; @@ -85,12 +85,12 @@ } - (void)windowDidExitFullScreen:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); wd.fullscreen = false; // Set window size limits. @@ -119,12 +119,12 @@ } - (void)windowDidChangeBackingProperties:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); CGFloat new_scale_factor = [wd.window_object backingScaleFactor]; CGFloat old_scale_factor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; @@ -137,7 +137,7 @@ wd.size.width = content_rect.size.width * scale; wd.size.height = content_rect.size.height * scale; - ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_DPI_CHANGE); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_DPI_CHANGE); CALayer *layer = [wd.window_view layer]; if (layer) { @@ -150,26 +150,26 @@ } - (void)windowWillStartLiveResize:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { ds->set_is_resizing(true); } } - (void)windowDidEndLiveResize:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (ds) { ds->set_is_resizing(false); } } - (void)windowDidResize:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); const NSRect content_rect = [wd.window_view frame]; const float scale = ds->screen_get_max_scale(); wd.size.width = content_rect.size.width * scale; @@ -192,12 +192,12 @@ } - (void)windowDidMove:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); ds->release_pressed_events(); if (!wd.rect_changed_callback.is_null()) { @@ -210,12 +210,12 @@ } - (void)windowDidBecomeKey:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); if (ds->mouse_get_mode() == DisplayServer::MOUSE_MODE_CAPTURED) { const NSRect content_rect = [wd.window_view frame]; @@ -228,43 +228,43 @@ } ds->set_last_focused_window(window_id); - ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN); } - (void)windowDidResignKey:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); ds->release_pressed_events(); - ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT); } - (void)windowDidMiniaturize:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); ds->release_pressed_events(); - ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_OUT); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT); } - (void)windowDidDeminiaturize:(NSNotification *)notification { - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { return; } - DisplayServerOSX::WindowData &wd = ds->get_window(window_id); + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); ds->set_last_focused_window(window_id); - ds->send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN); + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN); } @end diff --git a/platform/osx/joypad_osx.cpp b/platform/macos/joypad_macos.cpp index be9567e17c..1ddcfec1b5 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/macos/joypad_macos.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joypad_osx.cpp */ +/* joypad_macos.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "joypad_osx.h" +#include "joypad_macos.h" #include <machine/endian.h> #define GODOT_JOY_LOOP_RUN_MODE CFSTR("GodotJoypad") -static JoypadOSX *self = nullptr; +static JoypadMacOS *self = nullptr; joypad::joypad() { ff_constant_force.lMagnitude = 10000; @@ -235,7 +235,7 @@ static bool is_joypad(IOHIDDeviceRef p_device_ref) { return true; } -void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) { +void JoypadMacOS::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) { if (p_res != kIOReturnSuccess || have_device(p_device)) { return; } @@ -258,7 +258,7 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) { IOHIDDeviceScheduleWithRunLoop(p_device, CFRunLoopGetCurrent(), GODOT_JOY_LOOP_RUN_MODE); } -void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) { +void JoypadMacOS::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) { int device = get_joy_ref(p_device); ERR_FAIL_COND(device == -1); @@ -278,7 +278,7 @@ static String _hex_str(uint8_t p_byte) { return ret; } -bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { +bool JoypadMacOS::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { p_joy->device_ref = p_device_ref; // Get device name. String name; @@ -445,7 +445,7 @@ static HatMask process_hat_value(int p_min, int p_max, int p_value, bool p_offse return hat_value; } -void JoypadOSX::poll_joypads() const { +void JoypadMacOS::poll_joypads() const { while (CFRunLoopRunInMode(GODOT_JOY_LOOP_RUN_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { // No-op. Pending callbacks will fire. } @@ -456,7 +456,7 @@ static float axis_correct(int p_value, int p_min, int p_max) { return 2.0f * (p_value - p_min) / (p_max - p_min) - 1.0f; } -void JoypadOSX::process_joypads() { +void JoypadMacOS::process_joypads() { poll_joypads(); for (int i = 0; i < device_list.size(); i++) { @@ -494,7 +494,7 @@ void JoypadOSX::process_joypads() { } } -void JoypadOSX::joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp) { +void JoypadMacOS::joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp) { joypad *joy = &device_list.write[get_joy_index(p_id)]; joy->ff_timestamp = p_timestamp; joy->ff_effect.dwDuration = p_duration * FF_SECONDS; @@ -503,13 +503,13 @@ void JoypadOSX::joypad_vibration_start(int p_id, float p_magnitude, float p_dura FFEffectStart(joy->ff_object, 1, 0); } -void JoypadOSX::joypad_vibration_stop(int p_id, uint64_t p_timestamp) { +void JoypadMacOS::joypad_vibration_stop(int p_id, uint64_t p_timestamp) { joypad *joy = &device_list.write[get_joy_index(p_id)]; joy->ff_timestamp = p_timestamp; FFEffectStop(joy->ff_object); } -int JoypadOSX::get_joy_index(int p_id) const { +int JoypadMacOS::get_joy_index(int p_id) const { for (int i = 0; i < device_list.size(); i++) { if (device_list[i].id == p_id) { return i; @@ -518,7 +518,7 @@ int JoypadOSX::get_joy_index(int p_id) const { return -1; } -int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const { +int JoypadMacOS::get_joy_ref(IOHIDDeviceRef p_device) const { for (int i = 0; i < device_list.size(); i++) { if (device_list[i].device_ref == p_device) { return i; @@ -527,7 +527,7 @@ int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const { return -1; } -bool JoypadOSX::have_device(IOHIDDeviceRef p_device) const { +bool JoypadMacOS::have_device(IOHIDDeviceRef p_device) const { for (int i = 0; i < device_list.size(); i++) { if (device_list[i].device_ref == p_device) { return true; @@ -561,7 +561,7 @@ static CFDictionaryRef create_match_dictionary(const UInt32 page, const UInt32 u return retval; } -void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const { +void JoypadMacOS::config_hid_manager(CFArrayRef p_matching_array) const { CFRunLoopRef runloop = CFRunLoopGetCurrent(); IOReturn ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); ERR_FAIL_COND(ret != kIOReturnSuccess); @@ -576,7 +576,7 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const { } } -JoypadOSX::JoypadOSX(Input *in) { +JoypadMacOS::JoypadMacOS(Input *in) { self = this; input = in; @@ -604,7 +604,7 @@ JoypadOSX::JoypadOSX(Input *in) { } } -JoypadOSX::~JoypadOSX() { +JoypadMacOS::~JoypadMacOS() { for (int i = 0; i < device_list.size(); i++) { device_list.write[i].free(); } diff --git a/platform/osx/joypad_osx.h b/platform/macos/joypad_macos.h index 3f89048ce6..4b14fed6d5 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/macos/joypad_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* joypad_osx.h */ +/* joypad_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef JOYPADOSX_H -#define JOYPADOSX_H +#ifndef JOYPAD_MACOS_H +#define JOYPAD_MACOS_H #ifdef MACOS_10_0_4 #import <IOKit/hidsystem/IOHIDUsageTables.h> @@ -88,7 +88,7 @@ struct joypad { joypad(); }; -class JoypadOSX { +class JoypadMacOS { enum { JOYPADS_MAX = 16, }; @@ -117,8 +117,8 @@ public: void _device_added(IOReturn p_res, IOHIDDeviceRef p_device); void _device_removed(IOReturn p_res, IOHIDDeviceRef p_device); - JoypadOSX(Input *in); - ~JoypadOSX(); + JoypadMacOS(Input *in); + ~JoypadMacOS(); }; -#endif // JOYPADOSX_H +#endif // JOYPAD_MACOS_H diff --git a/platform/osx/key_mapping_osx.h b/platform/macos/key_mapping_macos.h index 252cc907bb..fc5b791e44 100644 --- a/platform/osx/key_mapping_osx.h +++ b/platform/macos/key_mapping_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* key_mapping_osx.h */ +/* key_mapping_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef KEY_MAPPING_OSX_H -#define KEY_MAPPING_OSX_H +#ifndef KEY_MAPPING_MACOS_H +#define KEY_MAPPING_MACOS_H #include "core/os/keyboard.h" -class KeyMappingOSX { - KeyMappingOSX() {} +class KeyMappingMacOS { + KeyMappingMacOS() {} static bool is_numpad_key(unsigned int key); @@ -49,4 +49,4 @@ public: static unsigned int keycode_get_native_mask(Key p_keycode); }; -#endif // KEY_MAPPING_OSX_H +#endif // KEY_MAPPING_MACOS_H diff --git a/platform/osx/key_mapping_osx.mm b/platform/macos/key_mapping_macos.mm index 0bf6bc7d1c..f6cff7124b 100644 --- a/platform/osx/key_mapping_osx.mm +++ b/platform/macos/key_mapping_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* key_mapping_osx.mm */ +/* key_mapping_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "key_mapping_osx.h" +#include "key_mapping_macos.h" #import <Carbon/Carbon.h> #import <Cocoa/Cocoa.h> -bool KeyMappingOSX::is_numpad_key(unsigned int key) { +bool KeyMappingMacOS::is_numpad_key(unsigned int key) { static const unsigned int table[] = { 0x41, /* kVK_ANSI_KeypadDecimal */ 0x43, /* kVK_ANSI_KeypadMultiply */ @@ -65,7 +65,7 @@ bool KeyMappingOSX::is_numpad_key(unsigned int key) { } // Keyboard symbol translation table. -static const Key _osx_to_godot_table[128] = { +static const Key _macos_to_godot_table[128] = { /* 00 */ Key::A, /* 01 */ Key::S, /* 02 */ Key::D, @@ -197,18 +197,18 @@ static const Key _osx_to_godot_table[128] = { }; // Translates a OS X keycode to a Godot keycode. -Key KeyMappingOSX::translate_key(unsigned int key) { +Key KeyMappingMacOS::translate_key(unsigned int key) { if (key >= 128) { return Key::UNKNOWN; } - return _osx_to_godot_table[key]; + return _macos_to_godot_table[key]; } -// Translates a Godot keycode back to a OSX keycode. -unsigned int KeyMappingOSX::unmap_key(Key key) { +// Translates a Godot keycode back to a macOS keycode. +unsigned int KeyMappingMacOS::unmap_key(Key key) { for (int i = 0; i <= 126; i++) { - if (_osx_to_godot_table[i] == key) { + if (_macos_to_godot_table[i] == key) { return i; } } @@ -279,7 +279,7 @@ static const _KeyCodeMap _keycodes[55] = { }; // Remap key according to current keyboard layout. -Key KeyMappingOSX::remap_key(unsigned int key, unsigned int state) { +Key KeyMappingMacOS::remap_key(unsigned int key, unsigned int state) { if (is_numpad_key(key)) { return translate_key(key); } @@ -463,7 +463,7 @@ static const _KeyCodeText _native_keycodes[] = { /* clang-format on */ }; -String KeyMappingOSX::keycode_get_native_string(Key p_keycode) { +String KeyMappingMacOS::keycode_get_native_string(Key p_keycode) { const _KeyCodeText *kct = &_native_keycodes[0]; while (kct->text) { @@ -475,7 +475,7 @@ String KeyMappingOSX::keycode_get_native_string(Key p_keycode) { return String(); } -unsigned int KeyMappingOSX::keycode_get_native_mask(Key p_keycode) { +unsigned int KeyMappingMacOS::keycode_get_native_mask(Key p_keycode) { unsigned int mask = 0; if ((p_keycode & KeyModifierMask::CTRL) != Key::NONE) { mask |= NSEventModifierFlagControl; diff --git a/platform/osx/logo.png b/platform/macos/logo.png Binary files differindex b5a660b165..b5a660b165 100644 --- a/platform/osx/logo.png +++ b/platform/macos/logo.png diff --git a/platform/osx/osx_terminal_logger.h b/platform/macos/macos_terminal_logger.h index 8413509c4b..a811a5cbaf 100644 --- a/platform/osx/osx_terminal_logger.h +++ b/platform/macos/macos_terminal_logger.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* osx_terminal_logger.h */ +/* macos_terminal_logger.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,17 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OSX_TERMINAL_LOGGER_H -#define OSX_TERMINAL_LOGGER_H +#ifndef MACOS_TERMINAL_LOGGER_H +#define MACOS_TERMINAL_LOGGER_H -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED #include "core/io/logger.h" -class OSXTerminalLogger : public StdLogger { +class MacOSTerminalLogger : public StdLogger { public: virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) override; }; -#endif // OSX_ENABLED -#endif // OSX_TERMINAL_LOGGER_H +#endif // MACOS_ENABLED + +#endif // MACOS_TERMINAL_LOGGER_H diff --git a/platform/osx/osx_terminal_logger.mm b/platform/macos/macos_terminal_logger.mm index 48e26f42bf..b5ea2938ee 100644 --- a/platform/osx/osx_terminal_logger.mm +++ b/platform/macos/macos_terminal_logger.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* osx_terminal_logger.mm */ +/* macos_terminal_logger.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "osx_terminal_logger.h" +#include "macos_terminal_logger.h" -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED #include <os/log.h> -void OSXTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) { +void MacOSTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) { if (!should_log(true)) { return; } @@ -79,4 +79,4 @@ void OSXTerminalLogger::log_error(const char *p_function, const char *p_file, in } } -#endif // OSX_ENABLED +#endif // MACOS_ENABLED diff --git a/platform/osx/os_osx.h b/platform/macos/os_macos.h index b105be4a06..a1eb0f7f69 100644 --- a/platform/osx/os_osx.h +++ b/platform/macos/os_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* os_osx.h */ +/* os_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef OS_OSX_H -#define OS_OSX_H +#ifndef OS_MACOS_H +#define OS_MACOS_H #include "core/input/input.h" -#include "crash_handler_osx.h" +#include "crash_handler_macos.h" #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/coremidi/midi_driver_coremidi.h" #include "drivers/unix/os_unix.h" -#include "joypad_osx.h" +#include "joypad_macos.h" #include "servers/audio_server.h" -class OS_OSX : public OS_Unix { +class OS_MacOS : public OS_Unix { bool force_quit = false; - JoypadOSX *joypad_osx = nullptr; + JoypadMacOS *joypad_macos = nullptr; #ifdef COREAUDIO_ENABLED AudioDriverCoreAudio audio_driver; @@ -97,6 +97,8 @@ public: virtual String get_locale() const override; + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; virtual String get_executable_path() const override; virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override; virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; @@ -113,8 +115,8 @@ public: void run(); - OS_OSX(); - ~OS_OSX(); + OS_MacOS(); + ~OS_MacOS(); }; -#endif +#endif // OS_MACOS_H diff --git a/platform/osx/os_osx.mm b/platform/macos/os_macos.mm index 5230ed4155..cc550043de 100644 --- a/platform/osx/os_osx.mm +++ b/platform/macos/os_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* os_osx.mm */ +/* os_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,16 +28,16 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "os_osx.h" +#include "os_macos.h" #include "core/version_generated.gen.h" #include "main/main.h" -#include "dir_access_osx.h" -#include "display_server_osx.h" +#include "dir_access_macos.h" +#include "display_server_macos.h" #include "godot_application.h" #include "godot_application_delegate.h" -#include "osx_terminal_logger.h" +#include "macos_terminal_logger.h" #include <dlfcn.h> #include <libproc.h> @@ -45,7 +45,7 @@ #include <os/log.h> #include <sys/sysctl.h> -_FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) { +_FORCE_INLINE_ String OS_MacOS::get_framework_executable(const String &p_path) { // Append framework executable name, or return as is if p_path is not a framework. Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); if (da->dir_exists(p_path) && da->file_exists(p_path.plus_file(p_path.get_file().get_basename()))) { @@ -55,10 +55,10 @@ _FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) { } } -void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) { +void OS_MacOS::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) { // Prevent main loop from sleeping and redraw window during resize / modal popups. - DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD || !ds->get_is_resizing())) { Main::force_redraw(); if (!Main::is_iterating()) { // Avoid cyclic loop. @@ -69,13 +69,13 @@ void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActi CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Prevent main loop from sleeping. } -void OS_OSX::initialize() { +void OS_MacOS::initialize() { crash_handler.initialize(); initialize_core(); } -String OS_OSX::get_processor_name() const { +String OS_MacOS::get_processor_name() const { char buffer[256]; size_t buffer_len = 256; if (sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_len, NULL, 0) == 0) { @@ -84,35 +84,35 @@ String OS_OSX::get_processor_name() const { ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string.")); } -void OS_OSX::initialize_core() { +void OS_MacOS::initialize_core() { OS_Unix::initialize_core(); - DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_RESOURCES); - DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_USERDATA); - DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_FILESYSTEM); + DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_RESOURCES); + DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_USERDATA); + DirAccess::make_default<DirAccessMacOS>(DirAccess::ACCESS_FILESYSTEM); } -void OS_OSX::finalize() { +void OS_MacOS::finalize() { #ifdef COREMIDI_ENABLED midi_driver.close(); #endif delete_main_loop(); - if (joypad_osx) { - memdelete(joypad_osx); + if (joypad_macos) { + memdelete(joypad_macos); } } -void OS_OSX::initialize_joypads() { - joypad_osx = memnew(JoypadOSX(Input::get_singleton())); +void OS_MacOS::initialize_joypads() { + joypad_macos = memnew(JoypadMacOS(Input::get_singleton())); } -void OS_OSX::set_main_loop(MainLoop *p_main_loop) { +void OS_MacOS::set_main_loop(MainLoop *p_main_loop) { main_loop = p_main_loop; } -void OS_OSX::delete_main_loop() { +void OS_MacOS::delete_main_loop() { if (!main_loop) { return; } @@ -121,19 +121,19 @@ void OS_OSX::delete_main_loop() { main_loop = nullptr; } -void OS_OSX::set_cmdline_platform_args(const List<String> &p_args) { +void OS_MacOS::set_cmdline_platform_args(const List<String> &p_args) { launch_service_args = p_args; } -List<String> OS_OSX::get_cmdline_platform_args() const { +List<String> OS_MacOS::get_cmdline_platform_args() const { return launch_service_args; } -String OS_OSX::get_name() const { +String OS_MacOS::get_name() const { return "macOS"; } -void OS_OSX::alert(const String &p_alert, const String &p_title) { +void OS_MacOS::alert(const String &p_alert, const String &p_title) { NSAlert *window = [[NSAlert alloc] init]; NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()]; NSString *ns_alert = [NSString stringWithUTF8String:p_alert.utf8().get_data()]; @@ -150,7 +150,7 @@ void OS_OSX::alert(const String &p_alert, const String &p_title) { } } -Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { +Error OS_MacOS::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) { String path = get_framework_executable(p_path); if (!FileAccess::exists(path)) { @@ -173,11 +173,11 @@ Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, return OK; } -MainLoop *OS_OSX::get_main_loop() const { +MainLoop *OS_MacOS::get_main_loop() const { return main_loop; } -String OS_OSX::get_config_path() const { +String OS_MacOS::get_config_path() const { // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well. if (has_environment("XDG_CONFIG_HOME")) { if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) { @@ -192,7 +192,7 @@ String OS_OSX::get_config_path() const { return "."; } -String OS_OSX::get_data_path() const { +String OS_MacOS::get_data_path() const { // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well. if (has_environment("XDG_DATA_HOME")) { if (get_environment("XDG_DATA_HOME").is_absolute_path()) { @@ -204,7 +204,7 @@ String OS_OSX::get_data_path() const { return get_config_path(); } -String OS_OSX::get_cache_path() const { +String OS_MacOS::get_cache_path() const { // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on macOS as well. if (has_environment("XDG_CACHE_HOME")) { if (get_environment("XDG_CACHE_HOME").is_absolute_path()) { @@ -219,7 +219,7 @@ String OS_OSX::get_cache_path() const { return get_config_path(); } -String OS_OSX::get_bundle_resource_dir() const { +String OS_MacOS::get_bundle_resource_dir() const { String ret; NSBundle *main = [NSBundle mainBundle]; @@ -230,7 +230,7 @@ String OS_OSX::get_bundle_resource_dir() const { return ret; } -String OS_OSX::get_bundle_icon_path() const { +String OS_MacOS::get_bundle_icon_path() const { String ret; NSBundle *main = [NSBundle mainBundle]; @@ -244,11 +244,11 @@ String OS_OSX::get_bundle_icon_path() const { } // Get properly capitalized engine name for system paths -String OS_OSX::get_godot_dir_name() const { +String OS_MacOS::get_godot_dir_name() const { return String(VERSION_SHORT_NAME).capitalize(); } -String OS_OSX::get_system_dir(SystemDir p_dir, bool p_shared_storage) const { +String OS_MacOS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const { NSSearchPathDirectory id; bool found = true; @@ -287,7 +287,7 @@ String OS_OSX::get_system_dir(SystemDir p_dir, bool p_shared_storage) const { return ret; } -Error OS_OSX::shell_open(String p_uri) { +Error OS_MacOS::shell_open(String p_uri) { NSString *string = [NSString stringWithUTF8String:p_uri.utf8().get_data()]; NSURL *uri = [[NSURL alloc] initWithString:string]; // Escape special characters in filenames @@ -298,12 +298,86 @@ Error OS_OSX::shell_open(String p_uri) { return OK; } -String OS_OSX::get_locale() const { +String OS_MacOS::get_locale() const { NSString *locale_code = [[NSLocale preferredLanguages] objectAtIndex:0]; return String([locale_code UTF8String]).replace("-", "_"); } -String OS_OSX::get_executable_path() const { +Vector<String> OS_MacOS::get_system_fonts() const { + HashSet<String> font_names; + CFArrayRef fonts = CTFontManagerCopyAvailableFontFamilyNames(); + if (fonts) { + for (CFIndex i = 0; i < CFArrayGetCount(fonts); i++) { + CFStringRef cf_name = (CFStringRef)CFArrayGetValueAtIndex(fonts, i); + if (cf_name && (CFStringGetLength(cf_name) > 0) && (CFStringCompare(cf_name, CFSTR("LastResort"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && (CFStringGetCharacterAtIndex(cf_name, 0) != '.')) { + NSString *ns_name = (__bridge NSString *)cf_name; + font_names.insert(String::utf8([ns_name UTF8String])); + } + } + CFRelease(fonts); + } + + Vector<String> ret; + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +} + +String OS_MacOS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { + String ret; + + String font_name = p_font_name; + if (font_name.to_lower() == "sans-serif") { + font_name = "Helvetica"; + } else if (font_name.to_lower() == "serif") { + font_name = "Times"; + } else if (font_name.to_lower() == "monospace") { + font_name = "Courier"; + } else if (font_name.to_lower() == "fantasy") { + font_name = "Papyrus"; + } else if (font_name.to_lower() == "cursive") { + font_name = "Apple Chancery"; + }; + + CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8); + + CTFontSymbolicTraits traits = 0; + if (p_bold) { + traits |= kCTFontBoldTrait; + } + if (p_italic) { + traits |= kCTFontItalicTrait; + } + + CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits); + CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits); + + CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr); + CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name); + CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict); + + CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes); + if (font) { + CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(font, kCTFontURLAttribute); + if (url) { + NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]]; + ret = String::utf8([font_path UTF8String]); + CFRelease(url); + } + CFRelease(font); + } + + CFRelease(attributes); + CFRelease(traits_dict); + CFRelease(sym_traits); + CFRelease(name); + + return ret; +} + +String OS_MacOS::get_executable_path() const { char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; int pid = getpid(); pid_t ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf)); @@ -317,7 +391,7 @@ String OS_OSX::get_executable_path() const { } } -Error OS_OSX::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) { +Error OS_MacOS::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id, bool p_open_console) { // Use NSWorkspace if path is an .app bundle. NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())]; NSBundle *bundle = [NSBundle bundleWithURL:url]; @@ -375,7 +449,7 @@ Error OS_OSX::create_process(const String &p_path, const List<String> &p_argumen } } -Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) { +Error OS_MacOS::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) { // If executable is bundled, always execute editor instances as an app bundle to ensure app window is registered and activated correctly. NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; if (nsappname != nil) { @@ -387,7 +461,7 @@ Error OS_OSX::create_instance(const List<String> &p_arguments, ProcessID *r_chil } } -String OS_OSX::get_unique_id() const { +String OS_MacOS::get_unique_id() const { static String serial_number; if (serial_number.is_empty()) { @@ -412,19 +486,19 @@ String OS_OSX::get_unique_id() const { return serial_number; } -bool OS_OSX::_check_internal_feature_support(const String &p_feature) { +bool OS_MacOS::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc"; } -void OS_OSX::disable_crash_handler() { +void OS_MacOS::disable_crash_handler() { crash_handler.disable(); } -bool OS_OSX::is_disable_crash_handler() const { +bool OS_MacOS::is_disable_crash_handler() const { return crash_handler.is_disabled(); } -Error OS_OSX::move_to_trash(const String &p_path) { +Error OS_MacOS::move_to_trash(const String &p_path) { NSFileManager *fm = [NSFileManager defaultManager]; NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())]; NSError *err; @@ -437,7 +511,7 @@ Error OS_OSX::move_to_trash(const String &p_path) { return OK; } -void OS_OSX::run() { +void OS_MacOS::run() { force_quit = false; if (!main_loop) { @@ -452,7 +526,7 @@ void OS_OSX::run() { if (DisplayServer::get_singleton()) { DisplayServer::get_singleton()->process_events(); // Get rid of pending events. } - joypad_osx->process_joypads(); + joypad_macos->process_joypads(); if (Main::iteration()) { quit = true; @@ -465,19 +539,19 @@ void OS_OSX::run() { main_loop->finalize(); } -OS_OSX::OS_OSX() { +OS_MacOS::OS_MacOS() { main_loop = nullptr; force_quit = false; Vector<Logger *> loggers; - loggers.push_back(memnew(OSXTerminalLogger)); + loggers.push_back(memnew(MacOSTerminalLogger)); _set_logger(memnew(CompositeLogger(loggers))); #ifdef COREAUDIO_ENABLED AudioDriverManager::add_driver(&audio_driver); #endif - DisplayServerOSX::register_osx_driver(); + DisplayServerMacOS::register_macos_driver(); // Implicitly create shared NSApplication instance. [GodotApplication sharedApplication]; @@ -518,7 +592,7 @@ OS_OSX::OS_OSX() { [NSApp activateIgnoringOtherApps:YES]; } -OS_OSX::~OS_OSX() { +OS_MacOS::~OS_MacOS() { CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes); CFRelease(pre_wait_observer); } diff --git a/platform/osx/platform_config.h b/platform/macos/platform_config.h index e114606b82..e114606b82 100644 --- a/platform/osx/platform_config.h +++ b/platform/macos/platform_config.h diff --git a/platform/osx/platform_osx_builders.py b/platform/macos/platform_macos_builders.py index 953ed479db..3a1cc92bd2 100644 --- a/platform/osx/platform_osx_builders.py +++ b/platform/macos/platform_macos_builders.py @@ -7,7 +7,7 @@ import os from platform_methods import subprocess_main -def make_debug_osx(target, source, env): +def make_debug_macos(target, source, env): if env["macports_clang"] != "no": mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local") mpclangver = env["macports_clang"] diff --git a/platform/osx/tts_osx.h b/platform/macos/tts_macos.h index 449418e48f..344676868a 100644 --- a/platform/osx/tts_osx.h +++ b/platform/macos/tts_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* tts_osx.h */ +/* tts_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TTS_OSX_H -#define TTS_OSX_H +#ifndef TTS_MACOS_H +#define TTS_MACOS_H #include "core/string/ustring.h" #include "core/templates/list.h" @@ -45,7 +45,7 @@ #import <AVFoundation/AVFoundation.h> #endif -@interface TTS_OSX : NSObject <AVSpeechSynthesizerDelegate> { +@interface TTS_MacOS : NSObject <AVSpeechSynthesizerDelegate> { // AVSpeechSynthesizer bool speaking; HashMap<id, int> ids; @@ -68,4 +68,4 @@ - (Array)getVoices; @end -#endif // TTS_OSX_H +#endif // TTS_MACOS_H diff --git a/platform/osx/tts_osx.mm b/platform/macos/tts_macos.mm index e6a5236cd9..3c101b9531 100644 --- a/platform/osx/tts_osx.mm +++ b/platform/macos/tts_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* tts_osx.mm */ +/* tts_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,9 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "tts_osx.h" +#include "tts_macos.h" -@implementation TTS_OSX +@implementation TTS_MacOS - (id)init { self = [super init]; diff --git a/platform/osx/vulkan_context_osx.h b/platform/macos/vulkan_context_macos.h index ade0f4a4c9..579c42b042 100644 --- a/platform/osx/vulkan_context_osx.h +++ b/platform/macos/vulkan_context_macos.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* vulkan_context_osx.h */ +/* vulkan_context_macos.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,20 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VULKAN_DEVICE_OSX_H -#define VULKAN_DEVICE_OSX_H +#ifndef VULKAN_CONTEXT_MACOS_H +#define VULKAN_CONTEXT_MACOS_H #include "drivers/vulkan/vulkan_context.h" #import <AppKit/AppKit.h> -class VulkanContextOSX : public VulkanContext { +class VulkanContextMacOS : public VulkanContext { virtual const char *_get_platform_surface_extension() const; public: Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height); - VulkanContextOSX(); - ~VulkanContextOSX(); + VulkanContextMacOS(); + ~VulkanContextMacOS(); }; -#endif // VULKAN_DEVICE_OSX_H +#endif // VULKAN_CONTEXT_MACOS_H diff --git a/platform/osx/vulkan_context_osx.mm b/platform/macos/vulkan_context_macos.mm index bdabc24c28..cf317f3c68 100644 --- a/platform/osx/vulkan_context_osx.mm +++ b/platform/macos/vulkan_context_macos.mm @@ -1,5 +1,5 @@ /*************************************************************************/ -/* vulkan_context_osx.mm */ +/* vulkan_context_macos.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "vulkan_context_osx.h" +#include "vulkan_context_macos.h" #ifdef USE_VOLK #include <volk.h> #else #include <vulkan/vulkan.h> #endif -const char *VulkanContextOSX::_get_platform_surface_extension() const { +const char *VulkanContextMacOS::_get_platform_surface_extension() const { return VK_MVK_MACOS_SURFACE_EXTENSION_NAME; } -Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) { +Error VulkanContextMacOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, id p_window, int p_width, int p_height) { VkMacOSSurfaceCreateInfoMVK createInfo; createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; createInfo.pNext = nullptr; @@ -52,8 +52,8 @@ Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, Displ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height); } -VulkanContextOSX::VulkanContextOSX() { +VulkanContextMacOS::VulkanContextMacOS() { } -VulkanContextOSX::~VulkanContextOSX() { +VulkanContextMacOS::~VulkanContextMacOS() { } diff --git a/platform/osx/SCsub b/platform/osx/SCsub deleted file mode 100644 index 3a4c95613d..0000000000 --- a/platform/osx/SCsub +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -from platform_methods import run_in_subprocess -import platform_osx_builders - -files = [ - "os_osx.mm", - "godot_application.mm", - "godot_application_delegate.mm", - "crash_handler_osx.mm", - "osx_terminal_logger.mm", - "display_server_osx.mm", - "godot_content_view.mm", - "godot_window_delegate.mm", - "godot_window.mm", - "key_mapping_osx.mm", - "godot_main_osx.mm", - "dir_access_osx.mm", - "tts_osx.mm", - "joypad_osx.cpp", - "vulkan_context_osx.mm", - "gl_manager_osx_legacy.mm", -] - -prog = env.add_program("#bin/godot", files) - -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/register_platform_apis.h b/platform/register_platform_apis.h index 8b6d23a7a4..9dd90d9b20 100644 --- a/platform/register_platform_apis.h +++ b/platform/register_platform_apis.h @@ -28,10 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef REGISTER_APIS_H -#define REGISTER_APIS_H +#ifndef REGISTER_PLATFORM_APIS_H +#define REGISTER_PLATFORM_APIS_H void register_platform_apis(); void unregister_platform_apis(); -#endif +#endif // REGISTER_PLATFORM_APIS_H diff --git a/platform/uwp/app_uwp.h b/platform/uwp/app_uwp.h index 9aadcfac75..82ad3ca01a 100644 --- a/platform/uwp/app_uwp.h +++ b/platform/uwp/app_uwp.h @@ -112,4 +112,5 @@ namespace GodotUWP } /* clang-format on */ + #endif // APP_UWP_H diff --git a/platform/uwp/export/app_packager.h b/platform/uwp/export/app_packager.h index dc5a5259ec..18db3eb806 100644 --- a/platform/uwp/export/app_packager.h +++ b/platform/uwp/export/app_packager.h @@ -40,7 +40,7 @@ #include "core/io/zip_io.h" #include "core/object/class_db.h" #include "core/version.h" -#include "editor/editor_export.h" +#include "editor/export/editor_export_platform.h" #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" @@ -146,4 +146,4 @@ public: ~AppxPackager(); }; -#endif +#endif // UWP_APP_PACKAGER_H diff --git a/platform/uwp/export/export_plugin.h b/platform/uwp/export/export_plugin.h index d92687075c..c1a1f8a935 100644 --- a/platform/uwp/export/export_plugin.h +++ b/platform/uwp/export/export_plugin.h @@ -39,9 +39,9 @@ #include "core/io/zip_io.h" #include "core/object/class_db.h" #include "core/version.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" +#include "editor/export/editor_export_platform.h" #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" @@ -446,4 +446,4 @@ public: EditorExportPlatformUWP(); }; -#endif +#endif // UWP_EXPORT_PLUGIN_H diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h index 0869f1961d..81f84152b9 100644 --- a/platform/uwp/joypad_uwp.h +++ b/platform/uwp/joypad_uwp.h @@ -78,4 +78,4 @@ private: void joypad_vibration_stop(int p_device, uint64_t p_timestamp); }; -#endif +#endif // JOYPAD_UWP_H diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 1614bfdcc3..f37759c66f 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -557,6 +557,7 @@ uint64_t OS_UWP::get_ticks_usec() const { void OS_UWP::process_events() { joypad->process_controllers(); process_key_events(); + input->flush_buffered_events(); } void OS_UWP::process_key_events() { diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index bddf63ff18..b9d035ff41 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -252,4 +252,4 @@ public: ~OS_UWP(); }; -#endif +#endif // OS_UWP_H diff --git a/platform/windows/detect.py b/platform/windows/detect.py index b82fe5e7ad..dd2df1f004 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -198,7 +198,6 @@ def configure_msvc(env, manual_msvc_config): elif env["target"] == "debug": env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"]) # Allow big objects. Only needed for debug, see MinGW branch for rationale. - env.AppendUnique(CCFLAGS=["/bigobj"]) env.Append(LINKFLAGS=["/DEBUG"]) if env["debug_symbols"]: @@ -221,6 +220,10 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"]) env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding. env.AppendUnique(CXXFLAGS=["/TP"]) # assume all sources are C++ + # Once it was thought that only debug builds would be too large, + # but this has recently stopped being true. See the mingw function + # for notes on why this shouldn't be enabled for gcc + env.AppendUnique(CCFLAGS=["/bigobj"]) if manual_msvc_config: # should be automatic if SCons found it if os.getenv("WindowsSdkDir") is not None: @@ -267,6 +270,7 @@ def configure_msvc(env, manual_msvc_config): "bcrypt", "Avrt", "dwmapi", + "dwrite", ] if env["vulkan"]: @@ -438,6 +442,7 @@ def configure_mingw(env): "avrt", "uuid", "dwmapi", + "dwrite", ] ) diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index af19f24f09..20320470b8 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -30,6 +30,7 @@ #include "export.h" +#include "editor/export/editor_export.h" #include "export_plugin.h" void register_windows_exporter() { diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h index 09399f2bee..1054e04b1e 100644 --- a/platform/windows/export/export.h +++ b/platform/windows/export/export.h @@ -33,4 +33,4 @@ void register_windows_exporter(); -#endif +#endif // WINDOWS_EXPORT_H diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index 16c67345e0..45bfc761fe 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -104,7 +104,7 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> } String EditorExportPlatformWindows::get_template_file_name(const String &p_target, const String &p_arch) const { - return "windows_" + p_arch + "_" + p_target + ".exe"; + return "windows_" + p_target + "_" + p_arch + ".exe"; } List<String> EditorExportPlatformWindows::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h index 51f98365a9..b9e59829a0 100644 --- a/platform/windows/export/export_plugin.h +++ b/platform/windows/export/export_plugin.h @@ -33,8 +33,8 @@ #include "core/io/file_access.h" #include "core/os/os.h" -#include "editor/editor_export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export_platform_pc.h" #include "platform/windows/logo.gen.h" class EditorExportPlatformWindows : public EditorExportPlatformPC { @@ -54,4 +54,4 @@ public: virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override; }; -#endif +#endif // WINDOWS_EXPORT_PLUGIN_H diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis index bb855e4ac8..899956d65a 100644 --- a/platform/windows/godot.natvis +++ b/platform/windows/godot.natvis @@ -41,10 +41,12 @@ <DisplayString Condition="type == Variant::AABB">{_data._aabb}</DisplayString> <DisplayString Condition="type == Variant::BASIS">{_data._basis}</DisplayString> <DisplayString Condition="type == Variant::TRANSFORM3D">{_data._transform}</DisplayString> + <DisplayString Condition="type == Variant::PROJECTION">{_data._projection}</DisplayString> <DisplayString Condition="type == Variant::STRING">{*(String *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::VECTOR2">{*(Vector2 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::RECT2">{*(Rect2 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::VECTOR3">{*(Vector3 *)_data._mem}</DisplayString> + <DisplayString Condition="type == Variant::VECTOR4">{*(Vector4 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::PLANE">{*(Plane *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::QUATERNION">{*(Quaternion *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString> diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 6f414c094c..ad4be950cc 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -48,6 +48,7 @@ #include <avrt.h> #include <bcrypt.h> #include <direct.h> +#include <dwrite.h> #include <knownfolders.h> #include <process.h> #include <regstr.h> @@ -621,6 +622,135 @@ Error OS_Windows::set_cwd(const String &p_cwd) { return OK; } +Vector<String> OS_Windows::get_system_fonts() const { + Vector<String> ret; + HashSet<String> font_names; + + ComAutoreleaseRef<IDWriteFactory> dwrite_factory; + HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory.reference)); + ERR_FAIL_COND_V(FAILED(hr) || dwrite_factory.is_null(), ret); + + ComAutoreleaseRef<IDWriteFontCollection> font_collection; + hr = dwrite_factory->GetSystemFontCollection(&font_collection.reference, false); + ERR_FAIL_COND_V(FAILED(hr) || font_collection.is_null(), ret); + + UINT32 family_count = font_collection->GetFontFamilyCount(); + for (UINT32 i = 0; i < family_count; i++) { + ComAutoreleaseRef<IDWriteFontFamily> family; + hr = font_collection->GetFontFamily(i, &family.reference); + ERR_CONTINUE(FAILED(hr) || family.is_null()); + + ComAutoreleaseRef<IDWriteLocalizedStrings> family_names; + hr = family->GetFamilyNames(&family_names.reference); + ERR_CONTINUE(FAILED(hr) || family_names.is_null()); + + UINT32 index = 0; + BOOL exists = false; + UINT32 length = 0; + Char16String name; + + hr = family_names->FindLocaleName(L"en-us", &index, &exists); + ERR_CONTINUE(FAILED(hr)); + + hr = family_names->GetStringLength(index, &length); + ERR_CONTINUE(FAILED(hr)); + + name.resize(length + 1); + hr = family_names->GetString(index, (WCHAR *)name.ptrw(), length + 1); + ERR_CONTINUE(FAILED(hr)); + + font_names.insert(String::utf16(name.ptr(), length)); + } + + for (const String &E : font_names) { + ret.push_back(E); + } + return ret; +} + +String OS_Windows::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const { + String font_name = p_font_name; + if (font_name.to_lower() == "sans-serif") { + font_name = "Arial"; + } else if (font_name.to_lower() == "serif") { + font_name = "Times New Roman"; + } else if (font_name.to_lower() == "monospace") { + font_name = "Courier New"; + } else if (font_name.to_lower() == "cursive") { + font_name = "Comic Sans MS"; + } else if (font_name.to_lower() == "fantasy") { + font_name = "Gabriola"; + } + + ComAutoreleaseRef<IDWriteFactory> dwrite_factory; + HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory.reference)); + ERR_FAIL_COND_V(FAILED(hr) || dwrite_factory.is_null(), String()); + + ComAutoreleaseRef<IDWriteFontCollection> font_collection; + hr = dwrite_factory->GetSystemFontCollection(&font_collection.reference, false); + ERR_FAIL_COND_V(FAILED(hr) || font_collection.is_null(), String()); + + UINT32 index = 0; + BOOL exists = false; + font_collection->FindFamilyName((const WCHAR *)font_name.utf16().get_data(), &index, &exists); + if (FAILED(hr)) { + return String(); + } + + ComAutoreleaseRef<IDWriteFontFamily> family; + hr = font_collection->GetFontFamily(index, &family.reference); + if (FAILED(hr) || family.is_null()) { + return String(); + } + + ComAutoreleaseRef<IDWriteFont> dwrite_font; + hr = family->GetFirstMatchingFont(p_bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, p_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, &dwrite_font.reference); + if (FAILED(hr) || dwrite_font.is_null()) { + return String(); + } + + ComAutoreleaseRef<IDWriteFontFace> dwrite_face; + hr = dwrite_font->CreateFontFace(&dwrite_face.reference); + if (FAILED(hr) || dwrite_face.is_null()) { + return String(); + } + + UINT32 number_of_files = 0; + hr = dwrite_face->GetFiles(&number_of_files, nullptr); + if (FAILED(hr)) { + return String(); + } + Vector<ComAutoreleaseRef<IDWriteFontFile>> files; + files.resize(number_of_files); + hr = dwrite_face->GetFiles(&number_of_files, (IDWriteFontFile **)files.ptrw()); + if (FAILED(hr)) { + return String(); + } + + for (UINT32 i = 0; i < number_of_files; i++) { + void const *reference_key = nullptr; + UINT32 reference_key_size = 0; + ComAutoreleaseRef<IDWriteLocalFontFileLoader> loader; + + hr = files.write[i]->GetLoader((IDWriteFontFileLoader **)&loader.reference); + if (FAILED(hr) || loader.is_null()) { + continue; + } + hr = files.write[i]->GetReferenceKey(&reference_key, &reference_key_size); + if (FAILED(hr)) { + continue; + } + + WCHAR file_path[MAX_PATH]; + hr = loader->GetFilePathFromKey(reference_key, reference_key_size, &file_path[0], MAX_PATH); + if (FAILED(hr)) { + continue; + } + return String::utf16((const char16_t *)&file_path[0]); + } + return String(); +} + String OS_Windows::get_executable_path() const { WCHAR bufname[4096]; GetModuleFileNameW(nullptr, bufname, 4096); @@ -951,9 +1081,9 @@ String OS_Windows::get_user_data_dir() const { } String OS_Windows::get_unique_id() const { - HW_PROFILE_INFO HwProfInfo; - ERR_FAIL_COND_V(!GetCurrentHwProfile(&HwProfInfo), ""); - return String::utf16((const char16_t *)(HwProfInfo.szHwProfileGuid), HW_PROFILE_GUIDLEN); + HW_PROFILE_INFOA HwProfInfo; + ERR_FAIL_COND_V(!GetCurrentHwProfileA(&HwProfInfo), ""); + return String((HwProfInfo.szHwProfileGuid), HW_PROFILE_GUIDLEN); } bool OS_Windows::_check_internal_feature_support(const String &p_feature) { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index dc702c66e1..80fc860738 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -62,6 +62,26 @@ #define WINDOWS_DEBUG_OUTPUT_ENABLED #endif +template <class T> +class ComAutoreleaseRef { +public: + T *reference = nullptr; + + _FORCE_INLINE_ T *operator->() { return reference; } + _FORCE_INLINE_ const T *operator->() const { return reference; } + _FORCE_INLINE_ T *operator*() { return reference; } + _FORCE_INLINE_ const T *operator*() const { return reference; } + _FORCE_INLINE_ bool is_valid() const { return reference != nullptr; } + _FORCE_INLINE_ bool is_null() const { return reference == nullptr; } + ComAutoreleaseRef() {} + ~ComAutoreleaseRef() { + if (reference != nullptr) { + reference->Release(); + reference = nullptr; + } + } +}; + class JoypadWindows; class OS_Windows : public OS { #ifdef STDOUT_FILE @@ -147,6 +167,9 @@ public: virtual String get_environment(const String &p_var) const override; virtual bool set_environment(const String &p_var, const String &p_value) const override; + virtual Vector<String> get_system_fonts() const override; + virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override; + virtual String get_executable_path() const override; virtual String get_locale() const override; @@ -185,4 +208,4 @@ public: ~OS_Windows(); }; -#endif +#endif // OS_WINDOWS_H diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h index e68f0125ca..d5950a129a 100644 --- a/platform/windows/vulkan_context_win.h +++ b/platform/windows/vulkan_context_win.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VULKAN_DEVICE_WIN_H -#define VULKAN_DEVICE_WIN_H +#ifndef VULKAN_CONTEXT_WIN_H +#define VULKAN_CONTEXT_WIN_H #include "drivers/vulkan/vulkan_context.h" @@ -46,4 +46,4 @@ public: ~VulkanContextWindows(); }; -#endif // VULKAN_DEVICE_WIN_H +#endif // VULKAN_CONTEXT_WIN_H diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h index 1045f12201..348a49c845 100644 --- a/platform/windows/windows_terminal_logger.h +++ b/platform/windows/windows_terminal_logger.h @@ -44,4 +44,4 @@ public: #endif -#endif +#endif // WINDOWS_TERMINAL_LOGGER_H diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h index 3a41f810dc..ec38795a1a 100644 --- a/scene/2d/animated_sprite_2d.h +++ b/scene/2d/animated_sprite_2d.h @@ -114,4 +114,4 @@ public: AnimatedSprite2D(); }; -#endif // ANIMATED_SPRITE_H +#endif // ANIMATED_SPRITE_2D_H diff --git a/scene/2d/audio_listener_2d.h b/scene/2d/audio_listener_2d.h index 172d388efc..5cd1bfb251 100644 --- a/scene/2d/audio_listener_2d.h +++ b/scene/2d/audio_listener_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LISTENER_2D_H -#define LISTENER_2D_H +#ifndef AUDIO_LISTENER_2D_H +#define AUDIO_LISTENER_2D_H #include "scene/2d/node_2d.h" #include "scene/main/window.h" @@ -56,4 +56,4 @@ public: bool is_current() const; }; -#endif +#endif // AUDIO_LISTENER_2D_H diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index eaab58c4ae..94d22111ea 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -69,7 +69,7 @@ void AudioStreamPlayer2D::_notification(int p_what) { if (setplay.get() >= 0 && stream.is_valid()) { active.set(); - Ref<AudioStreamPlayback> new_playback = stream->instance_playback(); + Ref<AudioStreamPlayback> new_playback = stream->instantiate_playback(); ERR_FAIL_COND_MSG(new_playback.is_null(), "Failed to instantiate playback."); AudioServer::get_singleton()->start_playback_stream(new_playback, _get_actual_bus(), volume_vector, setplay.get(), pitch_scale); stream_playbacks.push_back(new_playback); diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index a22782fe44..d1c4dc4fdf 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -135,4 +135,4 @@ public: ~AudioStreamPlayer2D(); }; -#endif +#endif // AUDIO_STREAM_PLAYER_2D_H diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index 4e7cac1f3e..1f2d5810b0 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BACKBUFFERCOPY_H -#define BACKBUFFERCOPY_H +#ifndef BACK_BUFFER_COPY_H +#define BACK_BUFFER_COPY_H #include "scene/2d/node_2d.h" @@ -71,4 +71,4 @@ public: VARIANT_ENUM_CAST(BackBufferCopy::CopyMode); -#endif // BACKBUFFERCOPY_H +#endif // BACK_BUFFER_COPY_H diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 76b354805c..c43a796170 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -247,8 +247,8 @@ void Camera2D::_notification(int p_what) { add_to_group(canvas_group_name); _update_process_callback(); - _update_scroll(); first = true; + _update_scroll(); } break; case NOTIFICATION_EXIT_TREE: { @@ -439,7 +439,9 @@ void Camera2D::clear_current() { void Camera2D::set_limit(Side p_side, int p_limit) { ERR_FAIL_INDEX((int)p_side, 4); limit[p_side] = p_limit; + Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); + smoothed_camera_pos = old_smoothed_camera_pos; } int Camera2D::get_limit(Side p_side) const { diff --git a/scene/2d/canvas_group.h b/scene/2d/canvas_group.h index 9bc1772ee2..557e7e23dc 100644 --- a/scene/2d/canvas_group.h +++ b/scene/2d/canvas_group.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CANVASGROUP_H -#define CANVASGROUP_H +#ifndef CANVAS_GROUP_H +#define CANVAS_GROUP_H #include "scene/2d/node_2d.h" @@ -56,4 +56,4 @@ public: ~CanvasGroup(); }; -#endif // CANVASGROUP_H +#endif // CANVAS_GROUP_H diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h index ec37449f8f..1fd54898f8 100644 --- a/scene/2d/canvas_modulate.h +++ b/scene/2d/canvas_modulate.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CANVASMODULATE_H -#define CANVASMODULATE_H +#ifndef CANVAS_MODULATE_H +#define CANVAS_MODULATE_H #include "scene/2d/node_2d.h" @@ -52,4 +52,4 @@ public: ~CanvasModulate(); }; -#endif // CANVASMODULATE_H +#endif // CANVAS_MODULATE_H diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index 3c7f4cd9b5..a4231cc45d 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PARTICLES_2D_H -#define PARTICLES_2D_H +#ifndef GPU_PARTICLES_2D_H +#define GPU_PARTICLES_2D_H #include "scene/2d/node_2d.h" @@ -167,4 +167,4 @@ public: VARIANT_ENUM_CAST(GPUParticles2D::DrawOrder) VARIANT_ENUM_CAST(GPUParticles2D::EmitFlags) -#endif // PARTICLES_2D_H +#endif // GPU_PARTICLES_2D_H diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h index 4acfeaf781..b61e23464a 100644 --- a/scene/2d/light_occluder_2d.h +++ b/scene/2d/light_occluder_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LIGHTOCCLUDER2D_H -#define LIGHTOCCLUDER2D_H +#ifndef LIGHT_OCCLUDER_2D_H +#define LIGHT_OCCLUDER_2D_H #include "scene/2d/node_2d.h" @@ -111,4 +111,4 @@ public: ~LightOccluder2D(); }; -#endif // LIGHTOCCLUDER2D_H +#endif // LIGHT_OCCLUDER_2D_H diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 5322c5a5fe..27c510171a 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LINE2D_H -#define LINE2D_H +#ifndef LINE_2D_H +#define LINE_2D_H #include "node_2d.h" @@ -138,4 +138,4 @@ private: bool _antialiased = false; }; -#endif // LINE2D_H +#endif // LINE_2D_H diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 032a15cad2..76eba20058 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -163,4 +163,4 @@ private: void _check_distance_to_target(); }; -#endif +#endif // NAVIGATION_AGENT_2D_H diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index 948cf5b61a..afda05956a 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -74,4 +74,4 @@ private: real_t estimate_agent_radius() const; }; -#endif +#endif // NAVIGATION_OBSTACLE_2D_H diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index 473c34768f..0d8a31e6bb 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NODE2D_H -#define NODE2D_H +#ifndef NODE_2D_H +#define NODE_2D_H #include "scene/main/canvas_item.h" @@ -124,4 +124,4 @@ public: Node2D() {} }; -#endif // NODE2D_H +#endif // NODE_2D_H diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 8953813452..68e5ffdcf9 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -240,7 +240,7 @@ void RayCast2D::_draw_debug_shape() { Transform2D xf; xf.rotate(target_position.angle()); - xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); + xf.translate_local(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); Vector<Vector2> pts = { xf.xform(Vector2(arrow_size, 0)), diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp index ae810156a2..7589af0924 100644 --- a/scene/2d/shape_cast_2d.cpp +++ b/scene/2d/shape_cast_2d.cpp @@ -237,7 +237,7 @@ void ShapeCast2D::_notification(int p_what) { if (target_position != Vector2()) { Transform2D xf; xf.rotate(target_position.angle()); - xf.translate(Vector2(target_position.length(), 0)); + xf.translate_local(Vector2(target_position.length(), 0)); draw_line(Vector2(), target_position, draw_col, 2); diff --git a/scene/2d/shape_cast_2d.h b/scene/2d/shape_cast_2d.h index 7ff080aed0..660e52f189 100644 --- a/scene/2d/shape_cast_2d.h +++ b/scene/2d/shape_cast_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHAPE_CAST_2D -#define SHAPE_CAST_2D +#ifndef SHAPE_CAST_2D_H +#define SHAPE_CAST_2D_H #include "scene/2d/node_2d.h" #include "scene/resources/shape_2d.h" @@ -120,4 +120,4 @@ public: TypedArray<String> get_configuration_warnings() const override; }; -#endif +#endif // SHAPE_CAST_2D_H diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h index 6893e92d4a..5b33bb6802 100644 --- a/scene/2d/sprite_2d.h +++ b/scene/2d/sprite_2d.h @@ -125,4 +125,4 @@ public: ~Sprite2D(); }; -#endif // SPRITE_H +#endif // SPRITE_2D_H diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index cf8b6b8f94..5ba8c95a06 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -2652,7 +2652,7 @@ void TileMap::clear_layer(int p_layer) { // Remove all tiles. _clear_layer_internals(p_layer); layers[p_layer].tile_map.clear(); - + _recreate_layer_internals(p_layer); used_rect_cache_dirty = true; } @@ -2662,6 +2662,7 @@ void TileMap::clear() { for (unsigned int i = 0; i < layers.size(); i++) { layers[i].tile_map.clear(); } + _recreate_internals(); used_rect_cache_dirty = true; } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 0ac94b9d45..012bf01df9 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -130,7 +130,7 @@ public: } String to_string() const { - return vformat("Constraint {pos:%s, bit:%d, terrain:%d, priotity:%d}", base_cell_coords, bit, terrain, priority); + return vformat("Constraint {pos:%s, bit:%d, terrain:%d, priority:%d}", base_cell_coords, bit, terrain, priority); } Vector2i get_base_cell_coords() const { diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 4a4a2a1da0..9dea69cd64 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -131,7 +131,7 @@ void TouchScreenButton::_notification(int p_what) { pos = texture_normal->get_size() * 0.5; } - draw_set_transform_matrix(get_canvas_transform().translated(pos)); + draw_set_transform_matrix(get_canvas_transform().translated_local(pos)); shape->draw(get_canvas_item(), draw_col); } } break; @@ -258,7 +258,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { pos = texture_normal->get_size() * 0.5; } - touched = shape->collide(Transform2D().translated(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); + touched = shape->collide(Transform2D().translated_local(pos), unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); } if (bitmask.is_valid()) { diff --git a/scene/2d/visible_on_screen_notifier_2d.h b/scene/2d/visible_on_screen_notifier_2d.h index 38b508e2f6..ac7fad95a5 100644 --- a/scene/2d/visible_on_screen_notifier_2d.h +++ b/scene/2d/visible_on_screen_notifier_2d.h @@ -102,4 +102,4 @@ public: VARIANT_ENUM_CAST(VisibleOnScreenEnabler2D::EnableMode); -#endif // VISIBILITY_NOTIFIER_2D_H +#endif // VISIBLE_ON_SCREEN_NOTIFIER_2D_H diff --git a/scene/3d/audio_listener_3d.h b/scene/3d/audio_listener_3d.h index ebc37673ed..44c49f526e 100644 --- a/scene/3d/audio_listener_3d.h +++ b/scene/3d/audio_listener_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LISTENER_3D_H -#define LISTENER_3D_H +#ifndef AUDIO_LISTENER_3D_H +#define AUDIO_LISTENER_3D_H #include "scene/3d/node_3d.h" @@ -67,4 +67,4 @@ public: ~AudioListener3D(); }; -#endif +#endif // AUDIO_LISTENER_3D_H diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 824ea0407e..65b00742ee 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -281,7 +281,7 @@ void AudioStreamPlayer3D::_notification(int p_what) { if (setplay.get() >= 0 && stream.is_valid()) { active.set(); - Ref<AudioStreamPlayback> new_playback = stream->instance_playback(); + Ref<AudioStreamPlayback> new_playback = stream->instantiate_playback(); ERR_FAIL_COND_MSG(new_playback.is_null(), "Failed to instantiate playback."); HashMap<StringName, Vector<AudioFrame>> bus_map; bus_map[_get_actual_bus()] = volume_vector; diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index 85ece6d8d5..647b18a4a7 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -196,4 +196,5 @@ public: VARIANT_ENUM_CAST(AudioStreamPlayer3D::AttenuationModel) VARIANT_ENUM_CAST(AudioStreamPlayer3D::DopplerTracking) + #endif // AUDIO_STREAM_PLAYER_3D_H diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h index 137360b141..3224361a25 100644 --- a/scene/3d/bone_attachment_3d.h +++ b/scene/3d/bone_attachment_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BONE_ATTACHMENT_H -#define BONE_ATTACHMENT_H +#ifndef BONE_ATTACHMENT_3D_H +#define BONE_ATTACHMENT_3D_H #include "scene/3d/skeleton_3d.h" #ifdef TOOLS_ENABLED @@ -99,4 +99,4 @@ public: BoneAttachment3D(); }; -#endif // BONE_ATTACHMENT_H +#endif // BONE_ATTACHMENT_3D_H diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 10348b1eb6..da4a14394d 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -31,7 +31,7 @@ #include "camera_3d.h" #include "collision_object_3d.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "scene/main/viewport.h" void Camera3D::_update_audio_listener_state() { @@ -197,7 +197,7 @@ void Camera3D::set_frustum(real_t p_size, Vector2 p_offset, real_t p_z_near, rea update_gizmos(); } -void Camera3D::set_projection(Camera3D::Projection p_mode) { +void Camera3D::set_projection(ProjectionType p_mode) { if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL || p_mode == PROJECTION_FRUSTUM) { mode = p_mode; _update_camera_mode(); @@ -265,7 +265,7 @@ Vector3 Camera3D::project_local_ray_normal(const Point2 &p_pos) const { if (mode == PROJECTION_ORTHOGONAL) { ray = Vector3(0, 0, -1); } else { - CameraMatrix cm; + Projection cm; cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); Vector2 screen_he = cm.get_viewport_half_extents(); ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -near).normalized(); @@ -314,7 +314,7 @@ Vector<Vector3> Camera3D::get_near_plane_points() const { Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm; + Projection cm; if (mode == PROJECTION_ORTHOGONAL) { cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); @@ -340,7 +340,7 @@ Point2 Camera3D::unproject_position(const Vector3 &p_pos) const { Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm; + Projection cm; if (mode == PROJECTION_ORTHOGONAL) { cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); @@ -368,7 +368,7 @@ Vector3 Camera3D::project_position(const Point2 &p_point, real_t p_z_depth) cons } Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm; + Projection cm; if (mode == PROJECTION_ORTHOGONAL) { cm.set_orthogonal(size, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH); @@ -544,7 +544,7 @@ real_t Camera3D::get_far() const { return far; } -Camera3D::Projection Camera3D::get_projection() const { +Camera3D::ProjectionType Camera3D::get_projection() const { return mode; } @@ -607,7 +607,7 @@ Vector<Plane> Camera3D::get_frustum() const { ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>()); Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm; + Projection cm; if (mode == PROJECTION_PERSPECTIVE) { cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); } else { diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index 9f2f8ceed1..cedd976890 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -40,7 +40,7 @@ class Camera3D : public Node3D { GDCLASS(Camera3D, Node3D); public: - enum Projection { + enum ProjectionType { PROJECTION_PERSPECTIVE, PROJECTION_ORTHOGONAL, PROJECTION_FRUSTUM @@ -62,7 +62,7 @@ private: bool current = false; Viewport *viewport = nullptr; - Projection mode = PROJECTION_PERSPECTIVE; + ProjectionType mode = PROJECTION_PERSPECTIVE; real_t fov = 0.0; real_t size = 1.0; @@ -112,7 +112,7 @@ public: void set_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far); void set_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far); void set_frustum(real_t p_size, Vector2 p_offset, real_t p_z_near, real_t p_z_far); - void set_projection(Camera3D::Projection p_mode); + void set_projection(Camera3D::ProjectionType p_mode); void make_current(); void clear_current(bool p_enable_next = true); @@ -127,7 +127,7 @@ public: real_t get_near() const; Vector2 get_frustum_offset() const; - Projection get_projection() const; + ProjectionType get_projection() const; void set_fov(real_t p_fov); void set_size(real_t p_size); @@ -181,8 +181,8 @@ public: ~Camera3D(); }; -VARIANT_ENUM_CAST(Camera3D::Projection); +VARIANT_ENUM_CAST(Camera3D::ProjectionType); VARIANT_ENUM_CAST(Camera3D::KeepAspect); VARIANT_ENUM_CAST(Camera3D::DopplerTracking); -#endif +#endif // CAMERA_3D_H diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index 098f573551..3ec3aa0fc1 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -166,4 +166,4 @@ public: VARIANT_ENUM_CAST(CollisionObject3D::DisableMode); -#endif // COLLISION_OBJECT__H +#endif // COLLISION_OBJECT_3D_H diff --git a/scene/3d/collision_polygon_3d.h b/scene/3d/collision_polygon_3d.h index a24d485af2..74e5867a2f 100644 --- a/scene/3d/collision_polygon_3d.h +++ b/scene/3d/collision_polygon_3d.h @@ -79,4 +79,4 @@ public: CollisionPolygon3D(); }; -#endif // COLLISION_POLYGON_H +#endif // COLLISION_POLYGON_3D_H diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index 5c32230942..124c0d166d 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COLLISION_SHAPE_H -#define COLLISION_SHAPE_H +#ifndef COLLISION_SHAPE_3D_H +#define COLLISION_SHAPE_3D_H #include "scene/3d/node_3d.h" #include "scene/resources/shape_3d.h" @@ -68,4 +68,4 @@ public: ~CollisionShape3D(); }; -#endif // BODY_VOLUME_H +#endif // COLLISION_SHAPE_3D_H diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index 7f225ee98d..4cb693f494 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CPU_PARTICLES_H -#define CPU_PARTICLES_H +#ifndef CPU_PARTICLES_3D_H +#define CPU_PARTICLES_3D_H #include "scene/3d/visual_instance_3d.h" @@ -317,4 +317,4 @@ VARIANT_ENUM_CAST(CPUParticles3D::Parameter) VARIANT_ENUM_CAST(CPUParticles3D::ParticleFlags) VARIANT_ENUM_CAST(CPUParticles3D::EmissionShape) -#endif // CPU_PARTICLES_H +#endif // CPU_PARTICLES_3D_H diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index 01cab493ec..0112f24e0c 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -215,11 +215,13 @@ void Decal::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cull_mask"), &Decal::get_cull_mask); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,suffix:m"), "set_extents", "get_extents"); + ADD_GROUP("Textures", "texture_"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); + ADD_GROUP("Parameters", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate"); @@ -227,13 +229,16 @@ void Decal::_bind_methods() { // A Normal Fade of 1.0 causes the decal to be invisible even if fully perpendicular to a surface. // Due to this, limit Normal Fade to 0.999. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "normal_fade", PROPERTY_HINT_RANGE, "0,0.999,0.001"), "set_normal_fade", "get_normal_fade"); + ADD_GROUP("Vertical Fade", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "upper_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_upper_fade", "get_upper_fade"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lower_fade", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_lower_fade", "get_lower_fade"); + ADD_GROUP("Distance Fade", "distance_fade_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin", PROPERTY_HINT_NONE, "suffix:m"), "set_distance_fade_begin", "get_distance_fade_begin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length", PROPERTY_HINT_NONE, "suffix:m"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_distance_fade_begin", "get_distance_fade_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_GROUP("Cull Mask", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); diff --git a/scene/3d/decal.h b/scene/3d/decal.h index d5990272c6..38da4c14e3 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -57,8 +57,8 @@ private: real_t upper_fade = 0.3; real_t lower_fade = 0.3; bool distance_fade_enabled = false; - real_t distance_fade_begin = 10.0; - real_t distance_fade_length = 1.0; + real_t distance_fade_begin = 40.0; + real_t distance_fade_length = 10.0; protected: static void _bind_methods(); diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index adce45a0a9..0c745dd734 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PARTICLES_H -#define PARTICLES_H +#ifndef GPU_PARTICLES_3D_H +#define GPU_PARTICLES_3D_H #include "scene/3d/visual_instance_3d.h" #include "scene/resources/skin.h" @@ -179,4 +179,4 @@ VARIANT_ENUM_CAST(GPUParticles3D::DrawOrder) VARIANT_ENUM_CAST(GPUParticles3D::TransformAlign) VARIANT_ENUM_CAST(GPUParticles3D::EmitFlags) -#endif // PARTICLES_H +#endif // GPU_PARTICLES_3D_H diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index da0789ccd5..1fcd5160f6 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -30,6 +30,7 @@ #include "gpu_particles_collision_3d.h" +#include "core/object/worker_thread_pool.h" #include "mesh_instance_3d.h" #include "scene/3d/camera_3d.h" #include "scene/main/viewport.h" @@ -339,15 +340,12 @@ void GPUParticlesCollisionSDF3D::_compute_sdf_z(uint32_t p_z, ComputeSDFParams * } void GPUParticlesCollisionSDF3D::_compute_sdf(ComputeSDFParams *params) { - ThreadWorkPool work_pool; - work_pool.init(); - work_pool.begin_work(params->size.z, this, &GPUParticlesCollisionSDF3D::_compute_sdf_z, params); - while (!work_pool.is_done_dispatching()) { + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GPUParticlesCollisionSDF3D::_compute_sdf_z, params, params->size.z); + while (!WorkerThreadPool::get_singleton()->is_group_task_completed(group_task)) { OS::get_singleton()->delay_usec(10000); - bake_step_function(work_pool.get_work_index() * 100 / params->size.z, "Baking SDF"); + bake_step_function(WorkerThreadPool::get_singleton()->get_group_processed_element_count(group_task) * 100 / params->size.z, "Baking SDF"); } - work_pool.end_work(); - work_pool.finish(); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); } Vector3i GPUParticlesCollisionSDF3D::get_estimated_cell_size() const { diff --git a/scene/3d/importer_mesh_instance_3d.h b/scene/3d/importer_mesh_instance_3d.h index 3daf06771d..223b6fc80a 100644 --- a/scene/3d/importer_mesh_instance_3d.h +++ b/scene/3d/importer_mesh_instance_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_IMPORTER_MESH_INSTANCE_3D_H -#define SCENE_IMPORTER_MESH_INSTANCE_3D_H +#ifndef IMPORTER_MESH_INSTANCE_3D_H +#define IMPORTER_MESH_INSTANCE_3D_H #include "scene/3d/node_3d.h" #include "scene/resources/immediate_mesh.h" @@ -61,4 +61,5 @@ public: void set_skeleton_path(const NodePath &p_path); NodePath get_skeleton_path() const; }; -#endif + +#endif // IMPORTER_MESH_INSTANCE_3D_H diff --git a/scene/3d/joint_3d.cpp b/scene/3d/joint_3d.cpp index 0b824ef28b..b0509475a7 100644 --- a/scene/3d/joint_3d.cpp +++ b/scene/3d/joint_3d.cpp @@ -737,7 +737,8 @@ void Generic6DOFJoint3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flag_z", "flag", "value"), &Generic6DOFJoint3D::set_flag_z); ClassDB::bind_method(D_METHOD("get_flag_z", "flag"), &Generic6DOFJoint3D::get_flag_z); - // X + ADD_GROUP("Linear Limit", "linear_limit_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_x", "get_param_x", PARAM_LINEAR_UPPER_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_x", "get_param_x", PARAM_LINEAR_LOWER_LIMIT); @@ -745,15 +746,53 @@ void Generic6DOFJoint3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_RESTITUTION); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_x/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_x", "get_param_x", PARAM_LINEAR_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_UPPER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_LOWER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_DAMPING); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_UPPER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_LOWER_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_LIMIT_SOFTNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_RESTITUTION); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_DAMPING); + + ADD_GROUP("Linear Motor", "linear_motor_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_x/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_MOTOR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_MOTOR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_FORCE_LIMIT); + + ADD_GROUP("Linear Spring", "linear_spring_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_LINEAR_SPRING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_STIFFNESS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/damping"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/damping"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/damping"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); + + ADD_GROUP("Angular Limit", "angular_limit_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_x/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_x", "_get_angular_hi_limit_x"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_x/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_x", "_get_angular_lo_limit_x"); @@ -763,68 +802,15 @@ void Generic6DOFJoint3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_x/erp"), "set_param_x", "get_param_x", PARAM_ANGULAR_ERP); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/damping"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); - - // Y - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_UPPER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_y", "get_param_y", PARAM_LINEAR_LOWER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_LINEAR_DAMPING); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_LINEAR_MOTOR_FORCE_LIMIT); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_LINEAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/damping"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_y/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_y", "_get_angular_hi_limit_y"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_y/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_y", "_get_angular_lo_limit_y"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_LIMIT_SOFTNESS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_RESTITUTION); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_y", "get_param_y", PARAM_ANGULAR_DAMPING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_y/erp"), "set_param_y", "get_param_y", PARAM_ANGULAR_ERP); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/damping"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); - - // Z - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/upper_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_UPPER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/lower_distance", PROPERTY_HINT_NONE, "suffix:m"), "set_param_z", "get_param_z", PARAM_LINEAR_LOWER_LIMIT); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/softness", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_LIMIT_SOFTNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/restitution", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_RESTITUTION); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_limit_z/damping", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_param_z", "get_param_z", PARAM_LINEAR_DAMPING); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_MOTOR); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/target_velocity", PROPERTY_HINT_NONE, "suffix:m/s"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_TARGET_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_LINEAR_MOTOR_FORCE_LIMIT); - - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "linear_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_LINEAR_SPRING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_STIFFNESS); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/damping"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_DAMPING); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_spring_z/equilibrium_point"), "set_param_z", "get_param_z", PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_limit_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_LIMIT); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_z/upper_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_hi_limit_z", "_get_angular_hi_limit_z"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_limit_z/lower_angle", PROPERTY_HINT_RANGE, "-180,180,0.01"), "_set_angular_lo_limit_z", "_get_angular_lo_limit_z"); @@ -834,10 +820,32 @@ void Generic6DOFJoint3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_FORCE_LIMIT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_limit_z/erp"), "set_param_z", "get_param_z", PARAM_ANGULAR_ERP); + ADD_GROUP("Angular Motor", "angular_motor_"); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_MOTOR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/target_velocity"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_x/force_limit"), "set_param_x", "get_param_x", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_MOTOR); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/target_velocity"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_y/force_limit"), "set_param_y", "get_param_y", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_motor_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_MOTOR); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_z/target_velocity"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_TARGET_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_motor_z/force_limit"), "set_param_z", "get_param_z", PARAM_ANGULAR_MOTOR_FORCE_LIMIT); + ADD_GROUP("Angular Spring", "angular_spring_"); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_x/enabled"), "set_flag_x", "get_flag_x", FLAG_ENABLE_ANGULAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/stiffness"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/damping"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_x/equilibrium_point"), "set_param_x", "get_param_x", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); + + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_y/enabled"), "set_flag_y", "get_flag_y", FLAG_ENABLE_ANGULAR_SPRING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/stiffness"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_STIFFNESS); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/damping"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_y/equilibrium_point"), "set_param_y", "get_param_y", PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "angular_spring_z/enabled"), "set_flag_z", "get_flag_z", FLAG_ENABLE_ANGULAR_SPRING); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/stiffness"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_STIFFNESS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_spring_z/damping"), "set_param_z", "get_param_z", PARAM_ANGULAR_SPRING_DAMPING); diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index 6c999d85e2..678c217676 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -291,6 +291,7 @@ void Light3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_specular", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_SPECULAR); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_bake_mode", PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI/LightmapGI),Dynamic (VoxelGI/SDFGI only)"), "set_bake_mode", "get_bake_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); + ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BIAS); @@ -299,12 +300,16 @@ void Light3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_fog_fade", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_param", "get_param", PARAM_SHADOW_VOLUMETRIC_FOG_FADE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BLUR); + + ADD_GROUP("Distance Fade", "distance_fade_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_distance_fade_begin", "get_distance_fade_begin"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_shadow", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_distance_fade_shadow", "get_distance_fade_shadow"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_distance_fade_length", "get_distance_fade_length"); + ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); + ADD_GROUP("", ""); BIND_ENUM_CONSTANT(PARAM_ENERGY); diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h index f7a23c776a..85150b833f 100644 --- a/scene/3d/lightmap_gi.h +++ b/scene/3d/lightmap_gi.h @@ -271,4 +271,4 @@ VARIANT_ENUM_CAST(LightmapGI::GenerateProbes); VARIANT_ENUM_CAST(LightmapGI::BakeError); VARIANT_ENUM_CAST(LightmapGI::EnvironmentMode); -#endif // BAKED_LIGHTMAP_H +#endif // LIGHTMAP_GI_H diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h index dc9c64fa41..48d76b9a88 100644 --- a/scene/3d/mesh_instance_3d.h +++ b/scene/3d/mesh_instance_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef MESH_INSTANCE_H -#define MESH_INSTANCE_H +#ifndef MESH_INSTANCE_3D_H +#define MESH_INSTANCE_3D_H #include "core/templates/local_vector.h" #include "scene/3d/visual_instance_3d.h" @@ -98,4 +98,4 @@ public: ~MeshInstance3D(); }; -#endif +#endif // MESH_INSTANCE_3D_H diff --git a/scene/3d/multimesh_instance_3d.h b/scene/3d/multimesh_instance_3d.h index 111f1e9c09..2fa8dd965f 100644 --- a/scene/3d/multimesh_instance_3d.h +++ b/scene/3d/multimesh_instance_3d.h @@ -53,4 +53,4 @@ public: ~MultiMeshInstance3D(); }; -#endif // MULTIMESH_INSTANCE_H +#endif // MULTIMESH_INSTANCE_3D_H diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index 0a00d769c3..e05f0287f7 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NAVIGATION_AGENT_H -#define NAVIGATION_AGENT_H +#ifndef NAVIGATION_AGENT_3D_H +#define NAVIGATION_AGENT_3D_H #include "scene/main/node.h" @@ -175,4 +175,4 @@ private: void _check_distance_to_target(); }; -#endif +#endif // NAVIGATION_AGENT_3D_H diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index 0ddde64c0e..0316fc37a8 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NAVIGATION_OBSTACLE_H -#define NAVIGATION_OBSTACLE_H +#ifndef NAVIGATION_OBSTACLE_3D_H +#define NAVIGATION_OBSTACLE_3D_H #include "scene/3d/node_3d.h" @@ -73,4 +73,4 @@ private: real_t estimate_agent_radius() const; }; -#endif +#endif // NAVIGATION_OBSTACLE_3D_H diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index aaaf5dd3b8..b15e97de6a 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NAVIGATION_REGION_H -#define NAVIGATION_REGION_H +#ifndef NAVIGATION_REGION_3D_H +#define NAVIGATION_REGION_3D_H #include "scene/3d/node_3d.h" #include "scene/resources/navigation_mesh.h" @@ -85,4 +85,4 @@ public: ~NavigationRegion3D(); }; -#endif // NAVIGATION_REGION_H +#endif // NAVIGATION_REGION_3D_H diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 04b1081516..1de85d57a3 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -733,7 +733,7 @@ void Node3D::rotate_z(real_t p_angle) { void Node3D::translate(const Vector3 &p_offset) { Transform3D t = get_transform(); - t.translate(p_offset); + t.translate_local(p_offset); set_transform(t); } @@ -741,7 +741,7 @@ void Node3D::translate_object_local(const Vector3 &p_offset) { Transform3D t = get_transform(); Transform3D s; - s.translate(p_offset); + s.translate_local(p_offset); set_transform(t * s); } diff --git a/scene/3d/occluder_instance_3d.h b/scene/3d/occluder_instance_3d.h index ed6610074e..11d731b989 100644 --- a/scene/3d/occluder_instance_3d.h +++ b/scene/3d/occluder_instance_3d.h @@ -211,4 +211,4 @@ public: ~OccluderInstance3D(); }; -#endif +#endif // OCCLUDER_INSTANCE_3D_H diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 1f10337b4c..25226ad384 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -296,7 +296,7 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) { } } - t.translate(Vector3(h_offset, v_offset, 0)); + t.translate_local(Vector3(h_offset, v_offset, 0)); } else { t.origin = pos + Vector3(h_offset, v_offset, 0); } diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h index 7c7284534e..b4cc6db7e3 100644 --- a/scene/3d/path_3d.h +++ b/scene/3d/path_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PATH_H -#define PATH_H +#ifndef PATH_3D_H +#define PATH_3D_H #include "scene/3d/node_3d.h" #include "scene/resources/curve.h" @@ -119,4 +119,4 @@ public: VARIANT_ENUM_CAST(PathFollow3D::RotationMode); -#endif // PATH_H +#endif // PATH_3D_H diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 22dcb218bc..e4a41be6c0 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -784,4 +784,4 @@ private: VARIANT_ENUM_CAST(PhysicalBone3D::JointType); VARIANT_ENUM_CAST(PhysicalBone3D::DampMode); -#endif // PHYSICS_BODY__H +#endif // PHYSICS_BODY_3D_H diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h index c69c910efb..aa62f6927e 100644 --- a/scene/3d/ray_cast_3d.h +++ b/scene/3d/ray_cast_3d.h @@ -126,4 +126,4 @@ public: RayCast3D(); }; -#endif // RAY_CAST_H +#endif // RAY_CAST_3D_H diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index 424976d895..a161717ece 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef REFLECTIONPROBE_H -#define REFLECTIONPROBE_H +#ifndef REFLECTION_PROBE_H +#define REFLECTION_PROBE_H #include "scene/3d/visual_instance_3d.h" @@ -121,4 +121,4 @@ public: VARIANT_ENUM_CAST(ReflectionProbe::AmbientMode); VARIANT_ENUM_CAST(ReflectionProbe::UpdateMode); -#endif // REFLECTIONPROBE_H +#endif // REFLECTION_PROBE_H diff --git a/scene/3d/remote_transform_3d.h b/scene/3d/remote_transform_3d.h index 03bb253578..ab134c1261 100644 --- a/scene/3d/remote_transform_3d.h +++ b/scene/3d/remote_transform_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef REMOTETRANSFORM_H -#define REMOTETRANSFORM_H +#ifndef REMOTE_TRANSFORM_3D_H +#define REMOTE_TRANSFORM_3D_H #include "scene/3d/node_3d.h" @@ -75,4 +75,4 @@ public: RemoteTransform3D(); }; -#endif // REMOTETRANSFORM_H +#endif // REMOTE_TRANSFORM_3D_H diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index b342660b85..4c38fccc8b 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -493,6 +493,19 @@ int Skeleton3D::get_bone_axis_forward_enum(int p_bone) { return bones[p_bone].rest_bone_forward_axis; } +void Skeleton3D::set_motion_scale(float p_motion_scale) { + if (p_motion_scale <= 0) { + motion_scale = 1; + ERR_FAIL_MSG("Motion scale must be larger than 0."); + } + motion_scale = p_motion_scale; +} + +float Skeleton3D::get_motion_scale() const { + ERR_FAIL_COND_V(motion_scale <= 0, 1); + return motion_scale; +} + // Skeleton creation api void Skeleton3D::add_bone(const String &p_name) { @@ -1255,6 +1268,9 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("force_update_all_bone_transforms"), &Skeleton3D::force_update_all_bone_transforms); ClassDB::bind_method(D_METHOD("force_update_bone_child_transform", "bone_idx"), &Skeleton3D::force_update_bone_children_transforms); + ClassDB::bind_method(D_METHOD("set_motion_scale", "motion_scale"), &Skeleton3D::set_motion_scale); + ClassDB::bind_method(D_METHOD("get_motion_scale"), &Skeleton3D::get_motion_scale); + // Helper functions ClassDB::bind_method(D_METHOD("global_pose_to_world_transform", "global_pose"), &Skeleton3D::global_pose_to_world_transform); ClassDB::bind_method(D_METHOD("world_transform_to_global_pose", "world_transform"), &Skeleton3D::world_transform_to_global_pose); @@ -1278,15 +1294,13 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_modification_stack"), &Skeleton3D::get_modification_stack); ClassDB::bind_method(D_METHOD("execute_modifications", "delta", "execution_mode"), &Skeleton3D::execute_modifications); -#ifndef _3D_DISABLED + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "motion_scale", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater"), "set_motion_scale", "get_motion_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_rest_only"), "set_show_rest_only", "is_show_rest_only"); +#ifndef _3D_DISABLED ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones"); #endif // _3D_DISABLED -#ifdef TOOLS_ENABLED ADD_SIGNAL(MethodInfo("pose_updated")); -#endif // TOOLS_ENABLED - ADD_SIGNAL(MethodInfo("bone_pose_changed", PropertyInfo(Variant::INT, "bone_idx"))); ADD_SIGNAL(MethodInfo("bone_enabled_changed", PropertyInfo(Variant::INT, "bone_idx"))); ADD_SIGNAL(MethodInfo("show_rest_only_changed")); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index cb4c82d232..8b69410a39 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -146,6 +146,7 @@ private: bool rest_dirty = false; bool show_rest_only = false; + float motion_scale = 1.0; uint64_t version = 1; @@ -211,6 +212,9 @@ public: bool is_show_rest_only() const; void clear_bones(); + void set_motion_scale(float p_motion_scale); + float get_motion_scale() const; + // posing api void set_bone_pose_position(int p_bone, const Vector3 &p_position); @@ -288,4 +292,4 @@ public: ~Skeleton3D(); }; -#endif +#endif // SKELETON_3D_H diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 0f656187de..6ae86a2bf6 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETON_IK_H -#define SKELETON_IK_H +#ifndef SKELETON_IK_3D_H +#define SKELETON_IK_3D_H #ifndef _3D_DISABLED @@ -192,4 +192,4 @@ private: #endif // _3D_DISABLED -#endif // SKELETON_IK_H +#endif // SKELETON_IK_3D_H diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_dynamic_body_3d.h index e11e5c73df..04f3365f72 100644 --- a/scene/3d/soft_dynamic_body_3d.h +++ b/scene/3d/soft_dynamic_body_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SOFT_DYNAMIC_BODY_H -#define SOFT_DYNAMIC_BODY_H +#ifndef SOFT_DYNAMIC_BODY_3D_H +#define SOFT_DYNAMIC_BODY_3D_H #include "scene/3d/mesh_instance_3d.h" #include "servers/physics_server_3d.h" @@ -199,4 +199,4 @@ private: VARIANT_ENUM_CAST(SoftDynamicBody3D::DisableMode); -#endif // SOFT_DYNAMIC_BODY_H +#endif // SOFT_DYNAMIC_BODY_3D_H diff --git a/scene/3d/spring_arm_3d.h b/scene/3d/spring_arm_3d.h index 0b5307acf7..1a6f03abe4 100644 --- a/scene/3d/spring_arm_3d.h +++ b/scene/3d/spring_arm_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPRING_ARM_H -#define SPRING_ARM_H +#ifndef SPRING_ARM_3D_H +#define SPRING_ARM_3D_H #include "scene/3d/node_3d.h" @@ -68,4 +68,4 @@ private: void process_spring(); }; -#endif +#endif // SPRING_ARM_3D_H diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h index 0ef8bd7482..2f3a37af2a 100644 --- a/scene/3d/vehicle_body_3d.h +++ b/scene/3d/vehicle_body_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VEHICLE_BODY_H -#define VEHICLE_BODY_H +#ifndef VEHICLE_BODY_3D_H +#define VEHICLE_BODY_3D_H #include "scene/3d/physics_body_3d.h" @@ -210,4 +210,4 @@ public: VehicleBody3D(); }; -#endif // VEHICLE_BODY_H +#endif // VEHICLE_BODY_3D_H diff --git a/scene/3d/velocity_tracker_3d.h b/scene/3d/velocity_tracker_3d.h index 7fdcacc9c1..6b27cdffc2 100644 --- a/scene/3d/velocity_tracker_3d.h +++ b/scene/3d/velocity_tracker_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPATIAL_VELOCITY_TRACKER_H -#define SPATIAL_VELOCITY_TRACKER_H +#ifndef VELOCITY_TRACKER_3D_H +#define VELOCITY_TRACKER_3D_H #include "scene/3d/node_3d.h" @@ -58,4 +58,4 @@ public: VelocityTracker3D(); }; -#endif // SPATIAL_VELOCITY_TRACKER_H +#endif // VELOCITY_TRACKER_3D_H diff --git a/scene/3d/visible_on_screen_notifier_3d.h b/scene/3d/visible_on_screen_notifier_3d.h index fe17f1e444..60461569f4 100644 --- a/scene/3d/visible_on_screen_notifier_3d.h +++ b/scene/3d/visible_on_screen_notifier_3d.h @@ -96,4 +96,4 @@ public: VARIANT_ENUM_CAST(VisibleOnScreenEnabler3D::EnableMode); -#endif // VISIBILITY_NOTIFIER_H +#endif // VISIBLE_ON_SCREEN_NOTIFIER_3D_H diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 69917f6992..e76e85cfef 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -461,15 +461,16 @@ void GeometryInstance3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01,suffix:m"), "set_extra_cull_margin", "get_extra_cull_margin"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_bias", PROPERTY_HINT_RANGE, "0.001,128,0.001"), "set_lod_bias", "get_lod_bias"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_occlusion_culling"), "set_ignore_occlusion_culling", "is_ignoring_occlusion_culling"); + ADD_GROUP("Global Illumination", "gi_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI/LightmapGI),Dynamic (VoxelGI only)"), "set_gi_mode", "get_gi_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, String::utf8("1×,2×,4×,8×")), "set_lightmap_scale", "get_lightmap_scale"); ADD_GROUP("Visibility Range", "visibility_range_"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_begin", "get_visibility_range_begin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_begin_margin", "get_visibility_range_begin_margin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_end", "get_visibility_range_end"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,suffix:m"), "set_visibility_range_end_margin", "get_visibility_range_end_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_begin", "get_visibility_range_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_begin_margin", "get_visibility_range_begin_margin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_end", "get_visibility_range_end"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_end_margin", "get_visibility_range_end_margin"); ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_range_fade_mode", PROPERTY_HINT_ENUM, "Disabled,Self,Dependencies"), "set_visibility_range_fade_mode", "get_visibility_range_fade_mode"); BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_OFF); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 9e0d9b9a2a..159b14613c 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VISUAL_INSTANCE_H -#define VISUAL_INSTANCE_H +#ifndef VISUAL_INSTANCE_3D_H +#define VISUAL_INSTANCE_3D_H #include "scene/3d/node_3d.h" @@ -196,4 +196,4 @@ VARIANT_ENUM_CAST(GeometryInstance3D::LightmapScale); VARIANT_ENUM_CAST(GeometryInstance3D::GIMode); VARIANT_ENUM_CAST(GeometryInstance3D::VisibilityRangeFadeMode); -#endif +#endif // VISUAL_INSTANCE_3D_H diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h index 0179795ddc..68bce768b7 100644 --- a/scene/3d/voxelizer.h +++ b/scene/3d/voxelizer.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VOXEL_LIGHT_BAKER_H -#define VOXEL_LIGHT_BAKER_H +#ifndef VOXELIZER_H +#define VOXELIZER_H #include "scene/resources/multimesh.h" @@ -129,4 +129,4 @@ public: Voxelizer(); }; -#endif // VOXEL_LIGHT_BAKER_H +#endif // VOXELIZER_H diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h index 8dbb57364c..9955aa72a8 100644 --- a/scene/3d/world_environment.h +++ b/scene/3d/world_environment.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENARIO_FX_H -#define SCENARIO_FX_H +#ifndef WORLD_ENVIRONMENT_H +#define WORLD_ENVIRONMENT_H #include "scene/main/node.h" #include "scene/resources/camera_effects.h" @@ -60,4 +60,4 @@ public: WorldEnvironment(); }; -#endif +#endif // WORLD_ENVIRONMENT_H diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 1dad6078b4..40a43043c6 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -120,7 +120,7 @@ Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const { Vector3 ray; // Just use the first view, if multiple views are supported this function has no good result - CameraMatrix cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); + Projection cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); Vector2 screen_he = cm.get_viewport_half_extents(); ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_near()).normalized(); @@ -143,7 +143,7 @@ Point2 XRCamera3D::unproject_position(const Vector3 &p_pos) const { Size2 viewport_size = get_viewport()->get_visible_rect().size; // Just use the first view, if multiple views are supported this function has no good result - CameraMatrix cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); + Projection cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); Plane p(get_camera_transform().xform_inv(p_pos), 1.0); @@ -173,7 +173,7 @@ Vector3 XRCamera3D::project_position(const Point2 &p_point, real_t p_z_depth) co Size2 viewport_size = get_viewport()->get_visible_rect().size; // Just use the first view, if multiple views are supported this function has no good result - CameraMatrix cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); + Projection cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); Vector2 vp_he = cm.get_viewport_half_extents(); @@ -202,7 +202,7 @@ Vector<Plane> XRCamera3D::get_frustum() const { Size2 viewport_size = get_viewport()->get_visible_rect().size; // TODO Just use the first view for now, this is mostly for debugging so we may look into using our combined projection here. - CameraMatrix cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); + Projection cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); return cm.get_projection_planes(get_camera_transform()); }; diff --git a/scene/SCsub b/scene/SCsub index a7b23af598..92288211bb 100644 --- a/scene/SCsub +++ b/scene/SCsub @@ -9,7 +9,6 @@ env.add_source_files(env.scene_sources, "*.cpp") # Chain load SCsubs SConscript("main/SCsub") -SConscript("multiplayer/SCsub") SConscript("gui/SCsub") if not env["disable_3d"]: SConscript("3d/SCsub") diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index fe08e849a1..fbe23bedad 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -630,7 +630,7 @@ bool AnimationNodeStateMachinePlayback::_check_advance_condition(const Ref<Anima Node *expression_base = tree_base->get_node_or_null(advance_expression_base_node_path); if (expression_base) { Ref<Expression> exp = transition->expression; - bool ret = exp->execute(Array(), tree_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls. + bool ret = exp->execute(Array(), expression_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls. if (!exp->has_execute_failed()) { if (ret) { return true; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 2e87dbf9da..76bf71387e 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -64,7 +64,7 @@ void AnimatedValuesBackup::restore() const { if (arr.size() == 3) { Object::cast_to<Skeleton3D>(entry->object)->set_bone_pose_position(entry->bone_idx, arr[0]); Object::cast_to<Skeleton3D>(entry->object)->set_bone_pose_rotation(entry->bone_idx, arr[1]); - Object::cast_to<Skeleton3D>(entry->object)->set_bone_pose_scale(entry->bone_idx, arr[0]); + Object::cast_to<Skeleton3D>(entry->object)->set_bone_pose_scale(entry->bone_idx, arr[2]); } } } @@ -370,6 +370,10 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov node_cache->node_3d = nullptr; ERR_CONTINUE(node_cache->bone_idx < 0); } + Transform3D rest = node_cache->skeleton->get_bone_rest(bone_idx); + node_cache->init_loc = rest.origin; + node_cache->init_rot = rest.basis.get_rotation_quaternion(); + node_cache->init_scale = rest.basis.get_scale(); } else { // no property, just use spatialnode node_cache->skeleton = nullptr; @@ -450,6 +454,23 @@ static void _call_object(Object *p_object, const StringName &p_method, const Vec } } +Variant AnimationPlayer::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { + switch (p_anim->track_get_type(p_track)) { +#ifndef _3D_DISABLED + case Animation::TYPE_POSITION_3D: { + if (p_object_idx >= 0) { + const Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_object); + return Vector3(p_value) * skel->get_motion_scale(); + } + return p_value; + } break; +#endif // _3D_DISABLED + default: { + } break; + } + return p_value; +} + void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started, int p_pingponged) { _ensure_node_caches(p_anim); ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count()); @@ -494,14 +515,15 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + loc = _post_process_key_value(a, i, loc, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); cache_update[cache_update_size++] = nc; nc->accum_pass = accum_pass; nc->loc_accum = loc; - nc->rot_accum = Quaternion(); - nc->scale_accum = Vector3(); + nc->rot_accum = nc->init_rot; + nc->scale_accum = nc->init_scale; } else { nc->loc_accum = nc->loc_accum.lerp(loc, p_interp); } @@ -521,14 +543,15 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + rot = _post_process_key_value(a, i, rot, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); cache_update[cache_update_size++] = nc; nc->accum_pass = accum_pass; - nc->loc_accum = Vector3(); + nc->loc_accum = nc->init_loc; nc->rot_accum = rot; - nc->scale_accum = Vector3(); + nc->scale_accum = nc->init_scale; } else { nc->rot_accum = nc->rot_accum.slerp(rot, p_interp); } @@ -548,13 +571,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + scale = _post_process_key_value(a, i, scale, nc->node_3d, nc->bone_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); cache_update[cache_update_size++] = nc; nc->accum_pass = accum_pass; - nc->loc_accum = Vector3(); - nc->rot_accum = Quaternion(); + nc->loc_accum = nc->init_loc; + nc->rot_accum = nc->init_rot; nc->scale_accum = scale; } else { nc->scale_accum = nc->scale_accum.lerp(scale, p_interp); @@ -575,6 +599,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (err != OK) { continue; } + blend = _post_process_key_value(a, i, blend, nc->node_blend_shape, nc->blend_shape_idx); if (nc->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX); @@ -627,9 +652,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (p_time < first_key_time) { double c = Math::ease(p_time / first_key_time, transition); Variant first_value = a->track_get_key_value(i, first_key); + first_value = _post_process_key_value(a, i, first_value, nc->node); Variant interp_value; Variant::interpolate(pa->capture, first_value, c, interp_value); - if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); cache_update_prop[cache_update_prop_size++] = pa; @@ -649,6 +674,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (value == Variant()) { continue; } + value = _post_process_key_value(a, i, value, nc->node); if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); @@ -665,6 +691,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double for (int &F : indices) { Variant value = a->track_get_key_value(i, F); + value = _post_process_key_value(a, i, value, nc->node); switch (pa->special) { case SP_NONE: { bool valid; @@ -749,6 +776,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double TrackNodeCache::BezierAnim *ba = &E->value; real_t bezier = a->bezier_track_interpolate(i, p_time); + bezier = _post_process_key_value(a, i, bezier, nc->node); if (ba->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_bezier_size >= NODE_CACHE_UPDATE_MAX); cache_update_bezier[cache_update_bezier_size++] = ba; @@ -1173,11 +1201,15 @@ void AnimationPlayer::_animation_process(double p_delta) { emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name); } } else { - //stop(); playing = false; _set_process(false); if (end_notify) { emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned); + + if (movie_quit_on_finish && OS::get_singleton()->has_feature("movie")) { + print_line(vformat("Movie Maker mode is enabled. Quitting on animation finish as requested by: %s", get_path())); + get_tree()->quit(); + } } } end_reached = false; @@ -1864,6 +1896,14 @@ AnimationPlayer::AnimationMethodCallMode AnimationPlayer::get_method_call_mode() return method_call_mode; } +void AnimationPlayer::set_movie_quit_on_finish_enabled(bool p_enabled) { + movie_quit_on_finish = p_enabled; +} + +bool AnimationPlayer::is_movie_quit_on_finish_enabled() const { + return movie_quit_on_finish; +} + void AnimationPlayer::_set_process(bool p_process, bool p_force) { if (processing == p_process && !p_force) { return; @@ -2084,6 +2124,9 @@ void AnimationPlayer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_method_call_mode", "mode"), &AnimationPlayer::set_method_call_mode); ClassDB::bind_method(D_METHOD("get_method_call_mode"), &AnimationPlayer::get_method_call_mode); + ClassDB::bind_method(D_METHOD("set_movie_quit_on_finish_enabled"), &AnimationPlayer::set_movie_quit_on_finish_enabled); + ClassDB::bind_method(D_METHOD("is_movie_quit_on_finish_enabled"), &AnimationPlayer::is_movie_quit_on_finish_enabled); + ClassDB::bind_method(D_METHOD("get_current_animation_position"), &AnimationPlayer::get_current_animation_position); ClassDB::bind_method(D_METHOD("get_current_animation_length"), &AnimationPlayer::get_current_animation_length); @@ -2105,6 +2148,8 @@ void AnimationPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed", PROPERTY_HINT_RANGE, "-64,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "method_call_mode", PROPERTY_HINT_ENUM, "Deferred,Immediate"), "set_method_call_mode", "get_method_call_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "movie_quit_on_finish"), "set_movie_quit_on_finish_enabled", "is_movie_quit_on_finish_enabled"); + ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING_NAME, "anim_name"))); ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING_NAME, "old_name"), PropertyInfo(Variant::STRING_NAME, "new_name"))); ADD_SIGNAL(MethodInfo("animation_started", PropertyInfo(Variant::STRING_NAME, "anim_name"))); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index d3eb37a345..b6d8dab1ed 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -109,6 +109,9 @@ private: bool loc_used = false; bool rot_used = false; bool scale_used = false; + Vector3 init_loc = Vector3(0, 0, 0); + Quaternion init_rot = Quaternion(0, 0, 0, 1); + Vector3 init_scale = Vector3(1, 1, 1); Vector3 loc_accum; Quaternion rot_accum; @@ -259,6 +262,7 @@ private: bool reset_on_save = true; AnimationProcessCallback process_callback = ANIMATION_PROCESS_IDLE; AnimationMethodCallMode method_call_mode = ANIMATION_METHOD_CALL_DEFERRED; + bool movie_quit_on_finish = false; bool processing = false; bool active = true; @@ -313,6 +317,8 @@ protected: static void _bind_methods(); + virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); + public: StringName find_animation(const Ref<Animation> &p_animation) const; StringName find_animation_library(const Ref<Animation> &p_animation) const; @@ -368,6 +374,9 @@ public: void set_method_call_mode(AnimationMethodCallMode p_mode); AnimationMethodCallMode get_method_call_mode() const; + void set_movie_quit_on_finish_enabled(bool p_enabled); + bool is_movie_quit_on_finish_enabled() const; + void seek(double p_time, bool p_update = false); void seek_delta(double p_time, float p_delta); float get_current_animation_position() const; @@ -395,4 +404,4 @@ public: VARIANT_ENUM_CAST(AnimationPlayer::AnimationProcessCallback); VARIANT_ENUM_CAST(AnimationPlayer::AnimationMethodCallMode); -#endif +#endif // ANIMATION_PLAYER_H diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 4b80f571ae..b73fd6a24f 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -1054,7 +1054,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, (double)a->get_length(), &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = 0; } @@ -1064,7 +1066,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, 0, &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = (double)a->get_length(); } @@ -1074,8 +1078,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc[0] = _post_process_key_value(a, i, loc[0], t->object, t->bone_idx); a->position_track_interpolate(i, time, &loc[1]); + loc[1] = _post_process_key_value(a, i, loc[1], t->object, t->bone_idx); t->loc += (loc[1] - loc[0]) * blend; prev_time = !backward ? 0 : (double)a->get_length(); @@ -1092,6 +1098,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + loc = _post_process_key_value(a, i, loc, t->object, t->bone_idx); t->loc += (loc - t->init_loc) * blend; } @@ -1150,7 +1157,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, (double)a->get_length(), &rot[1]); + rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = 0; } @@ -1160,6 +1169,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, 0, &rot[1]); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = (double)a->get_length(); @@ -1170,8 +1180,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot[0] = _post_process_key_value(a, i, rot[0], t->object, t->bone_idx); a->rotation_track_interpolate(i, time, &rot[1]); + rot[1] = _post_process_key_value(a, i, rot[1], t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(rot[0].inverse() * rot[1], blend)).normalized(); prev_time = !backward ? 0 : (double)a->get_length(); @@ -1188,6 +1200,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + rot = _post_process_key_value(a, i, rot, t->object, t->bone_idx); t->rot = (t->rot * Quaternion().slerp(t->init_rot.inverse() * rot, blend)).normalized(); } @@ -1246,8 +1259,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, (double)a->get_length(), &scale[1]); t->scale += (scale[1] - scale[0]) * blend; + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); prev_time = 0; } } else { @@ -1256,7 +1271,9 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, 0, &scale[1]); + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); t->scale += (scale[1] - scale[0]) * blend; prev_time = (double)a->get_length(); } @@ -1266,8 +1283,10 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale[0] = _post_process_key_value(a, i, scale[0], t->object, t->bone_idx); a->scale_track_interpolate(i, time, &scale[1]); + scale[1] = _post_process_key_value(a, i, scale[1], t->object, t->bone_idx); t->scale += (scale[1] - scale[0]) * blend; prev_time = !backward ? 0 : (double)a->get_length(); @@ -1284,6 +1303,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + scale = _post_process_key_value(a, i, scale, t->object, t->bone_idx); t->scale += (scale - t->init_scale) * blend; } @@ -1306,6 +1326,7 @@ void AnimationTree::_process_graph(double p_delta) { if (err != OK) { continue; } + value = _post_process_key_value(a, i, value, t->object, t->shape_index); t->value += (value - t->init_value) * blend; #endif // _3D_DISABLED @@ -1317,6 +1338,7 @@ void AnimationTree::_process_graph(double p_delta) { if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE) { Variant value = a->value_track_interpolate(i, time); + value = _post_process_key_value(a, i, value, t->object); if (value == Variant()) { continue; @@ -1344,12 +1366,14 @@ void AnimationTree::_process_graph(double p_delta) { continue; } Variant value = a->track_get_key_value(i, idx); + value = _post_process_key_value(a, i, value, t->object); t->object->set_indexed(t->subpath, value); } else { List<int> indices; a->value_track_get_key_indices(i, time, delta, &indices, pingponged); for (int &F : indices) { Variant value = a->track_get_key_value(i, F); + value = _post_process_key_value(a, i, value, t->object); t->object->set_indexed(t->subpath, value); } } @@ -1388,6 +1412,7 @@ void AnimationTree::_process_graph(double p_delta) { TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track); real_t bezier = a->bezier_track_interpolate(i, time); + bezier = _post_process_key_value(a, i, bezier, t->object); if (t->process_pass != process_pass) { t->process_pass = process_pass; @@ -1663,6 +1688,23 @@ void AnimationTree::_process_graph(double p_delta) { } } +Variant AnimationTree::_post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx) { + switch (p_anim->track_get_type(p_track)) { +#ifndef _3D_DISABLED + case Animation::TYPE_POSITION_3D: { + if (p_object_idx >= 0) { + const Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_object); + return Vector3(p_value) * skel->get_motion_scale(); + } + return p_value; + } break; +#endif // _3D_DISABLED + default: { + } break; + } + return p_value; +} + void AnimationTree::advance(real_t p_time) { _process_graph(p_time); } diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index 4f9a330a89..99851d140e 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ANIMATION_GRAPH_PLAYER_H -#define ANIMATION_GRAPH_PLAYER_H +#ifndef ANIMATION_TREE_H +#define ANIMATION_TREE_H #include "animation_player.h" #include "scene/3d/node_3d.h" @@ -321,6 +321,8 @@ protected: void _notification(int p_what); static void _bind_methods(); + virtual Variant _post_process_key_value(const Ref<Animation> &p_anim, int p_track, Variant p_value, const Object *p_object, int p_object_idx = -1); + public: void set_tree_root(const Ref<AnimationNode> &p_root); Ref<AnimationNode> get_tree_root() const; @@ -359,4 +361,4 @@ public: VARIANT_ENUM_CAST(AnimationTree::AnimationProcessCallback) -#endif // ANIMATION_GRAPH_PLAYER_H +#endif // ANIMATION_TREE_H diff --git a/scene/animation/easing_equations.h b/scene/animation/easing_equations.h index 6d246c7a93..094829e406 100644 --- a/scene/animation/easing_equations.h +++ b/scene/animation/easing_equations.h @@ -402,4 +402,4 @@ static real_t out_in(real_t t, real_t b, real_t c, real_t d) { } }; // namespace back -#endif +#endif // EASING_EQUATIONS_H diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 5457da472f..72f7589224 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -464,6 +464,17 @@ Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, f APPLY_EQUATION(columns[2][1]); return r; } + case Variant::VECTOR4: { + Vector4 i = p_initial_val; + Vector4 d = p_delta_val; + Vector4 r; + + APPLY_EQUATION(x); + APPLY_EQUATION(y); + APPLY_EQUATION(z); + APPLY_EQUATION(w); + return r; + } case Variant::QUATERNION: { Quaternion i = p_initial_val; diff --git a/scene/animation/tween.h b/scene/animation/tween.h index 40268405cf..b57ec2e5e7 100644 --- a/scene/animation/tween.h +++ b/scene/animation/tween.h @@ -283,4 +283,4 @@ private: Callable callback; }; -#endif +#endif // TWEEN_H diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index efb647af29..04debcab05 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -136,7 +136,7 @@ void AudioStreamPlayer::play(float p_from_pos) { if (stream->is_monophonic() && is_playing()) { stop(); } - Ref<AudioStreamPlayback> stream_playback = stream->instance_playback(); + Ref<AudioStreamPlayback> stream_playback = stream->instantiate_playback(); ERR_FAIL_COND_MSG(stream_playback.is_null(), "Failed to instantiate playback."); AudioServer::get_singleton()->start_playback_stream(stream_playback, bus, _get_volume_vector(), p_from_pos, pitch_scale); diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h index 4ed126d36e..911363f45d 100644 --- a/scene/debugger/scene_debugger.h +++ b/scene/debugger/scene_debugger.h @@ -174,4 +174,4 @@ public: }; #endif -#endif +#endif // SCENE_DEBUGGER_H diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index ba3852ec98..7cf8de6432 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -155,4 +155,4 @@ public: ButtonGroup(); }; -#endif +#endif // BASE_BUTTON_H diff --git a/scene/gui/button.h b/scene/gui/button.h index 7a29cba677..9d8d457f7c 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -98,4 +98,4 @@ public: ~Button(); }; -#endif +#endif // BUTTON_H diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 22f968eac7..8968c1cc17 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -407,7 +407,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) { } /* Ctrl + Hover symbols */ -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED if (k->get_keycode() == Key::META) { #else if (k->get_keycode() == Key::CTRL) { diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h index a431d8a5b2..08bd91a368 100644 --- a/scene/gui/code_edit.h +++ b/scene/gui/code_edit.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CODEEDIT_H -#define CODEEDIT_H +#ifndef CODE_EDIT_H +#define CODE_EDIT_H #include "scene/gui/text_edit.h" @@ -433,4 +433,4 @@ public: VARIANT_ENUM_CAST(CodeEdit::CodeCompletionKind); -#endif // CODEEDIT_H +#endif // CODE_EDIT_H diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index bfe5ee335b..d9f603f136 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -998,10 +998,10 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) { h = y / w_edit->get_size().height; } - if (current_mode == MODE_HSV) { - color.set_hsv(h, s, v, color.a); - } else if (current_mode == MODE_OKHSL) { + if (actual_shape == SHAPE_OKHSL_CIRCLE) { color.set_ok_hsl(h, s, v, color.a); + } else { + color.set_hsv(h, s, v, color.a); } last_color = color; diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index e219c78319..8e65ee1861 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -276,4 +276,5 @@ public: VARIANT_ENUM_CAST(ColorPicker::PickerShapeType); VARIANT_ENUM_CAST(ColorPicker::ColorModeType); + #endif // COLOR_PICKER_H diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 20fcdf1136..242684b2a8 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -50,6 +50,9 @@ #include "editor/plugins/control_editor_plugin.h" #endif +// Editor plugin interoperability. + +// TODO: Decouple controls from their editor plugin and get rid of this. #ifdef TOOLS_ENABLED Dictionary Control::_edit_get_state() const { Dictionary s; @@ -181,6 +184,49 @@ Size2 Control::_edit_get_minimum_size() const { } #endif +// Editor integration. + +void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { + Node::get_argument_options(p_function, p_idx, r_options); + + if (p_idx == 0) { + List<StringName> sn; + String pf = p_function; + if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") { + Theme::get_default()->get_color_list(get_class(), &sn); + } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") { + Theme::get_default()->get_stylebox_list(get_class(), &sn); + } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") { + Theme::get_default()->get_font_list(get_class(), &sn); + } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") { + Theme::get_default()->get_font_size_list(get_class(), &sn); + } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") { + Theme::get_default()->get_constant_list(get_class(), &sn); + } + + sn.sort_custom<StringName::AlphCompare>(); + for (const StringName &name : sn) { + r_options->push_back(String(name).quote()); + } + } +} + +TypedArray<String> Control::get_configuration_warnings() const { + TypedArray<String> warnings = Node::get_configuration_warnings(); + + if (data.mouse_filter == MOUSE_FILTER_IGNORE && !data.tooltip.is_empty()) { + warnings.push_back(RTR("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\".")); + } + + return warnings; +} + +bool Control::is_text_field() const { + return false; +} + +// Dynamic properties. + String Control::properties_managed_by_container[] = { "offset_left", "offset_top", @@ -196,58 +242,6 @@ String Control::properties_managed_by_container[] = { "size" }; -void Control::accept_event() { - if (is_inside_tree()) { - get_viewport()->_gui_accept_event(); - } -} - -void Control::set_custom_minimum_size(const Size2 &p_custom) { - if (p_custom == data.custom_minimum_size) { - return; - } - data.custom_minimum_size = p_custom; - update_minimum_size(); -} - -Size2 Control::get_custom_minimum_size() const { - return data.custom_minimum_size; -} - -void Control::_update_minimum_size_cache() { - Size2 minsize = get_minimum_size(); - minsize.x = MAX(minsize.x, data.custom_minimum_size.x); - minsize.y = MAX(minsize.y, data.custom_minimum_size.y); - - bool size_changed = false; - if (data.minimum_size_cache != minsize) { - size_changed = true; - } - - data.minimum_size_cache = minsize; - data.minimum_size_valid = true; - - if (size_changed) { - update_minimum_size(); - } -} - -Size2 Control::get_combined_minimum_size() const { - if (!data.minimum_size_valid) { - const_cast<Control *>(this)->_update_minimum_size_cache(); - } - return data.minimum_size_cache; -} - -Transform2D Control::_get_internal_transform() const { - Transform2D rot_scale; - rot_scale.set_rotation_and_scale(data.rotation, data.scale); - Transform2D offset; - offset.set_origin(-data.pivot_offset); - - return offset.affine_inverse() * (rot_scale * offset); -} - bool Control::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (!name.begins_with("theme_override")) { @@ -258,21 +252,21 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { if (name.begins_with("theme_override_icons/")) { String dname = name.get_slicec('/', 1); if (data.icon_override.has(dname)) { - data.icon_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); + data.icon_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } data.icon_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("theme_override_styles/")) { String dname = name.get_slicec('/', 1); if (data.style_override.has(dname)) { - data.style_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); + data.style_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } data.style_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); } else if (name.begins_with("theme_override_fonts/")) { String dname = name.get_slicec('/', 1); if (data.font_override.has(dname)) { - data.font_override[dname]->disconnect("changed", callable_mp(this, &Control::_override_changed)); + data.font_override[dname]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } data.font_override.erase(dname); notification(NOTIFICATION_THEME_CHANGED); @@ -318,21 +312,6 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) { return true; } -void Control::_update_minimum_size() { - if (!is_inside_tree()) { - return; - } - - Size2 minsize = get_combined_minimum_size(); - data.updating_last_minimum_size = false; - - if (minsize != data.last_minimum_size) { - data.last_minimum_size = minsize; - _size_changed(); - emit_signal(SceneStringNames::get_singleton()->minimum_size_changed); - } -} - bool Control::_get(const StringName &p_name, Variant &r_ret) const { String sname = p_name; if (!sname.begins_with("theme_override")) { @@ -586,6 +565,12 @@ void Control::_validate_property(PropertyInfo &property) const { } } +// Global relations. + +bool Control::is_top_level_control() const { + return is_inside_tree() && (!data.parent_canvas_item && !data.RI && is_set_as_top_level()); +} + Control *Control::get_parent_control() const { return data.parent; } @@ -594,97 +579,64 @@ Window *Control::get_parent_window() const { return data.parent_window; } -void Control::set_layout_direction(Control::LayoutDirection p_direction) { - ERR_FAIL_INDEX((int)p_direction, 4); - - data.layout_dir = p_direction; - data.is_rtl_dirty = true; - - propagate_notification(NOTIFICATION_LAYOUT_DIRECTION_CHANGED); -} +Control *Control::get_root_parent_control() const { + const CanvasItem *ci = this; + const Control *root = this; -Control::LayoutDirection Control::get_layout_direction() const { - return data.layout_dir; -} + while (ci) { + const Control *c = Object::cast_to<Control>(ci); + if (c) { + root = c; -bool Control::is_layout_rtl() const { - if (data.is_rtl_dirty) { - const_cast<Control *>(this)->data.is_rtl_dirty = false; - if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { - Window *parent_window = get_parent_window(); - Control *parent_control = get_parent_control(); - if (parent_control) { - const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl(); - } else if (parent_window) { - const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl(); - } else { - if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { - const_cast<Control *>(this)->data.is_rtl = true; - } else { - String locale = TranslationServer::get_singleton()->get_tool_locale(); - const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); - } - } - } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { - if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { - const_cast<Control *>(this)->data.is_rtl = true; - } else { - String locale = TranslationServer::get_singleton()->get_tool_locale(); - const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + if (c->data.RI || c->is_top_level_control()) { + break; } - } else { - const_cast<Control *>(this)->data.is_rtl = (data.layout_dir == LAYOUT_DIRECTION_RTL); } - } - return data.is_rtl; -} -void Control::set_auto_translate(bool p_enable) { - if (p_enable == data.auto_translate) { - return; + ci = ci->get_parent_item(); } - data.auto_translate = p_enable; - - notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); -} - -bool Control::is_auto_translating() const { - return data.auto_translate; -} - -void Control::_clear_size_warning() { - data.size_warning = false; + return const_cast<Control *>(root); } -//moved theme configuration here, so controls can set up even if still not inside active scene - -void Control::add_child_notify(Node *p_child) { - Control *child_c = Object::cast_to<Control>(p_child); - - if (child_c && child_c->data.theme.is_null() && (data.theme_owner || data.theme_owner_window)) { - _propagate_theme_changed(child_c, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff +Rect2 Control::get_parent_anchorable_rect() const { + if (!is_inside_tree()) { + return Rect2(); } - Window *child_w = Object::cast_to<Window>(p_child); + Rect2 parent_rect; + if (data.parent_canvas_item) { + parent_rect = data.parent_canvas_item->get_anchorable_rect(); + } else { +#ifdef TOOLS_ENABLED + Node *edited_root = get_tree()->get_edited_scene_root(); + if (edited_root && (this == edited_root || edited_root->is_ancestor_of(this))) { + parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); + } else { + parent_rect = get_viewport()->get_visible_rect(); + } - if (child_w && child_w->theme.is_null() && (data.theme_owner || data.theme_owner_window)) { - _propagate_theme_changed(child_w, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff +#else + parent_rect = get_viewport()->get_visible_rect(); +#endif } + + return parent_rect; } -void Control::remove_child_notify(Node *p_child) { - Control *child_c = Object::cast_to<Control>(p_child); +Size2 Control::get_parent_area_size() const { + return get_parent_anchorable_rect().size; +} - if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) { - _propagate_theme_changed(child_c, nullptr, nullptr); - } +// Positioning and sizing. - Window *child_w = Object::cast_to<Window>(p_child); +Transform2D Control::_get_internal_transform() const { + Transform2D rot_scale; + rot_scale.set_rotation_and_scale(data.rotation, data.scale); + Transform2D offset; + offset.set_origin(-data.pivot_offset); - if (child_w && (child_w->theme_owner || child_w->theme_owner_window) && child_w->theme.is_null()) { - _propagate_theme_changed(child_w, nullptr, nullptr); - } + return offset.affine_inverse() * (rot_scale * offset); } void Control::_update_canvas_item_transform() { @@ -699,815 +651,146 @@ void Control::_update_canvas_item_transform() { RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), xform); } -void Control::_notification(int p_notification) { - switch (p_notification) { - case NOTIFICATION_POST_ENTER_TREE: { - data.minimum_size_valid = false; - data.is_rtl_dirty = true; - _size_changed(); - } break; - - case NOTIFICATION_EXIT_TREE: { - release_focus(); - get_viewport()->_gui_remove_control(this); - } break; - - case NOTIFICATION_READY: { -#ifdef DEBUG_ENABLED - connect("ready", callable_mp(this, &Control::_clear_size_warning), varray(), CONNECT_DEFERRED | CONNECT_ONESHOT); -#endif - } break; - - case NOTIFICATION_ENTER_CANVAS: { - data.parent = Object::cast_to<Control>(get_parent()); - data.parent_window = Object::cast_to<Window>(get_parent()); - data.is_rtl_dirty = true; - - if (data.theme.is_null()) { - if (data.parent && (data.parent->data.theme_owner || data.parent->data.theme_owner_window)) { - data.theme_owner = data.parent->data.theme_owner; - data.theme_owner_window = data.parent->data.theme_owner_window; - notification(NOTIFICATION_THEME_CHANGED); - } else if (data.parent_window && (data.parent_window->theme_owner || data.parent_window->theme_owner_window)) { - data.theme_owner = data.parent_window->theme_owner; - data.theme_owner_window = data.parent_window->theme_owner_window; - notification(NOTIFICATION_THEME_CHANGED); - } - } - - CanvasItem *node = this; - bool has_parent_control = false; - - while (!node->is_set_as_top_level()) { - CanvasItem *parent = Object::cast_to<CanvasItem>(node->get_parent()); - if (!parent) { - break; - } - - Control *parent_control = Object::cast_to<Control>(parent); - if (parent_control) { - has_parent_control = true; - break; - } - - node = parent; - } - - if (has_parent_control) { - // Do nothing, has a parent control. - } else { - // Is a regular root control or top_level. - Viewport *viewport = get_viewport(); - ERR_FAIL_COND(!viewport); - data.RI = viewport->_gui_add_root_control(this); - } - - data.parent_canvas_item = get_parent_item(); - - if (data.parent_canvas_item) { - data.parent_canvas_item->connect("item_rect_changed", callable_mp(this, &Control::_size_changed)); - } else { - // Connect viewport. - Viewport *viewport = get_viewport(); - ERR_FAIL_COND(!viewport); - viewport->connect("size_changed", callable_mp(this, &Control::_size_changed)); - } - } break; - - case NOTIFICATION_EXIT_CANVAS: { - if (data.parent_canvas_item) { - data.parent_canvas_item->disconnect("item_rect_changed", callable_mp(this, &Control::_size_changed)); - data.parent_canvas_item = nullptr; - } else if (!is_set_as_top_level()) { - //disconnect viewport - Viewport *viewport = get_viewport(); - ERR_FAIL_COND(!viewport); - viewport->disconnect("size_changed", callable_mp(this, &Control::_size_changed)); - } - - if (data.RI) { - get_viewport()->_gui_remove_root_control(data.RI); - data.RI = nullptr; - } - - data.parent = nullptr; - data.parent_canvas_item = nullptr; - data.parent_window = nullptr; - data.is_rtl_dirty = true; - } break; - - case NOTIFICATION_MOVED_IN_PARENT: { - // some parents need to know the order of the children to draw (like TabContainer) - // update if necessary - if (data.parent) { - data.parent->update(); - } - update(); - - if (data.RI) { - get_viewport()->_gui_set_root_order_dirty(); - } - } break; - - case NOTIFICATION_RESIZED: { - emit_signal(SceneStringNames::get_singleton()->resized); - } break; - - case NOTIFICATION_DRAW: { - _update_canvas_item_transform(); - RenderingServer::get_singleton()->canvas_item_set_custom_rect(get_canvas_item(), !data.disable_visibility_clip, Rect2(Point2(), get_size())); - RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), data.clip_contents); - } break; - - case NOTIFICATION_MOUSE_ENTER: { - emit_signal(SceneStringNames::get_singleton()->mouse_entered); - } break; - - case NOTIFICATION_MOUSE_EXIT: { - emit_signal(SceneStringNames::get_singleton()->mouse_exited); - } break; - - case NOTIFICATION_FOCUS_ENTER: { - emit_signal(SceneStringNames::get_singleton()->focus_entered); - update(); - } break; - - case NOTIFICATION_FOCUS_EXIT: { - emit_signal(SceneStringNames::get_singleton()->focus_exited); - update(); - } break; - - case NOTIFICATION_THEME_CHANGED: { - update_minimum_size(); - update(); - } break; - - case NOTIFICATION_VISIBILITY_CHANGED: { - if (!is_visible_in_tree()) { - if (get_viewport() != nullptr) { - get_viewport()->_gui_hide_control(this); - } - } else { - data.minimum_size_valid = false; - _update_minimum_size(); - _size_changed(); - } - } break; - - case NOTIFICATION_TRANSLATION_CHANGED: - case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { - if (is_inside_tree()) { - data.is_rtl_dirty = true; - _size_changed(); - } - } break; - } -} - -bool Control::has_point(const Point2 &p_point) const { - bool ret; - if (GDVIRTUAL_CALL(_has_point, p_point, ret)) { - return ret; - } - return Rect2(Point2(), get_size()).has_point(p_point); -} - -void Control::set_drag_forwarding(Object *p_target) { - if (p_target) { - data.drag_owner = p_target->get_instance_id(); - } else { - data.drag_owner = ObjectID(); - } -} - -Variant Control::get_drag_data(const Point2 &p_point) { - if (data.drag_owner.is_valid()) { - Object *obj = ObjectDB::get_instance(data.drag_owner); - if (obj) { - return obj->call("_get_drag_data_fw", p_point, this); - } - } - - Variant dd; - if (GDVIRTUAL_CALL(_get_drag_data, p_point, dd)) { - return dd; - } - - return Variant(); -} - -bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const { - if (data.drag_owner.is_valid()) { - Object *obj = ObjectDB::get_instance(data.drag_owner); - if (obj) { - return obj->call("_can_drop_data_fw", p_point, p_data, this); - } - } - - bool ret; - if (GDVIRTUAL_CALL(_can_drop_data, p_point, p_data, ret)) { - return ret; - } - return false; -} - -void Control::drop_data(const Point2 &p_point, const Variant &p_data) { - if (data.drag_owner.is_valid()) { - Object *obj = ObjectDB::get_instance(data.drag_owner); - if (obj) { - obj->call("_drop_data_fw", p_point, p_data, this); - return; - } - } - - GDVIRTUAL_CALL(_drop_data, p_point, p_data); -} - -void Control::force_drag(const Variant &p_data, Control *p_control) { - ERR_FAIL_COND(!is_inside_tree()); - ERR_FAIL_COND(p_data.get_type() == Variant::NIL); - - get_viewport()->_gui_force_drag(this, p_data, p_control); -} - -void Control::set_drag_preview(Control *p_control) { - ERR_FAIL_COND(!is_inside_tree()); - ERR_FAIL_COND(!get_viewport()->gui_is_dragging()); - get_viewport()->_gui_set_drag_preview(this, p_control); -} - -bool Control::is_drag_successful() const { - return is_inside_tree() && get_viewport()->gui_is_drag_successful(); -} - -void Control::_call_gui_input(const Ref<InputEvent> &p_event) { - emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); //signal should be first, so it's possible to override an event (and then accept it) - if (!is_inside_tree() || get_viewport()->is_input_handled()) { - return; //input was handled, abort - } - GDVIRTUAL_CALL(_gui_input, p_event); - if (!is_inside_tree() || get_viewport()->is_input_handled()) { - return; //input was handled, abort - } - gui_input(p_event); -} -void Control::gui_input(const Ref<InputEvent> &p_event) { -} - -Size2 Control::get_minimum_size() const { - Vector2 ms; - if (GDVIRTUAL_CALL(_get_minimum_size, ms)) { - return ms; - } - return Vector2(); +Transform2D Control::get_transform() const { + Transform2D xform = _get_internal_transform(); + xform[2] += get_position(); + return xform; } -template <class T> -T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { - ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified."); - - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - // For each theme resource check the theme types provided and see if p_name exists with any of them. - for (const StringName &E : p_theme_types) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { - return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); - } - - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { - return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E); - } - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - for (const StringName &E : p_theme_types) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { - return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E); - } - } - } +/// Anchors and offsets. - // Lastly, fall back on the items defined in the default Theme, if they exist. - for (const StringName &E : p_theme_types) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { - return Theme::get_default()->get_theme_item(p_data_type, p_name, E); - } - } - // If they don't exist, use any type to return the default/empty value. - return Theme::get_default()->get_theme_item(p_data_type, p_name, p_theme_types[0]); +void Control::_set_anchor(Side p_side, real_t p_anchor) { + set_anchor(p_side, p_anchor); } -bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { - ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); - - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - // For each theme resource check the theme types provided and see if p_name exists with any of them. - for (const StringName &E : p_theme_types) { - if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { - return true; - } - - if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } +void Control::set_anchor(Side p_side, real_t p_anchor, bool p_keep_offset, bool p_push_opposite_anchor) { + ERR_FAIL_INDEX((int)p_side, 4); - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - for (const StringName &E : p_theme_types) { - if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - } + Rect2 parent_rect = get_parent_anchorable_rect(); + real_t parent_range = (p_side == SIDE_LEFT || p_side == SIDE_RIGHT) ? parent_rect.size.x : parent_rect.size.y; + real_t previous_pos = data.offset[p_side] + data.anchor[p_side] * parent_range; + real_t previous_opposite_pos = data.offset[(p_side + 2) % 4] + data.anchor[(p_side + 2) % 4] * parent_range; - // Lastly, fall back on the items defined in the default Theme, if they exist. - for (const StringName &E : p_theme_types) { - if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { - return true; - } - } - return false; -} + data.anchor[p_side] = p_anchor; -void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) { - Theme::get_project_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + if (((p_side == SIDE_LEFT || p_side == SIDE_TOP) && data.anchor[p_side] > data.anchor[(p_side + 2) % 4]) || + ((p_side == SIDE_RIGHT || p_side == SIDE_BOTTOM) && data.anchor[p_side] < data.anchor[(p_side + 2) % 4])) { + if (p_push_opposite_anchor) { + data.anchor[(p_side + 2) % 4] = data.anchor[p_side]; } else { - Theme::get_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); - } - } else { - Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list); - } -} - -Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); - if (tex) { - return *tex; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<Ref<Texture2D>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); -} - -Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const Ref<StyleBox> *style = data.style_override.getptr(p_name); - if (style) { - return *style; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); -} - -Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const Ref<Font> *font = data.font_override.getptr(p_name); - if (font) { - return *font; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<Ref<Font>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); -} - -int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const int *font_size = data.font_size_override.getptr(p_name); - if (font_size && (*font_size) > 0) { - return *font_size; + data.anchor[p_side] = data.anchor[(p_side + 2) % 4]; } } - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); -} - -Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const Color *color = data.color_override.getptr(p_name); - if (color) { - return *color; + if (!p_keep_offset) { + data.offset[p_side] = previous_pos - data.anchor[p_side] * parent_range; + if (p_push_opposite_anchor) { + data.offset[(p_side + 2) % 4] = previous_opposite_pos - data.anchor[(p_side + 2) % 4] * parent_range; } } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<Color>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); -} - -int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - const int *constant = data.constant_override.getptr(p_name); - if (constant) { - return *constant; - } + if (is_inside_tree()) { + _size_changed(); } - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); -} - -bool Control::has_theme_icon_override(const StringName &p_name) const { - const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); - return tex != nullptr; -} - -bool Control::has_theme_stylebox_override(const StringName &p_name) const { - const Ref<StyleBox> *style = data.style_override.getptr(p_name); - return style != nullptr; -} - -bool Control::has_theme_font_override(const StringName &p_name) const { - const Ref<Font> *font = data.font_override.getptr(p_name); - return font != nullptr; -} - -bool Control::has_theme_font_size_override(const StringName &p_name) const { - const int *font_size = data.font_size_override.getptr(p_name); - return font_size != nullptr; -} - -bool Control::has_theme_color_override(const StringName &p_name) const { - const Color *color = data.color_override.getptr(p_name); - return color != nullptr; -} - -bool Control::has_theme_constant_override(const StringName &p_name) const { - const int *constant = data.constant_override.getptr(p_name); - return constant != nullptr; + update(); } -bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_icon_override(p_name)) { - return true; - } - } +real_t Control::get_anchor(Side p_side) const { + ERR_FAIL_INDEX_V(int(p_side), 4, 0.0); - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); + return data.anchor[p_side]; } -bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_stylebox_override(p_name)) { - return true; - } - } +void Control::set_offset(Side p_side, real_t p_value) { + ERR_FAIL_INDEX((int)p_side, 4); - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + data.offset[p_side] = p_value; + _size_changed(); } -bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_font_override(p_name)) { - return true; - } - } +real_t Control::get_offset(Side p_side) const { + ERR_FAIL_INDEX_V((int)p_side, 4, 0); - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); + return data.offset[p_side]; } -bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_font_size_override(p_name)) { - return true; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); +void Control::set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos, bool p_push_opposite_anchor) { + set_anchor(p_side, p_anchor, false, p_push_opposite_anchor); + set_offset(p_side, p_pos); } -bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_color_override(p_name)) { - return true; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); +void Control::set_begin(const Size2 &p_point) { + data.offset[0] = p_point.x; + data.offset[1] = p_point.y; + _size_changed(); } -bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { - if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { - if (has_theme_constant_override(p_name)) { - return true; - } - } - - List<StringName> theme_types; - _get_theme_type_dependencies(p_theme_type, &theme_types); - return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); +Size2 Control::get_begin() const { + return Size2(data.offset[0], data.offset[1]); } -float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_base_scale()) { - return theme_owner->data.theme->get_default_base_scale(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) { - return theme_owner_window->theme->get_default_base_scale(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_base_scale()) { - return Theme::get_project_default()->get_default_base_scale(); - } - } - - // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_base_scale()) { - return Theme::get_default()->get_default_base_scale(); - } - return Theme::get_fallback_base_scale(); +void Control::set_end(const Size2 &p_point) { + data.offset[2] = p_point.x; + data.offset[3] = p_point.y; + _size_changed(); } -float Control::get_theme_default_base_scale() const { - return fetch_theme_default_base_scale(data.theme_owner, data.theme_owner_window); +Size2 Control::get_end() const { + return Size2(data.offset[2], data.offset[3]); } -Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_font()) { - return theme_owner->data.theme->get_default_font(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_font()) { - return theme_owner_window->theme->get_default_font(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_font()) { - return Theme::get_project_default()->get_default_font(); - } - } +void Control::set_h_grow_direction(GrowDirection p_direction) { + ERR_FAIL_INDEX((int)p_direction, 3); - // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_font()) { - return Theme::get_default()->get_default_font(); - } - return Theme::get_fallback_font(); + data.h_grow = p_direction; + _size_changed(); } -Ref<Font> Control::get_theme_default_font() const { - return fetch_theme_default_font(data.theme_owner, data.theme_owner_window); +Control::GrowDirection Control::get_h_grow_direction() const { + return data.h_grow; } -int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window) { - // First, look through each control or window node in the branch, until no valid parent can be found. - // Only nodes with a theme resource attached are considered. - // For each theme resource see if their assigned theme has the default value defined and valid. - Control *theme_owner = p_theme_owner; - Window *theme_owner_window = p_theme_owner_window; - - while (theme_owner || theme_owner_window) { - if (theme_owner && theme_owner->data.theme->has_default_font_size()) { - return theme_owner->data.theme->get_default_font_size(); - } - - if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) { - return theme_owner_window->theme->get_default_font_size(); - } - - Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); - Control *parent_c = Object::cast_to<Control>(parent); - if (parent_c) { - theme_owner = parent_c->data.theme_owner; - theme_owner_window = parent_c->data.theme_owner_window; - } else { - Window *parent_w = Object::cast_to<Window>(parent); - if (parent_w) { - theme_owner = parent_w->theme_owner; - theme_owner_window = parent_w->theme_owner_window; - } else { - theme_owner = nullptr; - theme_owner_window = nullptr; - } - } - } - - // Secondly, check the project-defined Theme resource. - if (Theme::get_project_default().is_valid()) { - if (Theme::get_project_default()->has_default_font_size()) { - return Theme::get_project_default()->get_default_font_size(); - } - } +void Control::set_v_grow_direction(GrowDirection p_direction) { + ERR_FAIL_INDEX((int)p_direction, 3); - // Lastly, fall back on the default Theme. - if (Theme::get_default()->has_default_font_size()) { - return Theme::get_default()->get_default_font_size(); - } - return Theme::get_fallback_font_size(); + data.v_grow = p_direction; + _size_changed(); } -int Control::get_theme_default_font_size() const { - return fetch_theme_default_font_size(data.theme_owner, data.theme_owner_window); +Control::GrowDirection Control::get_v_grow_direction() const { + return data.v_grow; } -Rect2 Control::get_parent_anchorable_rect() const { - if (!is_inside_tree()) { - return Rect2(); - } - - Rect2 parent_rect; - if (data.parent_canvas_item) { - parent_rect = data.parent_canvas_item->get_anchorable_rect(); - } else { -#ifdef TOOLS_ENABLED - Node *edited_root = get_tree()->get_edited_scene_root(); - if (edited_root && (this == edited_root || edited_root->is_ancestor_of(this))) { - parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); - } else { - parent_rect = get_viewport()->get_visible_rect(); - } +void Control::_compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]) { + Size2 parent_rect_size = get_parent_anchorable_rect().size; + ERR_FAIL_COND(parent_rect_size.x == 0.0); + ERR_FAIL_COND(parent_rect_size.y == 0.0); -#else - parent_rect = get_viewport()->get_visible_rect(); -#endif + real_t x = p_rect.position.x; + if (is_layout_rtl()) { + x = parent_rect_size.x - x - p_rect.size.x; } - - return parent_rect; -} - -Size2 Control::get_parent_area_size() const { - return get_parent_anchorable_rect().size; + r_anchors[0] = (x - p_offsets[0]) / parent_rect_size.x; + r_anchors[1] = (p_rect.position.y - p_offsets[1]) / parent_rect_size.y; + r_anchors[2] = (x + p_rect.size.x - p_offsets[2]) / parent_rect_size.x; + r_anchors[3] = (p_rect.position.y + p_rect.size.y - p_offsets[3]) / parent_rect_size.y; } -void Control::_size_changed() { - Rect2 parent_rect = get_parent_anchorable_rect(); - - real_t edge_pos[4]; - - for (int i = 0; i < 4; i++) { - real_t area = parent_rect.size[i & 1]; - edge_pos[i] = data.offset[i] + (data.anchor[i] * area); - } - - Point2 new_pos_cache = Point2(edge_pos[0], edge_pos[1]); - Size2 new_size_cache = Point2(edge_pos[2], edge_pos[3]) - new_pos_cache; - - Size2 minimum_size = get_combined_minimum_size(); - - if (minimum_size.width > new_size_cache.width) { - if (data.h_grow == GROW_DIRECTION_BEGIN) { - new_pos_cache.x += new_size_cache.width - minimum_size.width; - } else if (data.h_grow == GROW_DIRECTION_BOTH) { - new_pos_cache.x += 0.5 * (new_size_cache.width - minimum_size.width); - } - - new_size_cache.width = minimum_size.width; - } +void Control::_compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]) { + Size2 parent_rect_size = get_parent_anchorable_rect().size; + real_t x = p_rect.position.x; if (is_layout_rtl()) { - new_pos_cache.x = parent_rect.size.x - new_pos_cache.x - new_size_cache.x; - } - - if (minimum_size.height > new_size_cache.height) { - if (data.v_grow == GROW_DIRECTION_BEGIN) { - new_pos_cache.y += new_size_cache.height - minimum_size.height; - } else if (data.v_grow == GROW_DIRECTION_BOTH) { - new_pos_cache.y += 0.5 * (new_size_cache.height - minimum_size.height); - } - - new_size_cache.height = minimum_size.height; - } - - bool pos_changed = new_pos_cache != data.pos_cache; - bool size_changed = new_size_cache != data.size_cache; - - data.pos_cache = new_pos_cache; - data.size_cache = new_size_cache; - - if (is_inside_tree()) { - if (size_changed) { - notification(NOTIFICATION_RESIZED); - } - if (pos_changed || size_changed) { - item_rect_changed(size_changed); - _notify_transform(); - } - - if (pos_changed && !size_changed) { - _update_canvas_item_transform(); //move because it won't be updated - } + x = parent_rect_size.x - x - p_rect.size.x; } + r_offsets[0] = x - (p_anchors[0] * parent_rect_size.x); + r_offsets[1] = p_rect.position.y - (p_anchors[1] * parent_rect_size.y); + r_offsets[2] = x + p_rect.size.x - (p_anchors[2] * parent_rect_size.x); + r_offsets[3] = p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y); } +/// Presets and layout modes. + void Control::_set_layout_mode(LayoutMode p_mode) { bool list_changed = false; @@ -1557,47 +840,6 @@ Control::LayoutMode Control::_get_layout_mode() const { return LayoutMode::LAYOUT_MODE_POSITION; } -void Control::set_anchor(Side p_side, real_t p_anchor, bool p_keep_offset, bool p_push_opposite_anchor) { - ERR_FAIL_INDEX((int)p_side, 4); - - Rect2 parent_rect = get_parent_anchorable_rect(); - real_t parent_range = (p_side == SIDE_LEFT || p_side == SIDE_RIGHT) ? parent_rect.size.x : parent_rect.size.y; - real_t previous_pos = data.offset[p_side] + data.anchor[p_side] * parent_range; - real_t previous_opposite_pos = data.offset[(p_side + 2) % 4] + data.anchor[(p_side + 2) % 4] * parent_range; - - data.anchor[p_side] = p_anchor; - - if (((p_side == SIDE_LEFT || p_side == SIDE_TOP) && data.anchor[p_side] > data.anchor[(p_side + 2) % 4]) || - ((p_side == SIDE_RIGHT || p_side == SIDE_BOTTOM) && data.anchor[p_side] < data.anchor[(p_side + 2) % 4])) { - if (p_push_opposite_anchor) { - data.anchor[(p_side + 2) % 4] = data.anchor[p_side]; - } else { - data.anchor[p_side] = data.anchor[(p_side + 2) % 4]; - } - } - - if (!p_keep_offset) { - data.offset[p_side] = previous_pos - data.anchor[p_side] * parent_range; - if (p_push_opposite_anchor) { - data.offset[(p_side + 2) % 4] = previous_opposite_pos - data.anchor[(p_side + 2) % 4] * parent_range; - } - } - if (is_inside_tree()) { - _size_changed(); - } - - update(); -} - -void Control::_set_anchor(Side p_side, real_t p_anchor) { - set_anchor(p_side, p_anchor); -} - -void Control::set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos, bool p_push_opposite_anchor) { - set_anchor(p_side, p_anchor, false, p_push_opposite_anchor); - set_offset(p_side, p_pos); -} - void Control::_set_anchors_layout_preset(int p_preset) { bool list_changed = false; @@ -2037,43 +1279,37 @@ void Control::set_grow_direction_preset(LayoutPreset p_preset) { } } -real_t Control::get_anchor(Side p_side) const { - ERR_FAIL_INDEX_V(int(p_side), 4, 0.0); +/// Manual positioning. - return data.anchor[p_side]; +void Control::_set_position(const Size2 &p_point) { + set_position(p_point); } -void Control::set_offset(Side p_side, real_t p_value) { - ERR_FAIL_INDEX((int)p_side, 4); - - data.offset[p_side] = p_value; +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); + } else { + _compute_offsets(Rect2(p_point, data.size_cache), data.anchor, data.offset); + } _size_changed(); } -void Control::set_begin(const Size2 &p_point) { - data.offset[0] = p_point.x; - data.offset[1] = p_point.y; - _size_changed(); +Size2 Control::get_position() const { + return data.pos_cache; } -void Control::set_end(const Size2 &p_point) { - data.offset[2] = p_point.x; - data.offset[3] = p_point.y; - _size_changed(); +void Control::_set_global_position(const Point2 &p_point) { + set_global_position(p_point); } -real_t Control::get_offset(Side p_side) const { - ERR_FAIL_INDEX_V((int)p_side, 4, 0); - - return data.offset[p_side]; -} +void Control::set_global_position(const Point2 &p_point, bool p_keep_offsets) { + Transform2D inv; -Size2 Control::get_begin() const { - return Size2(data.offset[0], data.offset[1]); -} + if (data.parent_canvas_item) { + inv = data.parent_canvas_item->get_global_transform().affine_inverse(); + } -Size2 Control::get_end() const { - return Size2(data.offset[2], data.offset[3]); + set_position(inv.xform(p_point), p_keep_offsets); } Point2 Control::get_global_position() const { @@ -2091,72 +1327,6 @@ Point2 Control::get_screen_position() const { return global_pos; } -void Control::_set_global_position(const Point2 &p_point) { - set_global_position(p_point); -} - -void Control::set_global_position(const Point2 &p_point, bool p_keep_offsets) { - Transform2D inv; - - if (data.parent_canvas_item) { - inv = data.parent_canvas_item->get_global_transform().affine_inverse(); - } - - set_position(inv.xform(p_point), p_keep_offsets); -} - -void Control::_compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]) { - Size2 parent_rect_size = get_parent_anchorable_rect().size; - ERR_FAIL_COND(parent_rect_size.x == 0.0); - ERR_FAIL_COND(parent_rect_size.y == 0.0); - - real_t x = p_rect.position.x; - if (is_layout_rtl()) { - x = parent_rect_size.x - x - p_rect.size.x; - } - r_anchors[0] = (x - p_offsets[0]) / parent_rect_size.x; - r_anchors[1] = (p_rect.position.y - p_offsets[1]) / parent_rect_size.y; - r_anchors[2] = (x + p_rect.size.x - p_offsets[2]) / parent_rect_size.x; - r_anchors[3] = (p_rect.position.y + p_rect.size.y - p_offsets[3]) / parent_rect_size.y; -} - -void Control::_compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]) { - Size2 parent_rect_size = get_parent_anchorable_rect().size; - - real_t x = p_rect.position.x; - if (is_layout_rtl()) { - x = parent_rect_size.x - x - p_rect.size.x; - } - r_offsets[0] = x - (p_anchors[0] * parent_rect_size.x); - r_offsets[1] = p_rect.position.y - (p_anchors[1] * parent_rect_size.y); - r_offsets[2] = x + p_rect.size.x - (p_anchors[2] * parent_rect_size.x); - r_offsets[3] = p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y); -} - -void Control::_set_position(const Size2 &p_point) { - set_position(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); - } else { - _compute_offsets(Rect2(p_point, data.size_cache), data.anchor, data.offset); - } - _size_changed(); -} - -void Control::set_rect(const Rect2 &p_rect) { - for (int i = 0; i < 4; i++) { - data.anchor[i] = ANCHOR_BEGIN; - } - - _compute_offsets(p_rect, data.anchor, data.offset); - if (is_inside_tree()) { - _size_changed(); - } -} - void Control::_set_size(const Size2 &p_size) { #ifdef DEBUG_ENABLED if (data.size_warning && (data.anchor[SIDE_LEFT] != data.anchor[SIDE_RIGHT] || data.anchor[SIDE_TOP] != data.anchor[SIDE_BOTTOM])) { @@ -2184,10 +1354,6 @@ void Control::set_size(const Size2 &p_size, bool p_keep_offsets) { _size_changed(); } -Size2 Control::get_position() const { - return data.pos_cache; -} - Size2 Control::get_size() const { return data.size_cache; } @@ -2196,6 +1362,21 @@ void Control::reset_size() { set_size(Size2()); } +void Control::set_rect(const Rect2 &p_rect) { + for (int i = 0; i < 4; i++) { + data.anchor[i] = ANCHOR_BEGIN; + } + + _compute_offsets(p_rect, data.anchor, data.offset); + if (is_inside_tree()) { + _size_changed(); + } +} + +Rect2 Control::get_rect() const { + return Rect2(get_position(), get_size()); +} + Rect2 Control::get_global_rect() const { return Rect2(get_global_position(), get_size()); } @@ -2220,118 +1401,382 @@ Rect2 Control::get_window_rect() const { return gr; } -Rect2 Control::get_rect() const { - return Rect2(get_position(), get_size()); -} - Rect2 Control::get_anchorable_rect() const { return Rect2(Point2(), get_size()); } -void Control::begin_bulk_theme_override() { - data.bulk_theme_override = true; +void Control::set_scale(const Vector2 &p_scale) { + data.scale = p_scale; + // Avoid having 0 scale values, can lead to errors in physics and rendering. + if (data.scale.x == 0) { + data.scale.x = CMP_EPSILON; + } + if (data.scale.y == 0) { + data.scale.y = CMP_EPSILON; + } + update(); + _notify_transform(); } -void Control::end_bulk_theme_override() { - ERR_FAIL_COND(!data.bulk_theme_override); +Vector2 Control::get_scale() const { + return data.scale; +} - data.bulk_theme_override = false; - _notify_theme_changed(); +void Control::set_rotation(real_t p_radians) { + data.rotation = p_radians; + update(); + _notify_transform(); } -void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) { - ERR_FAIL_COND(!p_icon.is_valid()); +real_t Control::get_rotation() const { + return data.rotation; +} - if (data.icon_override.has(p_name)) { - data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +void Control::set_pivot_offset(const Vector2 &p_pivot) { + data.pivot_offset = p_pivot; + update(); + _notify_transform(); +} + +Vector2 Control::get_pivot_offset() const { + return data.pivot_offset; +} + +/// Sizes. + +void Control::_update_minimum_size() { + if (!is_inside_tree()) { + return; } - data.icon_override[p_name] = p_icon; - data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); + Size2 minsize = get_combined_minimum_size(); + data.updating_last_minimum_size = false; + + if (minsize != data.last_minimum_size) { + data.last_minimum_size = minsize; + _size_changed(); + emit_signal(SceneStringNames::get_singleton()->minimum_size_changed); + } } -void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { - ERR_FAIL_COND(!p_style.is_valid()); +void Control::update_minimum_size() { + if (!is_inside_tree() || data.block_minimum_size_adjust) { + return; + } - if (data.style_override.has(p_name)) { - data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); + Control *invalidate = this; + + //invalidate cache upwards + while (invalidate && invalidate->data.minimum_size_valid) { + invalidate->data.minimum_size_valid = false; + if (invalidate->is_set_as_top_level()) { + break; // do not go further up + } + if (!invalidate->data.parent && get_parent()) { + Window *parent_window = Object::cast_to<Window>(get_parent()); + if (parent_window && parent_window->is_wrapping_controls()) { + parent_window->child_controls_changed(); + } + } + invalidate = invalidate->data.parent; } - data.style_override[p_name] = p_style; - data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); + if (!is_visible_in_tree()) { + return; + } + + if (data.updating_last_minimum_size) { + return; + } + + data.updating_last_minimum_size = true; + + MessageQueue::get_singleton()->push_call(this, "_update_minimum_size"); } -void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) { - ERR_FAIL_COND(!p_font.is_valid()); +void Control::set_block_minimum_size_adjust(bool p_block) { + data.block_minimum_size_adjust = p_block; +} - if (data.font_override.has(p_name)) { - data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +bool Control::is_minimum_size_adjust_blocked() const { + return data.block_minimum_size_adjust; +} + +Size2 Control::get_minimum_size() const { + Vector2 ms; + if (GDVIRTUAL_CALL(_get_minimum_size, ms)) { + return ms; } + return Vector2(); +} - data.font_override[p_name] = p_font; - data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); - _notify_theme_changed(); +void Control::set_custom_minimum_size(const Size2 &p_custom) { + if (p_custom == data.custom_minimum_size) { + return; + } + data.custom_minimum_size = p_custom; + update_minimum_size(); } -void Control::add_theme_font_size_override(const StringName &p_name, int p_font_size) { - data.font_size_override[p_name] = p_font_size; - _notify_theme_changed(); +Size2 Control::get_custom_minimum_size() const { + return data.custom_minimum_size; } -void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) { - data.color_override[p_name] = p_color; - _notify_theme_changed(); +void Control::_update_minimum_size_cache() { + Size2 minsize = get_minimum_size(); + minsize.x = MAX(minsize.x, data.custom_minimum_size.x); + minsize.y = MAX(minsize.y, data.custom_minimum_size.y); + + bool size_changed = false; + if (data.minimum_size_cache != minsize) { + size_changed = true; + } + + data.minimum_size_cache = minsize; + data.minimum_size_valid = true; + + if (size_changed) { + update_minimum_size(); + } } -void Control::add_theme_constant_override(const StringName &p_name, int p_constant) { - data.constant_override[p_name] = p_constant; - _notify_theme_changed(); +Size2 Control::get_combined_minimum_size() const { + if (!data.minimum_size_valid) { + const_cast<Control *>(this)->_update_minimum_size_cache(); + } + return data.minimum_size_cache; } -void Control::remove_theme_icon_override(const StringName &p_name) { - if (data.icon_override.has(p_name)) { - data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +void Control::_size_changed() { + Rect2 parent_rect = get_parent_anchorable_rect(); + + real_t edge_pos[4]; + + for (int i = 0; i < 4; i++) { + real_t area = parent_rect.size[i & 1]; + edge_pos[i] = data.offset[i] + (data.anchor[i] * area); } - data.icon_override.erase(p_name); - _notify_theme_changed(); + Point2 new_pos_cache = Point2(edge_pos[0], edge_pos[1]); + Size2 new_size_cache = Point2(edge_pos[2], edge_pos[3]) - new_pos_cache; + + Size2 minimum_size = get_combined_minimum_size(); + + if (minimum_size.width > new_size_cache.width) { + if (data.h_grow == GROW_DIRECTION_BEGIN) { + new_pos_cache.x += new_size_cache.width - minimum_size.width; + } else if (data.h_grow == GROW_DIRECTION_BOTH) { + new_pos_cache.x += 0.5 * (new_size_cache.width - minimum_size.width); + } + + new_size_cache.width = minimum_size.width; + } + + if (is_layout_rtl()) { + new_pos_cache.x = parent_rect.size.x - new_pos_cache.x - new_size_cache.x; + } + + if (minimum_size.height > new_size_cache.height) { + if (data.v_grow == GROW_DIRECTION_BEGIN) { + new_pos_cache.y += new_size_cache.height - minimum_size.height; + } else if (data.v_grow == GROW_DIRECTION_BOTH) { + new_pos_cache.y += 0.5 * (new_size_cache.height - minimum_size.height); + } + + new_size_cache.height = minimum_size.height; + } + + bool pos_changed = new_pos_cache != data.pos_cache; + bool size_changed = new_size_cache != data.size_cache; + + data.pos_cache = new_pos_cache; + data.size_cache = new_size_cache; + + if (is_inside_tree()) { + if (size_changed) { + notification(NOTIFICATION_RESIZED); + } + if (pos_changed || size_changed) { + item_rect_changed(size_changed); + _notify_transform(); + } + + if (pos_changed && !size_changed) { + _update_canvas_item_transform(); //move because it won't be updated + } + } } -void Control::remove_theme_style_override(const StringName &p_name) { - if (data.style_override.has(p_name)) { - data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +void Control::_clear_size_warning() { + data.size_warning = false; +} + +// Container sizing. + +void Control::set_h_size_flags(int p_flags) { + if (data.h_size_flags == p_flags) { + return; } + data.h_size_flags = p_flags; + emit_signal(SceneStringNames::get_singleton()->size_flags_changed); +} - data.style_override.erase(p_name); - _notify_theme_changed(); +int Control::get_h_size_flags() const { + return data.h_size_flags; } -void Control::remove_theme_font_override(const StringName &p_name) { - if (data.font_override.has(p_name)) { - data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed)); +void Control::set_v_size_flags(int p_flags) { + if (data.v_size_flags == p_flags) { + return; } + data.v_size_flags = p_flags; + emit_signal(SceneStringNames::get_singleton()->size_flags_changed); +} - data.font_override.erase(p_name); - _notify_theme_changed(); +int Control::get_v_size_flags() const { + return data.v_size_flags; } -void Control::remove_theme_font_size_override(const StringName &p_name) { - data.font_size_override.erase(p_name); - _notify_theme_changed(); +void Control::set_stretch_ratio(real_t p_ratio) { + if (data.expand == p_ratio) { + return; + } + + data.expand = p_ratio; + emit_signal(SceneStringNames::get_singleton()->size_flags_changed); } -void Control::remove_theme_color_override(const StringName &p_name) { - data.color_override.erase(p_name); - _notify_theme_changed(); +real_t Control::get_stretch_ratio() const { + return data.expand; } -void Control::remove_theme_constant_override(const StringName &p_name) { - data.constant_override.erase(p_name); - _notify_theme_changed(); +// Input events. + +void Control::_call_gui_input(const Ref<InputEvent> &p_event) { + emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); //signal should be first, so it's possible to override an event (and then accept it) + if (!is_inside_tree() || get_viewport()->is_input_handled()) { + return; //input was handled, abort + } + GDVIRTUAL_CALL(_gui_input, p_event); + if (!is_inside_tree() || get_viewport()->is_input_handled()) { + return; //input was handled, abort + } + gui_input(p_event); +} + +void Control::gui_input(const Ref<InputEvent> &p_event) { +} + +void Control::accept_event() { + if (is_inside_tree()) { + get_viewport()->_gui_accept_event(); + } +} + +bool Control::has_point(const Point2 &p_point) const { + bool ret; + if (GDVIRTUAL_CALL(_has_point, p_point, ret)) { + return ret; + } + return Rect2(Point2(), get_size()).has_point(p_point); +} + +void Control::set_mouse_filter(MouseFilter p_filter) { + ERR_FAIL_INDEX(p_filter, 3); + data.mouse_filter = p_filter; + notify_property_list_changed(); + update_configuration_warnings(); +} + +Control::MouseFilter Control::get_mouse_filter() const { + return data.mouse_filter; +} + +void Control::set_force_pass_scroll_events(bool p_force_pass_scroll_events) { + data.force_pass_scroll_events = p_force_pass_scroll_events; +} + +bool Control::is_force_pass_scroll_events() const { + return data.force_pass_scroll_events; +} + +void Control::warp_mouse(const Point2 &p_position) { + ERR_FAIL_COND(!is_inside_tree()); + get_viewport()->warp_mouse(get_global_transform_with_canvas().xform(p_position)); +} + +// Drag and drop handling. + +void Control::set_drag_forwarding(Object *p_target) { + if (p_target) { + data.drag_owner = p_target->get_instance_id(); + } else { + data.drag_owner = ObjectID(); + } +} + +Variant Control::get_drag_data(const Point2 &p_point) { + if (data.drag_owner.is_valid()) { + Object *obj = ObjectDB::get_instance(data.drag_owner); + if (obj) { + return obj->call("_get_drag_data_fw", p_point, this); + } + } + + Variant dd; + if (GDVIRTUAL_CALL(_get_drag_data, p_point, dd)) { + return dd; + } + + return Variant(); +} + +bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const { + if (data.drag_owner.is_valid()) { + Object *obj = ObjectDB::get_instance(data.drag_owner); + if (obj) { + return obj->call("_can_drop_data_fw", p_point, p_data, this); + } + } + + bool ret; + if (GDVIRTUAL_CALL(_can_drop_data, p_point, p_data, ret)) { + return ret; + } + return false; +} + +void Control::drop_data(const Point2 &p_point, const Variant &p_data) { + if (data.drag_owner.is_valid()) { + Object *obj = ObjectDB::get_instance(data.drag_owner); + if (obj) { + obj->call("_drop_data_fw", p_point, p_data, this); + return; + } + } + + GDVIRTUAL_CALL(_drop_data, p_point, p_data); +} + +void Control::force_drag(const Variant &p_data, Control *p_control) { + ERR_FAIL_COND(!is_inside_tree()); + ERR_FAIL_COND(p_data.get_type() == Variant::NIL); + + get_viewport()->_gui_force_drag(this, p_data, p_control); +} + +void Control::set_drag_preview(Control *p_control) { + ERR_FAIL_COND(!is_inside_tree()); + ERR_FAIL_COND(!get_viewport()->gui_is_dragging()); + get_viewport()->_gui_set_drag_preview(this, p_control); +} + +bool Control::is_drag_successful() const { + return is_inside_tree() && get_viewport()->gui_is_drag_successful(); } +// Focus. + void Control::set_focus_mode(FocusMode p_focus_mode) { ERR_FAIL_INDEX((int)p_focus_mode, 3); @@ -2342,6 +1787,41 @@ void Control::set_focus_mode(FocusMode p_focus_mode) { data.focus_mode = p_focus_mode; } +Control::FocusMode Control::get_focus_mode() const { + return data.focus_mode; +} + +bool Control::has_focus() const { + return is_inside_tree() && get_viewport()->_gui_control_has_focus(this); +} + +void Control::grab_focus() { + ERR_FAIL_COND(!is_inside_tree()); + + if (data.focus_mode == FOCUS_NONE) { + WARN_PRINT("This control can't grab focus. Use set_focus_mode() to allow a control to get focus."); + return; + } + + get_viewport()->_gui_control_grab_focus(this); +} + +void Control::grab_click_focus() { + ERR_FAIL_COND(!is_inside_tree()); + + get_viewport()->_gui_grab_click_focus(this); +} + +void Control::release_focus() { + ERR_FAIL_COND(!is_inside_tree()); + + if (!has_focus()) { + return; + } + + get_viewport()->gui_release_focus(); +} + static Control *_next_control(Control *p_from) { if (p_from->is_set_as_top_level()) { return nullptr; // Can't go above. @@ -2520,181 +2000,6 @@ Control *Control::find_prev_valid_focus() const { return nullptr; } -Control::FocusMode Control::get_focus_mode() const { - return data.focus_mode; -} - -bool Control::has_focus() const { - return is_inside_tree() && get_viewport()->_gui_control_has_focus(this); -} - -void Control::grab_focus() { - ERR_FAIL_COND(!is_inside_tree()); - - if (data.focus_mode == FOCUS_NONE) { - WARN_PRINT("This control can't grab focus. Use set_focus_mode() to allow a control to get focus."); - return; - } - - get_viewport()->_gui_control_grab_focus(this); -} - -void Control::release_focus() { - ERR_FAIL_COND(!is_inside_tree()); - - if (!has_focus()) { - return; - } - - get_viewport()->gui_release_focus(); -} - -bool Control::is_top_level_control() const { - return is_inside_tree() && (!data.parent_canvas_item && !data.RI && is_set_as_top_level()); -} - -void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign) { - Control *c = Object::cast_to<Control>(p_at); - - if (c && c != p_owner && c->data.theme.is_valid()) { // has a theme, this can't be propagated - return; - } - - Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr; - - if (w && w != p_owner_window && w->theme.is_valid()) { // has a theme, this can't be propagated - return; - } - - for (int i = 0; i < p_at->get_child_count(); i++) { - CanvasItem *child = Object::cast_to<CanvasItem>(p_at->get_child(i)); - if (child) { - _propagate_theme_changed(child, p_owner, p_owner_window, p_assign); - } else { - Window *window = Object::cast_to<Window>(p_at->get_child(i)); - if (window) { - _propagate_theme_changed(window, p_owner, p_owner_window, p_assign); - } - } - } - - if (c) { - if (p_assign) { - c->data.theme_owner = p_owner; - c->data.theme_owner_window = p_owner_window; - } - c->notification(Control::NOTIFICATION_THEME_CHANGED); - c->emit_signal(SceneStringNames::get_singleton()->theme_changed); - } - - if (w) { - if (p_assign) { - w->theme_owner = p_owner; - w->theme_owner_window = p_owner_window; - } - w->notification(Window::NOTIFICATION_THEME_CHANGED); - w->emit_signal(SceneStringNames::get_singleton()->theme_changed); - } -} - -void Control::_theme_changed() { - _propagate_theme_changed(this, this, nullptr, false); -} - -void Control::_notify_theme_changed() { - if (!data.bulk_theme_override) { - notification(NOTIFICATION_THEME_CHANGED); - } -} - -void Control::set_theme(const Ref<Theme> &p_theme) { - if (data.theme == p_theme) { - return; - } - - if (data.theme.is_valid()) { - data.theme->disconnect("changed", callable_mp(this, &Control::_theme_changed)); - } - - data.theme = p_theme; - if (!p_theme.is_null()) { - data.theme_owner = this; - data.theme_owner_window = nullptr; - _propagate_theme_changed(this, this, nullptr); - } else { - Control *parent_c = Object::cast_to<Control>(get_parent()); - - if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window); - } else { - Window *parent_w = cast_to<Window>(get_parent()); - if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { - Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window); - } else { - Control::_propagate_theme_changed(this, nullptr, nullptr); - } - } - } - - if (data.theme.is_valid()) { - data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), varray(), CONNECT_DEFERRED); - } -} - -Ref<Theme> Control::get_theme() const { - return data.theme; -} - -void Control::set_theme_type_variation(const StringName &p_theme_type) { - data.theme_type_variation = p_theme_type; - _propagate_theme_changed(this, data.theme_owner, data.theme_owner_window); -} - -StringName Control::get_theme_type_variation() const { - return data.theme_type_variation; -} - -void Control::set_tooltip(const String &p_tooltip) { - data.tooltip = p_tooltip; - update_configuration_warnings(); -} - -String Control::get_tooltip(const Point2 &p_pos) const { - return data.tooltip; -} - -Control *Control::make_custom_tooltip(const String &p_text) const { - Object *ret = nullptr; - if (GDVIRTUAL_CALL(_make_custom_tooltip, p_text, ret)) { - return Object::cast_to<Control>(ret); - } - return nullptr; -} - -void Control::set_default_cursor_shape(CursorShape p_shape) { - ERR_FAIL_INDEX(int(p_shape), CURSOR_MAX); - - data.default_cursor = p_shape; -} - -Control::CursorShape Control::get_default_cursor_shape() const { - return data.default_cursor; -} - -Control::CursorShape Control::get_cursor_shape(const Point2 &p_pos) const { - return data.default_cursor; -} - -Transform2D Control::get_transform() const { - Transform2D xform = _get_internal_transform(); - xform[2] += get_position(); - return xform; -} - -String Control::_get_tooltip() const { - return data.tooltip; -} - void Control::set_focus_neighbor(Side p_side, const NodePath &p_neighbor) { ERR_FAIL_INDEX((int)p_side, 4); data.focus_neighbor[p_side] = p_neighbor; @@ -2861,273 +2166,1011 @@ void Control::_window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, cons } } -void Control::set_h_size_flags(int p_flags) { - if (data.h_size_flags == p_flags) { +// Rendering. + +void Control::set_default_cursor_shape(CursorShape p_shape) { + ERR_FAIL_INDEX(int(p_shape), CURSOR_MAX); + + data.default_cursor = p_shape; +} + +Control::CursorShape Control::get_default_cursor_shape() const { + return data.default_cursor; +} + +Control::CursorShape Control::get_cursor_shape(const Point2 &p_pos) const { + return data.default_cursor; +} + +void Control::set_disable_visibility_clip(bool p_ignore) { + data.disable_visibility_clip = p_ignore; + update(); +} + +bool Control::is_visibility_clip_disabled() const { + return data.disable_visibility_clip; +} + +void Control::set_clip_contents(bool p_clip) { + data.clip_contents = p_clip; + update(); +} + +bool Control::is_clipping_contents() { + return data.clip_contents; +} + +// Theming. + +void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign) { + Control *c = Object::cast_to<Control>(p_at); + + if (c && c != p_owner && c->data.theme.is_valid()) { // has a theme, this can't be propagated return; } - data.h_size_flags = p_flags; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + + Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr; + + if (w && w != p_owner_window && w->theme.is_valid()) { // has a theme, this can't be propagated + return; + } + + for (int i = 0; i < p_at->get_child_count(); i++) { + CanvasItem *child = Object::cast_to<CanvasItem>(p_at->get_child(i)); + if (child) { + _propagate_theme_changed(child, p_owner, p_owner_window, p_assign); + } else { + Window *window = Object::cast_to<Window>(p_at->get_child(i)); + if (window) { + _propagate_theme_changed(window, p_owner, p_owner_window, p_assign); + } + } + } + + if (c) { + if (p_assign) { + c->data.theme_owner = p_owner; + c->data.theme_owner_window = p_owner_window; + } + c->notification(Control::NOTIFICATION_THEME_CHANGED); + c->emit_signal(SceneStringNames::get_singleton()->theme_changed); + } + + if (w) { + if (p_assign) { + w->theme_owner = p_owner; + w->theme_owner_window = p_owner_window; + } + w->notification(Window::NOTIFICATION_THEME_CHANGED); + w->emit_signal(SceneStringNames::get_singleton()->theme_changed); + } } -int Control::get_h_size_flags() const { - return data.h_size_flags; +void Control::_theme_changed() { + _propagate_theme_changed(this, this, nullptr, false); } -void Control::set_v_size_flags(int p_flags) { - if (data.v_size_flags == p_flags) { - return; +void Control::_theme_property_override_changed() { + notification(NOTIFICATION_THEME_CHANGED); + emit_signal(SceneStringNames::get_singleton()->theme_changed); + update_minimum_size(); // Overrides are likely to affect minimum size. +} + +void Control::_notify_theme_changed() { + if (!data.bulk_theme_override) { + notification(NOTIFICATION_THEME_CHANGED); } - data.v_size_flags = p_flags; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); } -void Control::set_stretch_ratio(real_t p_ratio) { - if (data.expand == p_ratio) { +void Control::set_theme(const Ref<Theme> &p_theme) { + if (data.theme == p_theme) { return; } - data.expand = p_ratio; - emit_signal(SceneStringNames::get_singleton()->size_flags_changed); + if (data.theme.is_valid()) { + data.theme->disconnect("changed", callable_mp(this, &Control::_theme_changed)); + } + + data.theme = p_theme; + if (!p_theme.is_null()) { + data.theme_owner = this; + data.theme_owner_window = nullptr; + _propagate_theme_changed(this, this, nullptr); + } else { + Control *parent_c = Object::cast_to<Control>(get_parent()); + + if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) { + Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window); + } else { + Window *parent_w = cast_to<Window>(get_parent()); + if (parent_w && (parent_w->theme_owner || parent_w->theme_owner_window)) { + Control::_propagate_theme_changed(this, parent_w->theme_owner, parent_w->theme_owner_window); + } else { + Control::_propagate_theme_changed(this, nullptr, nullptr); + } + } + } + + if (data.theme.is_valid()) { + data.theme->connect("changed", callable_mp(this, &Control::_theme_changed), varray(), CONNECT_DEFERRED); + } } -real_t Control::get_stretch_ratio() const { - return data.expand; +Ref<Theme> Control::get_theme() const { + return data.theme; } -void Control::grab_click_focus() { - ERR_FAIL_COND(!is_inside_tree()); +void Control::set_theme_type_variation(const StringName &p_theme_type) { + data.theme_type_variation = p_theme_type; + _propagate_theme_changed(this, data.theme_owner, data.theme_owner_window); +} - get_viewport()->_gui_grab_click_focus(this); +StringName Control::get_theme_type_variation() const { + return data.theme_type_variation; } -void Control::update_minimum_size() { - if (!is_inside_tree() || data.block_minimum_size_adjust) { - return; +/// Theme property lookup. + +template <class T> +T Control::get_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, T(), "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. + for (const StringName &E : p_theme_types) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { + return theme_owner->data.theme->get_theme_item(p_data_type, p_name, E); + } + + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { + return theme_owner_window->theme->get_theme_item(p_data_type, p_name, E); + } + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } + } } - Control *invalidate = this; + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + for (const StringName &E : p_theme_types) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { + return Theme::get_project_default()->get_theme_item(p_data_type, p_name, E); + } + } + } - //invalidate cache upwards - while (invalidate && invalidate->data.minimum_size_valid) { - invalidate->data.minimum_size_valid = false; - if (invalidate->is_set_as_top_level()) { - break; // do not go further up + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (const StringName &E : p_theme_types) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { + return Theme::get_default()->get_theme_item(p_data_type, p_name, E); } - if (!invalidate->data.parent && get_parent()) { - Window *parent_window = Object::cast_to<Window>(get_parent()); - if (parent_window && parent_window->is_wrapping_controls()) { - parent_window->child_controls_changed(); + } + // If they don't exist, use any type to return the default/empty value. + return Theme::get_default()->get_theme_item(p_data_type, p_name, p_theme_types[0]); +} + +bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types) { + ERR_FAIL_COND_V_MSG(p_theme_types.size() == 0, false, "At least one theme type must be specified."); + + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + // For each theme resource check the theme types provided and see if p_name exists with any of them. + for (const StringName &E : p_theme_types) { + if (theme_owner && theme_owner->data.theme->has_theme_item(p_data_type, p_name, E)) { + return true; + } + + if (theme_owner_window && theme_owner_window->theme->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; } } - invalidate = invalidate->data.parent; } - if (!is_visible_in_tree()) { - return; + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + for (const StringName &E : p_theme_types) { + if (Theme::get_project_default()->has_theme_item(p_data_type, p_name, E)) { + return true; + } + } } - if (data.updating_last_minimum_size) { - return; + // Lastly, fall back on the items defined in the default Theme, if they exist. + for (const StringName &E : p_theme_types) { + if (Theme::get_default()->has_theme_item(p_data_type, p_name, E)) { + return true; + } } + return false; +} - data.updating_last_minimum_size = true; +void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) { + Theme::get_project_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + } else { + Theme::get_default()->get_type_dependencies(get_class_name(), data.theme_type_variation, p_list); + } + } else { + Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list); + } +} - MessageQueue::get_singleton()->push_call(this, "_update_minimum_size"); +Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); + if (tex) { + return *tex; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<Texture2D>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); } -int Control::get_v_size_flags() const { - return data.v_size_flags; +Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const Ref<StyleBox> *style = data.style_override.getptr(p_name); + if (style) { + return *style; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } -void Control::set_mouse_filter(MouseFilter p_filter) { - ERR_FAIL_INDEX(p_filter, 3); - data.mouse_filter = p_filter; - notify_property_list_changed(); - update_configuration_warnings(); +Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const Ref<Font> *font = data.font_override.getptr(p_name); + if (font) { + return *font; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Ref<Font>>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); } -Control::MouseFilter Control::get_mouse_filter() const { - return data.mouse_filter; +int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const int *font_size = data.font_size_override.getptr(p_name); + if (font_size && (*font_size) > 0) { + return *font_size; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } -void Control::set_force_pass_scroll_events(bool p_force_pass_scroll_events) { - data.force_pass_scroll_events = p_force_pass_scroll_events; +Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const Color *color = data.color_override.getptr(p_name); + if (color) { + return *color; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<Color>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); } -bool Control::is_force_pass_scroll_events() const { - return data.force_pass_scroll_events; +int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + const int *constant = data.constant_override.getptr(p_name); + if (constant) { + return *constant; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return get_theme_item_in_types<int>(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } -void Control::warp_mouse(const Point2 &p_position) { - ERR_FAIL_COND(!is_inside_tree()); - get_viewport()->warp_mouse(get_global_transform_with_canvas().xform(p_position)); +bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_icon_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_ICON, p_name, theme_types); } -bool Control::is_text_field() const { - return false; +bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_stylebox_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } -Array Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { - if (p_parser_type == TextServer::STRUCTURED_TEXT_CUSTOM) { - Array ret; - if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, ret)) { - return ret; - } else { - return Array(); +bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_font_override(p_name)) { + return true; } - } else { - return TS->parse_structured_text(p_parser_type, p_args, p_text); } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT, p_name, theme_types); } -void Control::set_rotation(real_t p_radians) { - data.rotation = p_radians; - update(); - _notify_transform(); +bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_font_size_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } -real_t Control::get_rotation() const { - return data.rotation; +bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_color_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_COLOR, p_name, theme_types); } -void Control::_override_changed() { - notification(NOTIFICATION_THEME_CHANGED); - emit_signal(SceneStringNames::get_singleton()->theme_changed); - update_minimum_size(); // Overrides are likely to affect minimum size. +bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { + if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) { + if (has_theme_constant_override(p_name)) { + return true; + } + } + + List<StringName> theme_types; + _get_theme_type_dependencies(p_theme_type, &theme_types); + return has_theme_item_in_types(data.theme_owner, data.theme_owner_window, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } -void Control::set_pivot_offset(const Vector2 &p_pivot) { - data.pivot_offset = p_pivot; - update(); - _notify_transform(); +/// Local property overrides. + +void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) { + ERR_FAIL_COND(!p_icon.is_valid()); + + if (data.icon_override.has(p_name)) { + data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + } + + data.icon_override[p_name] = p_icon; + data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + _notify_theme_changed(); } -Vector2 Control::get_pivot_offset() const { - return data.pivot_offset; +void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) { + ERR_FAIL_COND(!p_style.is_valid()); + + if (data.style_override.has(p_name)) { + data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + } + + data.style_override[p_name] = p_style; + data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + _notify_theme_changed(); } -void Control::set_scale(const Vector2 &p_scale) { - data.scale = p_scale; - // Avoid having 0 scale values, can lead to errors in physics and rendering. - if (data.scale.x == 0) { - data.scale.x = CMP_EPSILON; +void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) { + ERR_FAIL_COND(!p_font.is_valid()); + + if (data.font_override.has(p_name)) { + data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } - if (data.scale.y == 0) { - data.scale.y = CMP_EPSILON; + + data.font_override[p_name] = p_font; + data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_theme_property_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED); + _notify_theme_changed(); +} + +void Control::add_theme_font_size_override(const StringName &p_name, int p_font_size) { + data.font_size_override[p_name] = p_font_size; + _notify_theme_changed(); +} + +void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) { + data.color_override[p_name] = p_color; + _notify_theme_changed(); +} + +void Control::add_theme_constant_override(const StringName &p_name, int p_constant) { + data.constant_override[p_name] = p_constant; + _notify_theme_changed(); +} + +void Control::remove_theme_icon_override(const StringName &p_name) { + if (data.icon_override.has(p_name)) { + data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); } - update(); - _notify_transform(); + + data.icon_override.erase(p_name); + _notify_theme_changed(); } -Vector2 Control::get_scale() const { - return data.scale; +void Control::remove_theme_style_override(const StringName &p_name) { + if (data.style_override.has(p_name)) { + data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + } + + data.style_override.erase(p_name); + _notify_theme_changed(); } -Control *Control::get_root_parent_control() const { - const CanvasItem *ci = this; - const Control *root = this; +void Control::remove_theme_font_override(const StringName &p_name) { + if (data.font_override.has(p_name)) { + data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_theme_property_override_changed)); + } - while (ci) { - const Control *c = Object::cast_to<Control>(ci); - if (c) { - root = c; + data.font_override.erase(p_name); + _notify_theme_changed(); +} - if (c->data.RI || c->is_top_level_control()) { - break; +void Control::remove_theme_font_size_override(const StringName &p_name) { + data.font_size_override.erase(p_name); + _notify_theme_changed(); +} + +void Control::remove_theme_color_override(const StringName &p_name) { + data.color_override.erase(p_name); + _notify_theme_changed(); +} + +void Control::remove_theme_constant_override(const StringName &p_name) { + data.constant_override.erase(p_name); + _notify_theme_changed(); +} + +bool Control::has_theme_icon_override(const StringName &p_name) const { + const Ref<Texture2D> *tex = data.icon_override.getptr(p_name); + return tex != nullptr; +} + +bool Control::has_theme_stylebox_override(const StringName &p_name) const { + const Ref<StyleBox> *style = data.style_override.getptr(p_name); + return style != nullptr; +} + +bool Control::has_theme_font_override(const StringName &p_name) const { + const Ref<Font> *font = data.font_override.getptr(p_name); + return font != nullptr; +} + +bool Control::has_theme_font_size_override(const StringName &p_name) const { + const int *font_size = data.font_size_override.getptr(p_name); + return font_size != nullptr; +} + +bool Control::has_theme_color_override(const StringName &p_name) const { + const Color *color = data.color_override.getptr(p_name); + return color != nullptr; +} + +bool Control::has_theme_constant_override(const StringName &p_name) const { + const int *constant = data.constant_override.getptr(p_name); + return constant != nullptr; +} + +/// Default theme properties. + +float Control::fetch_theme_default_base_scale(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; + + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_base_scale()) { + return theme_owner->data.theme->get_default_base_scale(); + } + + if (theme_owner_window && theme_owner_window->theme->has_default_base_scale()) { + return theme_owner_window->theme->get_default_base_scale(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; } } + } - ci = ci->get_parent_item(); + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_base_scale()) { + return Theme::get_project_default()->get_default_base_scale(); + } } - return const_cast<Control *>(root); + // Lastly, fall back on the default Theme. + if (Theme::get_default()->has_default_base_scale()) { + return Theme::get_default()->get_default_base_scale(); + } + return Theme::get_fallback_base_scale(); } -void Control::set_block_minimum_size_adjust(bool p_block) { - data.block_minimum_size_adjust = p_block; +float Control::get_theme_default_base_scale() const { + return fetch_theme_default_base_scale(data.theme_owner, data.theme_owner_window); } -bool Control::is_minimum_size_adjust_blocked() const { - return data.block_minimum_size_adjust; -} +Ref<Font> Control::fetch_theme_default_font(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; -void Control::set_disable_visibility_clip(bool p_ignore) { - data.disable_visibility_clip = p_ignore; - update(); + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_font()) { + return theme_owner->data.theme->get_default_font(); + } + + if (theme_owner_window && theme_owner_window->theme->has_default_font()) { + return theme_owner_window->theme->get_default_font(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } + } + } + + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_font()) { + return Theme::get_project_default()->get_default_font(); + } + } + + // Lastly, fall back on the default Theme. + if (Theme::get_default()->has_default_font()) { + return Theme::get_default()->get_default_font(); + } + return Theme::get_fallback_font(); } -bool Control::is_visibility_clip_disabled() const { - return data.disable_visibility_clip; +Ref<Font> Control::get_theme_default_font() const { + return fetch_theme_default_font(data.theme_owner, data.theme_owner_window); } -void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { - Node::get_argument_options(p_function, p_idx, r_options); +int Control::fetch_theme_default_font_size(Control *p_theme_owner, Window *p_theme_owner_window) { + // First, look through each control or window node in the branch, until no valid parent can be found. + // Only nodes with a theme resource attached are considered. + // For each theme resource see if their assigned theme has the default value defined and valid. + Control *theme_owner = p_theme_owner; + Window *theme_owner_window = p_theme_owner_window; - if (p_idx == 0) { - List<StringName> sn; - String pf = p_function; - if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") { - Theme::get_default()->get_color_list(get_class(), &sn); - } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") { - Theme::get_default()->get_stylebox_list(get_class(), &sn); - } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") { - Theme::get_default()->get_font_list(get_class(), &sn); - } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") { - Theme::get_default()->get_font_size_list(get_class(), &sn); - } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") { - Theme::get_default()->get_constant_list(get_class(), &sn); + while (theme_owner || theme_owner_window) { + if (theme_owner && theme_owner->data.theme->has_default_font_size()) { + return theme_owner->data.theme->get_default_font_size(); } - sn.sort_custom<StringName::AlphCompare>(); - for (const StringName &name : sn) { - r_options->push_back(String(name).quote()); + if (theme_owner_window && theme_owner_window->theme->has_default_font_size()) { + return theme_owner_window->theme->get_default_font_size(); + } + + Node *parent = theme_owner ? theme_owner->get_parent() : theme_owner_window->get_parent(); + Control *parent_c = Object::cast_to<Control>(parent); + if (parent_c) { + theme_owner = parent_c->data.theme_owner; + theme_owner_window = parent_c->data.theme_owner_window; + } else { + Window *parent_w = Object::cast_to<Window>(parent); + if (parent_w) { + theme_owner = parent_w->theme_owner; + theme_owner_window = parent_w->theme_owner_window; + } else { + theme_owner = nullptr; + theme_owner_window = nullptr; + } } } + + // Secondly, check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + if (Theme::get_project_default()->has_default_font_size()) { + return Theme::get_project_default()->get_default_font_size(); + } + } + + // Lastly, fall back on the default Theme. + if (Theme::get_default()->has_default_font_size()) { + return Theme::get_default()->get_default_font_size(); + } + return Theme::get_fallback_font_size(); } -TypedArray<String> Control::get_configuration_warnings() const { - TypedArray<String> warnings = Node::get_configuration_warnings(); +int Control::get_theme_default_font_size() const { + return fetch_theme_default_font_size(data.theme_owner, data.theme_owner_window); +} - if (data.mouse_filter == MOUSE_FILTER_IGNORE && !data.tooltip.is_empty()) { - warnings.push_back(RTR("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\".")); +/// Bulk actions. + +void Control::begin_bulk_theme_override() { + data.bulk_theme_override = true; +} + +void Control::end_bulk_theme_override() { + ERR_FAIL_COND(!data.bulk_theme_override); + + data.bulk_theme_override = false; + _notify_theme_changed(); +} + +// Internationalization. + +Array Control::structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const { + if (p_parser_type == TextServer::STRUCTURED_TEXT_CUSTOM) { + Array ret; + if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, ret)) { + return ret; + } else { + return Array(); + } + } else { + return TS->parse_structured_text(p_parser_type, p_args, p_text); } +} - return warnings; +void Control::set_layout_direction(Control::LayoutDirection p_direction) { + ERR_FAIL_INDEX((int)p_direction, 4); + + data.layout_dir = p_direction; + data.is_rtl_dirty = true; + + propagate_notification(NOTIFICATION_LAYOUT_DIRECTION_CHANGED); } -void Control::set_clip_contents(bool p_clip) { - data.clip_contents = p_clip; - update(); +Control::LayoutDirection Control::get_layout_direction() const { + return data.layout_dir; } -bool Control::is_clipping_contents() { - return data.clip_contents; +bool Control::is_layout_rtl() const { + if (data.is_rtl_dirty) { + const_cast<Control *>(this)->data.is_rtl_dirty = false; + if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) { + Window *parent_window = get_parent_window(); + Control *parent_control = get_parent_control(); + if (parent_control) { + const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl(); + } else if (parent_window) { + const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl(); + } else { + if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { + const_cast<Control *>(this)->data.is_rtl = true; + } else { + String locale = TranslationServer::get_singleton()->get_tool_locale(); + const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + } + } + } else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) { + if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) { + const_cast<Control *>(this)->data.is_rtl = true; + } else { + String locale = TranslationServer::get_singleton()->get_tool_locale(); + const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale); + } + } else { + const_cast<Control *>(this)->data.is_rtl = (data.layout_dir == LAYOUT_DIRECTION_RTL); + } + } + return data.is_rtl; } -void Control::set_h_grow_direction(GrowDirection p_direction) { - ERR_FAIL_INDEX((int)p_direction, 3); +void Control::set_auto_translate(bool p_enable) { + if (p_enable == data.auto_translate) { + return; + } - data.h_grow = p_direction; - _size_changed(); + data.auto_translate = p_enable; + + notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); } -Control::GrowDirection Control::get_h_grow_direction() const { - return data.h_grow; +bool Control::is_auto_translating() const { + return data.auto_translate; } -void Control::set_v_grow_direction(GrowDirection p_direction) { - ERR_FAIL_INDEX((int)p_direction, 3); +// Extra properties. - data.v_grow = p_direction; - _size_changed(); +void Control::set_tooltip(const String &p_tooltip) { + data.tooltip = p_tooltip; + update_configuration_warnings(); } -Control::GrowDirection Control::get_v_grow_direction() const { - return data.v_grow; +String Control::_get_tooltip() const { + return data.tooltip; +} + +String Control::get_tooltip(const Point2 &p_pos) const { + return data.tooltip; +} + +Control *Control::make_custom_tooltip(const String &p_text) const { + Object *ret = nullptr; + if (GDVIRTUAL_CALL(_make_custom_tooltip, p_text, ret)) { + return Object::cast_to<Control>(ret); + } + return nullptr; +} + +// Base object overrides. + +void Control::add_child_notify(Node *p_child) { + Control *child_c = Object::cast_to<Control>(p_child); + + if (child_c && child_c->data.theme.is_null() && (data.theme_owner || data.theme_owner_window)) { + _propagate_theme_changed(child_c, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff + } + + Window *child_w = Object::cast_to<Window>(p_child); + + if (child_w && child_w->theme.is_null() && (data.theme_owner || data.theme_owner_window)) { + _propagate_theme_changed(child_w, data.theme_owner, data.theme_owner_window); //need to propagate here, since many controls may require setting up stuff + } +} + +void Control::remove_child_notify(Node *p_child) { + Control *child_c = Object::cast_to<Control>(p_child); + + if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) { + _propagate_theme_changed(child_c, nullptr, nullptr); + } + + Window *child_w = Object::cast_to<Window>(p_child); + + if (child_w && (child_w->theme_owner || child_w->theme_owner_window) && child_w->theme.is_null()) { + _propagate_theme_changed(child_w, nullptr, nullptr); + } +} + +void Control::_notification(int p_notification) { + switch (p_notification) { + case NOTIFICATION_POST_ENTER_TREE: { + data.minimum_size_valid = false; + data.is_rtl_dirty = true; + _size_changed(); + } break; + + case NOTIFICATION_EXIT_TREE: { + release_focus(); + get_viewport()->_gui_remove_control(this); + } break; + + case NOTIFICATION_READY: { +#ifdef DEBUG_ENABLED + connect("ready", callable_mp(this, &Control::_clear_size_warning), varray(), CONNECT_DEFERRED | CONNECT_ONESHOT); +#endif + } break; + + case NOTIFICATION_ENTER_CANVAS: { + data.parent = Object::cast_to<Control>(get_parent()); + data.parent_window = Object::cast_to<Window>(get_parent()); + data.is_rtl_dirty = true; + + if (data.theme.is_null()) { + if (data.parent && (data.parent->data.theme_owner || data.parent->data.theme_owner_window)) { + data.theme_owner = data.parent->data.theme_owner; + data.theme_owner_window = data.parent->data.theme_owner_window; + notification(NOTIFICATION_THEME_CHANGED); + } else if (data.parent_window && (data.parent_window->theme_owner || data.parent_window->theme_owner_window)) { + data.theme_owner = data.parent_window->theme_owner; + data.theme_owner_window = data.parent_window->theme_owner_window; + notification(NOTIFICATION_THEME_CHANGED); + } + } + + CanvasItem *node = this; + bool has_parent_control = false; + + while (!node->is_set_as_top_level()) { + CanvasItem *parent = Object::cast_to<CanvasItem>(node->get_parent()); + if (!parent) { + break; + } + + Control *parent_control = Object::cast_to<Control>(parent); + if (parent_control) { + has_parent_control = true; + break; + } + + node = parent; + } + + if (has_parent_control) { + // Do nothing, has a parent control. + } else { + // Is a regular root control or top_level. + Viewport *viewport = get_viewport(); + ERR_FAIL_COND(!viewport); + data.RI = viewport->_gui_add_root_control(this); + } + + data.parent_canvas_item = get_parent_item(); + + if (data.parent_canvas_item) { + data.parent_canvas_item->connect("item_rect_changed", callable_mp(this, &Control::_size_changed)); + } else { + // Connect viewport. + Viewport *viewport = get_viewport(); + ERR_FAIL_COND(!viewport); + viewport->connect("size_changed", callable_mp(this, &Control::_size_changed)); + } + } break; + + case NOTIFICATION_EXIT_CANVAS: { + if (data.parent_canvas_item) { + data.parent_canvas_item->disconnect("item_rect_changed", callable_mp(this, &Control::_size_changed)); + data.parent_canvas_item = nullptr; + } else if (!is_set_as_top_level()) { + //disconnect viewport + Viewport *viewport = get_viewport(); + ERR_FAIL_COND(!viewport); + viewport->disconnect("size_changed", callable_mp(this, &Control::_size_changed)); + } + + if (data.RI) { + get_viewport()->_gui_remove_root_control(data.RI); + data.RI = nullptr; + } + + data.parent = nullptr; + data.parent_canvas_item = nullptr; + data.parent_window = nullptr; + data.is_rtl_dirty = true; + } break; + + case NOTIFICATION_MOVED_IN_PARENT: { + // some parents need to know the order of the children to draw (like TabContainer) + // update if necessary + if (data.parent) { + data.parent->update(); + } + update(); + + if (data.RI) { + get_viewport()->_gui_set_root_order_dirty(); + } + } break; + + case NOTIFICATION_RESIZED: { + emit_signal(SceneStringNames::get_singleton()->resized); + } break; + + case NOTIFICATION_DRAW: { + _update_canvas_item_transform(); + RenderingServer::get_singleton()->canvas_item_set_custom_rect(get_canvas_item(), !data.disable_visibility_clip, Rect2(Point2(), get_size())); + RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), data.clip_contents); + } break; + + case NOTIFICATION_MOUSE_ENTER: { + emit_signal(SceneStringNames::get_singleton()->mouse_entered); + } break; + + case NOTIFICATION_MOUSE_EXIT: { + emit_signal(SceneStringNames::get_singleton()->mouse_exited); + } break; + + case NOTIFICATION_FOCUS_ENTER: { + emit_signal(SceneStringNames::get_singleton()->focus_entered); + update(); + } break; + + case NOTIFICATION_FOCUS_EXIT: { + emit_signal(SceneStringNames::get_singleton()->focus_exited); + update(); + } break; + + case NOTIFICATION_THEME_CHANGED: { + update_minimum_size(); + update(); + } break; + + case NOTIFICATION_VISIBILITY_CHANGED: { + if (!is_visible_in_tree()) { + if (get_viewport() != nullptr) { + get_viewport()->_gui_hide_control(this); + } + } else { + data.minimum_size_valid = false; + _update_minimum_size(); + _size_changed(); + } + } break; + + case NOTIFICATION_TRANSLATION_CHANGED: + case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { + if (is_inside_tree()) { + data.is_rtl_dirty = true; + _size_changed(); + } + } break; + } } void Control::_bind_methods() { - //ClassDB::bind_method(D_METHOD("_window_resize_event"),&Control::_window_resize_event); ClassDB::bind_method(D_METHOD("_update_minimum_size"), &Control::_update_minimum_size); ClassDB::bind_method(D_METHOD("accept_event"), &Control::accept_event); @@ -3300,7 +3343,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode"); ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION); - const String anchors_presets_options = "Custom:-1,PresetWide:15," + const String anchors_presets_options = "Custom:-1,PresetFullRect:15," "PresetTopLeft:0,PresetTopRight:1,PresetBottomRight:3,PresetBottomLeft:2," "PresetCenterLeft:4,PresetCenterTop:5,PresetCenterRight:6,PresetCenterBottom:7,PresetCenter:8," "PresetLeftWide:9,PresetTopWide:10,PresetRightWide:11,PresetBottomWide:12,PresetVCenterWide:13,PresetHCenterWide:14"; diff --git a/scene/gui/control.h b/scene/gui/control.h index 50cf9faeed..9f17eccc3b 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -159,13 +159,16 @@ private: }; struct Data { - Point2 pos_cache; - Size2 size_cache; - Size2 minimum_size_cache; - bool minimum_size_valid = false; + // Global relations. - Size2 last_minimum_size; - bool updating_last_minimum_size = false; + List<Control *>::Element *RI = nullptr; + + Control *parent = nullptr; + Window *parent_window = nullptr; + CanvasItem *parent_canvas_item = nullptr; + ObjectID drag_owner; + + // Positioning and sizing. real_t offset[4] = { 0.0, 0.0, 0.0, 0.0 }; real_t anchor[4] = { ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN }; @@ -173,49 +176,51 @@ private: GrowDirection h_grow = GROW_DIRECTION_END; GrowDirection v_grow = GROW_DIRECTION_END; - LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; - bool is_rtl_dirty = true; - bool is_rtl = false; - - bool auto_translate = true; - real_t rotation = 0.0; Vector2 scale = Vector2(1, 1); Vector2 pivot_offset; + + Point2 pos_cache; + Size2 size_cache; + Size2 minimum_size_cache; + bool minimum_size_valid = false; + + Size2 last_minimum_size; + bool updating_last_minimum_size = false; + bool block_minimum_size_adjust = false; + bool size_warning = true; + // Container sizing. + int h_size_flags = SIZE_FILL; int v_size_flags = SIZE_FILL; real_t expand = 1.0; Point2 custom_minimum_size; + // Input events and rendering. + MouseFilter mouse_filter = MOUSE_FILTER_STOP; bool force_pass_scroll_events = true; bool clip_contents = false; - - bool block_minimum_size_adjust = false; bool disable_visibility_clip = false; - Control *parent = nullptr; - ObjectID drag_owner; - Ref<Theme> theme; - Control *theme_owner = nullptr; - Window *theme_owner_window = nullptr; - Window *parent_window = nullptr; - StringName theme_type_variation; - - String tooltip; CursorShape default_cursor = CURSOR_ARROW; - List<Control *>::Element *RI = nullptr; - - CanvasItem *parent_canvas_item = nullptr; + // Focus. NodePath focus_neighbor[4]; NodePath focus_next; NodePath focus_prev; + // Theming. + + Ref<Theme> theme; + Control *theme_owner = nullptr; + Window *theme_owner_window = nullptr; + StringName theme_type_variation; + bool bulk_theme_override = false; Theme::ThemeIconMap icon_override; Theme::ThemeStyleMap style_override; @@ -224,50 +229,69 @@ private: Theme::ThemeColorMap color_override; Theme::ThemeConstantMap constant_override; + // Internationalization. + + LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; + bool is_rtl_dirty = true; + bool is_rtl = false; + + bool auto_translate = true; + + // Extra properties. + + String tooltip; + } data; + // Dynamic properties. + static constexpr unsigned properties_managed_by_container_count = 12; static String properties_managed_by_container[properties_managed_by_container_count]; - void _window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest); - Control *_get_focus_neighbor(Side p_side, int p_count = 0); + // Global relations. + + friend class Viewport; + friend class Window; + + // Positioning and sizing. + + void _update_canvas_item_transform(); + Transform2D _get_internal_transform() const; void _set_anchor(Side p_side, real_t p_anchor); void _set_position(const Point2 &p_point); void _set_global_position(const Point2 &p_point); void _set_size(const Size2 &p_size); + void _compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]); + void _compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]); + void _set_layout_mode(LayoutMode p_mode); LayoutMode _get_layout_mode() const; - void _set_anchors_layout_preset(int p_preset); int _get_anchors_layout_preset() const; - void _theme_changed(); - void _notify_theme_changed(); - + void _update_minimum_size_cache(); void _update_minimum_size(); + void _size_changed(); void _clear_size_warning(); - void _compute_offsets(Rect2 p_rect, const real_t p_anchors[4], real_t (&r_offsets)[4]); - void _compute_anchors(Rect2 p_rect, const real_t p_offsets[4], real_t (&r_anchors)[4]); - - void _size_changed(); - String _get_tooltip() const; + // Input events. - void _override_changed(); + void _call_gui_input(const Ref<InputEvent> &p_event); - void _update_canvas_item_transform(); + // Focus. - Transform2D _get_internal_transform() const; + void _window_find_focus_neighbor(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, real_t p_min, real_t &r_closest_dist, Control **r_closest); + Control *_get_focus_neighbor(Side p_side, int p_count = 0); - friend class Viewport; + // Theming. - void _call_gui_input(const Ref<InputEvent> &p_event); + void _theme_changed(); + void _theme_property_override_changed(); + void _notify_theme_changed(); - void _update_minimum_size_cache(); - friend class Window; static void _propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign = true); template <class T> @@ -275,24 +299,31 @@ private: static bool has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types); _FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const; -protected: - virtual void add_child_notify(Node *p_child) override; - virtual void remove_child_notify(Node *p_child) override; + // Extra properties. - //virtual void _window_gui_input(InputEvent p_event); + String _get_tooltip() const; - virtual Array structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; +protected: + // Dynamic properties. 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 _validate_property(PropertyInfo &property) const override; + // Internationalization. + + virtual Array structured_text_parser(TextServer::StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const; + + // Base object overrides. + + virtual void add_child_notify(Node *p_child) override; + virtual void remove_child_notify(Node *p_child) override; + void _notification(int p_notification); static void _bind_methods(); - //bind helpers + // Exposed virtual methods. GDVIRTUAL1RC(bool, _has_point, Vector2) GDVIRTUAL2RC(Array, _structured_text_parser, Array, String) @@ -307,8 +338,6 @@ protected: public: enum { - /* NOTIFICATION_DRAW=30, - NOTIFICATION_VISIBILITY_CHANGED=38*/ NOTIFICATION_RESIZED = 40, NOTIFICATION_MOUSE_ENTER = 41, NOTIFICATION_MOUSE_EXIT = 42, @@ -318,10 +347,11 @@ public: NOTIFICATION_SCROLL_BEGIN = 47, NOTIFICATION_SCROLL_END = 48, NOTIFICATION_LAYOUT_DIRECTION_CHANGED = 49, - }; - /* EDITOR */ + // Editor plugin interoperability. + + // TODO: Decouple controls from their editor plugin and get rid of this. #ifdef TOOLS_ENABLED virtual Dictionary _edit_get_state() const override; virtual void _edit_set_state(const Dictionary &p_state) override; @@ -347,56 +377,50 @@ public: virtual Size2 _edit_get_minimum_size() const override; #endif - virtual void gui_input(const Ref<InputEvent> &p_event); + // Editor integration. - void accept_event(); + virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; + TypedArray<String> get_configuration_warnings() const override; - virtual Size2 get_minimum_size() const; - virtual Size2 get_combined_minimum_size() const; - virtual bool has_point(const Point2 &p_point) const; - virtual void set_drag_forwarding(Object *p_target); - virtual Variant get_drag_data(const Point2 &p_point); - virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const; - virtual void drop_data(const Point2 &p_point, const Variant &p_data); - void set_drag_preview(Control *p_control); - void force_drag(const Variant &p_data, Control *p_control); - bool is_drag_successful() const; + virtual bool is_text_field() const; - void set_custom_minimum_size(const Size2 &p_custom); - Size2 get_custom_minimum_size() const; + // Global relations. + + bool is_top_level_control() const; Control *get_parent_control() const; Window *get_parent_window() const; + Control *get_root_parent_control() const; - void set_layout_direction(LayoutDirection p_direction); - LayoutDirection get_layout_direction() const; - virtual bool is_layout_rtl() const; - - void set_auto_translate(bool p_enable); - bool is_auto_translating() const; - _FORCE_INLINE_ String atr(const String p_string) const { return is_auto_translating() ? tr(p_string) : p_string; }; + Size2 get_parent_area_size() const; + Rect2 get_parent_anchorable_rect() const; - /* POSITIONING */ + // Positioning and sizing. - void set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets = true); - void set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0); - void set_anchors_and_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0); - void set_grow_direction_preset(LayoutPreset p_preset); + virtual Transform2D get_transform() const override; void set_anchor(Side p_side, real_t p_anchor, bool p_keep_offset = true, bool p_push_opposite_anchor = true); real_t get_anchor(Side p_side) const; - void set_offset(Side p_side, real_t p_value); real_t get_offset(Side p_side) const; - void set_anchor_and_offset(Side p_side, real_t p_anchor, real_t p_pos, bool p_push_opposite_anchor = true); - void set_begin(const Point2 &p_point); // helper - void set_end(const Point2 &p_point); // helper - + // TODO: Rename to set_begin/end_offsets ? + void set_begin(const Point2 &p_point); Point2 get_begin() const; + void set_end(const Point2 &p_point); Point2 get_end() const; + void set_h_grow_direction(GrowDirection p_direction); + GrowDirection get_h_grow_direction() const; + void set_v_grow_direction(GrowDirection p_direction); + GrowDirection get_v_grow_direction() const; + + void set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets = true); + void set_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0); + void set_anchors_and_offsets_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode = PRESET_MODE_MINSIZE, int p_margin = 0); + void set_grow_direction_preset(LayoutPreset p_preset); + void set_position(const Point2 &p_point, bool p_keep_offsets = false); void set_global_position(const Point2 &p_point, bool p_keep_offsets = false); Point2 get_position() const; @@ -407,52 +431,72 @@ public: Size2 get_size() const; void reset_size(); + void set_rect(const Rect2 &p_rect); // Reset anchors to begin and set rect, for faster container children sorting. Rect2 get_rect() const; Rect2 get_global_rect() const; Rect2 get_screen_rect() const; Rect2 get_window_rect() const; ///< use with care, as it blocks waiting for the rendering server Rect2 get_anchorable_rect() const override; - void set_rect(const Rect2 &p_rect); // Reset anchors to begin and set rect, for faster container children sorting. - + void set_scale(const Vector2 &p_scale); + Vector2 get_scale() const; void set_rotation(real_t p_radians); real_t get_rotation() const; - - void set_h_grow_direction(GrowDirection p_direction); - GrowDirection get_h_grow_direction() const; - - void set_v_grow_direction(GrowDirection p_direction); - GrowDirection get_v_grow_direction() const; - void set_pivot_offset(const Vector2 &p_pivot); Vector2 get_pivot_offset() const; - void set_scale(const Vector2 &p_scale); - Vector2 get_scale() const; + void update_minimum_size(); - void set_theme(const Ref<Theme> &p_theme); - Ref<Theme> get_theme() const; + void set_block_minimum_size_adjust(bool p_block); + bool is_minimum_size_adjust_blocked() const; - void set_theme_type_variation(const StringName &p_theme_type); - StringName get_theme_type_variation() const; + virtual Size2 get_minimum_size() const; + virtual Size2 get_combined_minimum_size() const; + + void set_custom_minimum_size(const Size2 &p_custom); + Size2 get_custom_minimum_size() const; + + // Container sizing. void set_h_size_flags(int p_flags); int get_h_size_flags() const; - void set_v_size_flags(int p_flags); int get_v_size_flags() const; - void set_stretch_ratio(real_t p_ratio); real_t get_stretch_ratio() const; - void update_minimum_size(); + // Input events. + + virtual void gui_input(const Ref<InputEvent> &p_event); + void accept_event(); + + virtual bool has_point(const Point2 &p_point) const; + + void set_mouse_filter(MouseFilter p_filter); + MouseFilter get_mouse_filter() const; + + void set_force_pass_scroll_events(bool p_force_pass_scroll_events); + bool is_force_pass_scroll_events() const; + + void warp_mouse(const Point2 &p_position); + + // Drag and drop handling. + + virtual void set_drag_forwarding(Object *p_target); + virtual Variant get_drag_data(const Point2 &p_point); + virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const; + virtual void drop_data(const Point2 &p_point, const Variant &p_data); + void set_drag_preview(Control *p_control); + void force_drag(const Variant &p_data, Control *p_control); + bool is_drag_successful() const; - /* FOCUS */ + // Focus. void set_focus_mode(FocusMode p_focus_mode); FocusMode get_focus_mode() const; bool has_focus() const; void grab_focus(); + void grab_click_focus(); void release_focus(); Control *find_next_valid_focus() const; @@ -466,13 +510,25 @@ public: void set_focus_previous(const NodePath &p_prev); NodePath get_focus_previous() const; - void set_mouse_filter(MouseFilter p_filter); - MouseFilter get_mouse_filter() const; + // Rendering. - void set_force_pass_scroll_events(bool p_force_pass_scroll_events); - bool is_force_pass_scroll_events() const; + void set_default_cursor_shape(CursorShape p_shape); + CursorShape get_default_cursor_shape() const; + virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const; + + void set_clip_contents(bool p_clip); + bool is_clipping_contents(); - /* SKINNING */ + void set_disable_visibility_clip(bool p_ignore); + bool is_visibility_clip_disabled() const; + + // Theming. + + void set_theme(const Ref<Theme> &p_theme); + Ref<Theme> get_theme() const; + + void set_theme_type_variation(const StringName &p_theme_type); + StringName get_theme_type_variation() const; void begin_bulk_theme_override(); void end_bulk_theme_override(); @@ -520,44 +576,23 @@ public: Ref<Font> get_theme_default_font() const; int get_theme_default_font_size() const; - /* TOOLTIP */ - - void set_tooltip(const String &p_tooltip); - virtual String get_tooltip(const Point2 &p_pos) const; - virtual Control *make_custom_tooltip(const String &p_text) const; - - /* CURSOR */ - - void set_default_cursor_shape(CursorShape p_shape); - CursorShape get_default_cursor_shape() const; - virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const; - - virtual Transform2D get_transform() const override; - - bool is_top_level_control() const; + // Internationalization. - Size2 get_parent_area_size() const; - Rect2 get_parent_anchorable_rect() const; - - void grab_click_focus(); - - void warp_mouse(const Point2 &p_position); - - virtual bool is_text_field() const; - - Control *get_root_parent_control() const; - - void set_clip_contents(bool p_clip); - bool is_clipping_contents(); + void set_layout_direction(LayoutDirection p_direction); + LayoutDirection get_layout_direction() const; + virtual bool is_layout_rtl() const; - void set_block_minimum_size_adjust(bool p_block); - bool is_minimum_size_adjust_blocked() const; + void set_auto_translate(bool p_enable); + bool is_auto_translating() const; + _FORCE_INLINE_ String atr(const String p_string) const { + return is_auto_translating() ? tr(p_string) : p_string; + }; - void set_disable_visibility_clip(bool p_ignore); - bool is_visibility_clip_disabled() const; + // Extra properties. - virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; - TypedArray<String> get_configuration_warnings() const override; + void set_tooltip(const String &p_tooltip); + virtual String get_tooltip(const Point2 &p_pos) const; + virtual Control *make_custom_tooltip(const String &p_text) const; Control() {} }; @@ -574,4 +609,4 @@ VARIANT_ENUM_CAST(Control::LayoutMode); VARIANT_ENUM_CAST(Control::LayoutDirection); VARIANT_ENUM_CAST(Control::TextDirection); -#endif +#endif // CONTROL_H diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 711361de88..9ebf5ddfb2 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -120,4 +120,4 @@ public: ConfirmationDialog(); }; -#endif +#endif // DIALOGS_H diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 017c9d8d4f..4945094086 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -196,4 +196,4 @@ public: VARIANT_ENUM_CAST(FileDialog::FileMode); VARIANT_ENUM_CAST(FileDialog::Access); -#endif +#endif // FILE_DIALOG_H diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index 9459bed63b..cc27a6b7c2 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -437,6 +437,10 @@ ColorPicker *GradientEdit::get_picker() { return picker; } +PopupPanel *GradientEdit::get_popup() { + return popup; +} + void GradientEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("ramp_changed")); } diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index 3badcd45ba..b7c99f1f1c 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -75,6 +75,7 @@ public: void set_interpolation_mode(Gradient::InterpolationMode p_interp_mode); Gradient::InterpolationMode get_interpolation_mode(); ColorPicker *get_picker(); + PopupPanel *get_popup(); virtual Size2 get_minimum_size() const override; diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 02e90e4717..beb17ec4cf 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -365,4 +365,4 @@ public: VARIANT_ENUM_CAST(GraphEdit::PanningScheme); -#endif // GRAPHEdit_H +#endif // GRAPH_EDIT_H diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index c7d87da0b5..21bd22759c 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef ITEMLIST_H -#define ITEMLIST_H +#ifndef ITEM_LIST_H +#define ITEM_LIST_H #include "scene/gui/control.h" #include "scene/gui/scroll_bar.h" @@ -259,4 +259,4 @@ public: VARIANT_ENUM_CAST(ItemList::SelectMode); VARIANT_ENUM_CAST(ItemList::IconMode); -#endif // ITEMLIST_H +#endif // ITEM_LIST_H diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 84f2ddf700..8094812203 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -31,6 +31,7 @@ #include "label.h" #include "core/config/project_settings.h" +#include "core/core_string_names.h" #include "core/string/print_string.h" #include "core/string/translation.h" @@ -64,7 +65,7 @@ bool Label::is_uppercase() const { } int Label::get_line_height(int p_line) const { - Ref<Font> font = get_theme_font(SNAME("font")); + Ref<Font> font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); if (p_line >= 0 && p_line < lines_rid.size()) { return TS->shaped_text_get_size(lines_rid[p_line]).y; } else if (lines_rid.size() > 0) { @@ -74,7 +75,8 @@ int Label::get_line_height(int p_line) const { } return h; } else { - return font->get_height(get_theme_font_size(SNAME("font_size"))); + int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); + return font->get_height(font_size); } } @@ -91,8 +93,8 @@ void Label::_shape() { } else { TS->shaped_text_set_direction(text_rid, (TextServer::Direction)text_direction); } - const Ref<Font> &font = get_theme_font(SNAME("font")); - int font_size = get_theme_font_size(SNAME("font_size")); + const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); + int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); ERR_FAIL_COND(font.is_null()); String text = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text; if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { @@ -223,9 +225,8 @@ void Label::_shape() { } void Label::_update_visible() { - int line_spacing = get_theme_constant(SNAME("line_spacing"), SNAME("Label")); + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing"), SNAME("Label")); Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label")); - Ref<Font> font = get_theme_font(SNAME("font")); int lines_visible = lines_rid.size(); if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { @@ -295,17 +296,19 @@ void Label::_notification(int p_what) { RID ci = get_canvas_item(); + bool has_settings = settings.is_valid(); + Size2 string_size; Size2 size = get_size(); Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - Ref<Font> font = get_theme_font(SNAME("font")); - Color font_color = get_theme_color(SNAME("font_color")); - Color font_shadow_color = get_theme_color(SNAME("font_shadow_color")); - Point2 shadow_ofs(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y"))); - int line_spacing = get_theme_constant(SNAME("line_spacing")); - Color font_outline_color = get_theme_color(SNAME("font_outline_color")); - int outline_size = get_theme_constant(SNAME("outline_size")); - int shadow_outline_size = get_theme_constant(SNAME("shadow_outline_size")); + Ref<Font> font = (has_settings && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); + Color font_color = has_settings ? settings->get_font_color() : get_theme_color(SNAME("font_color")); + Color font_shadow_color = has_settings ? settings->get_shadow_color() : get_theme_color(SNAME("font_shadow_color")); + Point2 shadow_ofs = has_settings ? settings->get_shadow_offset() : Point2(get_theme_constant(SNAME("shadow_offset_x")), get_theme_constant(SNAME("shadow_offset_y"))); + int line_spacing = has_settings ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing")); + Color font_outline_color = has_settings ? settings->get_outline_color() : get_theme_color(SNAME("font_outline_color")); + int outline_size = has_settings ? settings->get_outline_size() : get_theme_constant(SNAME("outline_size")); + int shadow_outline_size = has_settings ? settings->get_shadow_size() : get_theme_constant(SNAME("shadow_outline_size")); bool rtl = (TS->shaped_text_get_inferred_direction(text_rid) == TextServer::DIRECTION_RTL); bool rtl_layout = is_layout_rtl(); @@ -552,8 +555,10 @@ Size2 Label::get_minimum_size() const { Size2 min_size = minsize; - Ref<Font> font = get_theme_font(SNAME("font")); - min_size.height = MAX(min_size.height, font->get_height(get_theme_font_size(SNAME("font_size")))); + const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : get_theme_font(SNAME("font")); + int font_size = settings.is_valid() ? settings->get_font_size() : get_theme_font_size(SNAME("font_size")); + + min_size.height = MAX(min_size.height, font->get_height(font_size) + font->get_spacing(TextServer::SPACING_TOP) + font->get_spacing(TextServer::SPACING_BOTTOM)); Size2 min_style = get_theme_stylebox(SNAME("normal"))->get_minimum_size(); if (autowrap_mode != TextServer::AUTOWRAP_OFF) { @@ -578,9 +583,8 @@ int Label::get_line_count() const { } int Label::get_visible_line_count() const { - Ref<Font> font = get_theme_font(SNAME("font")); Ref<StyleBox> style = get_theme_stylebox(SNAME("normal")); - int line_spacing = get_theme_constant(SNAME("line_spacing")); + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : get_theme_constant(SNAME("line_spacing")); int lines_visible = 0; float total_h = 0.0; for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { @@ -641,6 +645,28 @@ void Label::set_text(const String &p_string) { update_minimum_size(); } +void Label::_invalidate() { + font_dirty = true; + update(); +} + +void Label::set_label_settings(const Ref<LabelSettings> &p_settings) { + if (settings != p_settings) { + if (settings.is_valid()) { + settings->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate)); + } + settings = p_settings; + if (settings.is_valid()) { + settings->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Label::_invalidate), varray(), CONNECT_REFERENCE_COUNTED); + } + _invalidate(); + } +} + +Ref<LabelSettings> Label::get_label_settings() const { + return settings; +} + void Label::set_text_direction(Control::TextDirection p_text_direction) { ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3); if (text_direction != p_text_direction) { @@ -804,6 +830,8 @@ void Label::_bind_methods() { ClassDB::bind_method(D_METHOD("get_vertical_alignment"), &Label::get_vertical_alignment); ClassDB::bind_method(D_METHOD("set_text", "text"), &Label::set_text); ClassDB::bind_method(D_METHOD("get_text"), &Label::get_text); + ClassDB::bind_method(D_METHOD("set_label_settings", "settings"), &Label::set_label_settings); + ClassDB::bind_method(D_METHOD("get_label_settings"), &Label::get_label_settings); ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &Label::set_text_direction); ClassDB::bind_method(D_METHOD("get_text_direction"), &Label::get_text_direction); ClassDB::bind_method(D_METHOD("set_language", "language"), &Label::set_language); @@ -836,6 +864,7 @@ void Label::_bind_methods() { ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override_options"), &Label::get_structured_text_bidi_override_options); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "label_settings", PROPERTY_HINT_RESOURCE_TYPE, "LabelSettings"), "set_label_settings", "get_label_settings"); ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment"); ADD_PROPERTY(PropertyInfo(Variant::INT, "vertical_alignment", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_vertical_alignment", "get_vertical_alignment"); ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode"); diff --git a/scene/gui/label.h b/scene/gui/label.h index a59d35950d..cab5b36d68 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -32,6 +32,7 @@ #define LABEL_H #include "scene/gui/control.h" +#include "scene/resources/label_settings.h" class Label : public Control { GDCLASS(Label, Control); @@ -65,8 +66,11 @@ private: int lines_skipped = 0; int max_lines_visible = -1; + Ref<LabelSettings> settings; + void _update_visible(); void _shape(); + void _invalidate(); protected: void _notification(int p_what); @@ -85,6 +89,9 @@ public: void set_text(const String &p_string); String get_text() const; + void set_label_settings(const Ref<LabelSettings> &p_settings); + Ref<LabelSettings> get_label_settings() const; + void set_text_direction(TextDirection p_text_direction); TextDirection get_text_direction() const; @@ -133,4 +140,4 @@ public: ~Label(); }; -#endif +#endif // LABEL_H diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 557da35bfd..6aa1694f1f 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -336,4 +336,4 @@ public: VARIANT_ENUM_CAST(LineEdit::MenuItems); -#endif +#endif // LINE_EDIT_H diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index 54a31f06ce..12a6a7618f 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LINKBUTTON_H -#define LINKBUTTON_H +#ifndef LINK_BUTTON_H +#define LINK_BUTTON_H #include "scene/gui/base_button.h" #include "scene/resources/text_line.h" @@ -86,4 +86,4 @@ public: VARIANT_ENUM_CAST(LinkButton::UnderlineMode); -#endif // LINKBUTTON_H +#endif // LINK_BUTTON_H diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h index 0a6b46c796..97c0d21f1e 100644 --- a/scene/gui/menu_button.h +++ b/scene/gui/menu_button.h @@ -71,4 +71,4 @@ public: ~MenuButton(); }; -#endif +#endif // MENU_BUTTON_H diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 7896132626..5665296699 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -105,4 +105,4 @@ public: ~OptionButton(); }; -#endif +#endif // OPTION_BUTTON_H diff --git a/scene/gui/popup.h b/scene/gui/popup.h index b53c8be50f..70eb8722d0 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -79,4 +79,4 @@ public: PopupPanel(); }; -#endif +#endif // POPUP_H diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index daa38b0e6d..e203793c2e 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -260,4 +260,4 @@ public: ~PopupMenu(); }; -#endif +#endif // POPUP_MENU_H diff --git a/scene/gui/range.h b/scene/gui/range.h index 1274821bd1..87bd0d88af 100644 --- a/scene/gui/range.h +++ b/scene/gui/range.h @@ -106,4 +106,4 @@ public: ~Range(); }; -#endif +#endif // RANGE_H diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 94e0944628..8e424977c4 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -224,13 +224,21 @@ void RichTextLabel::_update_line_font(ItemFrame *p_frame, int p_line, const Ref< for (int i = 0; i < spans; i++) { ItemText *it = reinterpret_cast<ItemText *>((uint64_t)TS->shaped_get_span_meta(t, i)); if (it) { - Ref<Font> font = _find_font(it); - if (font.is_null()) { - font = p_base_font; + Ref<Font> font = p_base_font; + int font_size = p_base_font_size; + + ItemFont *font_it = _find_font(it); + if (font_it) { + if (font_it->font.is_valid()) { + font = font_it->font; + } + if (font_it->font_size > 0) { + font_size = font_it->font_size; + } } - int font_size = _find_font_size(it); - if (font_size == -1) { - font_size = p_base_font_size; + ItemFontSize *font_size_it = _find_font_size(it); + if (font_size_it && font_size_it->font_size > 0) { + font_size = font_size_it->font_size; } TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font->get_opentype_features()); for (int j = 0; j < TextServer::SPACING_MAX; j++) { @@ -483,13 +491,21 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> l.dc_ol_color = dc->ol_color; } break; case ITEM_NEWLINE: { - Ref<Font> font = _find_font(it); - if (font.is_null()) { - font = p_base_font; + Ref<Font> font = p_base_font; + int font_size = p_base_font_size; + + ItemFont *font_it = _find_font(it); + if (font_it) { + if (font_it->font.is_valid()) { + font = font_it->font; + } + if (font_it->font_size > 0) { + font_size = font_it->font_size; + } } - int font_size = _find_font_size(it); - if (font_size == -1) { - font_size = p_base_font_size; + ItemFontSize *font_size_it = _find_font_size(it); + if (font_size_it && font_size_it->font_size > 0) { + font_size = font_size_it->font_size; } l.text_buf->add_string("\n", font, font_size); text += "\n"; @@ -498,13 +514,21 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> } break; case ITEM_TEXT: { ItemText *t = static_cast<ItemText *>(it); - Ref<Font> font = _find_font(it); - if (font.is_null()) { - font = p_base_font; + Ref<Font> font = p_base_font; + int font_size = p_base_font_size; + + ItemFont *font_it = _find_font(it); + if (font_it) { + if (font_it->font.is_valid()) { + font = font_it->font; + } + if (font_it->font_size > 0) { + font_size = font_it->font_size; + } } - int font_size = _find_font_size(it); - if (font_size == -1) { - font_size = p_base_font_size; + ItemFontSize *font_size_it = _find_font_size(it); + if (font_size_it && font_size_it->font_size > 0) { + font_size = font_size_it->font_size; } String lang = _find_language(it); String tx = t->text; @@ -750,13 +774,21 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } } if (!prefix.is_empty()) { - Ref<Font> font = _find_font(l.from); - if (font.is_null()) { - font = get_theme_font(SNAME("normal_font")); + Ref<Font> font = get_theme_font(SNAME("normal_font")); + int font_size = get_theme_font_size(SNAME("normal_font_size")); + + ItemFont *font_it = _find_font(l.from); + if (font_it) { + if (font_it->font.is_valid()) { + font = font_it->font; + } + if (font_it->font_size > 0) { + font_size = font_it->font_size; + } } - int font_size = _find_font_size(l.from); - if (font_size == -1) { - font_size = get_theme_font_size(SNAME("normal_font_size")); + ItemFontSize *font_size_it = _find_font_size(l.from); + if (font_size_it && font_size_it->font_size > 0) { + font_size = font_size_it->font_size; } if (rtl) { float offx = 0.0f; @@ -1519,13 +1551,20 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V int stop = text_rect_begin; *r_click_item = _find_indentable(it); while (*r_click_item) { - Ref<Font> font = _find_font(*r_click_item); - if (!font.is_valid()) { - font = get_theme_font(SNAME("normal_font")); + Ref<Font> font = get_theme_font(SNAME("normal_font")); + int font_size = get_theme_font_size(SNAME("normal_font_size")); + ItemFont *font_it = _find_font(*r_click_item); + if (font_it) { + if (font_it->font.is_valid()) { + font = font_it->font; + } + if (font_it->font_size > 0) { + font_size = font_it->font_size; + } } - int font_size = _find_font_size(*r_click_item); - if (font_size == -1) { - font_size = get_theme_font_size(SNAME("normal_font_size")); + ItemFontSize *font_size_it = _find_font_size(*r_click_item); + if (font_size_it && font_size_it->font_size > 0) { + font_size = font_size_it->font_size; } if (rtl) { stop += tab_size * font->get_char_size(' ', font_size).width; @@ -2109,34 +2148,34 @@ RichTextLabel::Item *RichTextLabel::_find_indentable(Item *p_item) { return indentable; } -Ref<Font> RichTextLabel::_find_font(Item *p_item) { +RichTextLabel::ItemFont *RichTextLabel::_find_font(Item *p_item) { Item *fontitem = p_item; while (fontitem) { if (fontitem->type == ITEM_FONT) { ItemFont *fi = static_cast<ItemFont *>(fontitem); - return fi->font; + return fi; } fontitem = fontitem->parent; } - return Ref<Font>(); + return nullptr; } -int RichTextLabel::_find_font_size(Item *p_item) { +RichTextLabel::ItemFontSize *RichTextLabel::_find_font_size(Item *p_item) { Item *sizeitem = p_item; while (sizeitem) { if (sizeitem->type == ITEM_FONT_SIZE) { ItemFontSize *fi = static_cast<ItemFontSize *>(sizeitem); - return fi->font_size; + return fi; } sizeitem = sizeitem->parent; } - return -1; + return nullptr; } int RichTextLabel::_find_outline_size(Item *p_item, int p_default) { @@ -2222,24 +2261,40 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font, int while (item) { if (item->type == ITEM_INDENT) { - Ref<Font> font = _find_font(item); - if (font.is_null()) { - font = p_base_font; + Ref<Font> font = p_base_font; + int font_size = p_base_font_size; + + ItemFont *font_it = _find_font(item); + if (font_it) { + if (font_it->font.is_valid()) { + font = font_it->font; + } + if (font_it->font_size > 0) { + font_size = font_it->font_size; + } } - int font_size = _find_font_size(item); - if (font_size == -1) { - font_size = p_base_font_size; + ItemFontSize *font_size_it = _find_font_size(item); + if (font_size_it && font_size_it->font_size > 0) { + font_size = font_size_it->font_size; } margin += tab_size * font->get_char_size(' ', font_size).width; } else if (item->type == ITEM_LIST) { - Ref<Font> font = _find_font(item); - if (font.is_null()) { - font = p_base_font; + Ref<Font> font = p_base_font; + int font_size = p_base_font_size; + + ItemFont *font_it = _find_font(item); + if (font_it) { + if (font_it->font.is_valid()) { + font = font_it->font; + } + if (font_it->font_size > 0) { + font_size = font_it->font_size; + } } - int font_size = _find_font_size(item); - if (font_size == -1) { - font_size = p_base_font_size; + ItemFontSize *font_size_it = _find_font_size(item); + if (font_size_it && font_size_it->font_size > 0) { + font_size = font_size_it->font_size; } margin += tab_size * font->get_char_size(' ', font_size).width; } @@ -2918,7 +2973,7 @@ void RichTextLabel::push_dropcap(const String &p_string, const Ref<Font> &p_font _add_item(item, false); } -void RichTextLabel::push_font(const Ref<Font> &p_font) { +void RichTextLabel::push_font(const Ref<Font> &p_font, int p_size) { _stop_thread(); MutexLock data_lock(data_mutex); @@ -2927,6 +2982,7 @@ void RichTextLabel::push_font(const Ref<Font> &p_font) { ItemFont *item = memnew(ItemFont); item->font = p_font; + item->font_size = p_size; _add_item(item, true); } @@ -2934,35 +2990,35 @@ void RichTextLabel::push_normal() { Ref<Font> normal_font = get_theme_font(SNAME("normal_font")); ERR_FAIL_COND(normal_font.is_null()); - push_font(normal_font); + push_font(normal_font, get_theme_font_size(SNAME("normal_font_size"))); } void RichTextLabel::push_bold() { Ref<Font> bold_font = get_theme_font(SNAME("bold_font")); ERR_FAIL_COND(bold_font.is_null()); - push_font(bold_font); + push_font(bold_font, get_theme_font_size(SNAME("bold_font_size"))); } void RichTextLabel::push_bold_italics() { Ref<Font> bold_italics_font = get_theme_font(SNAME("bold_italics_font")); ERR_FAIL_COND(bold_italics_font.is_null()); - push_font(bold_italics_font); + push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); } void RichTextLabel::push_italics() { Ref<Font> italics_font = get_theme_font(SNAME("italics_font")); ERR_FAIL_COND(italics_font.is_null()); - push_font(italics_font); + push_font(italics_font, get_theme_font_size(SNAME("italics_font_size"))); } void RichTextLabel::push_mono() { Ref<Font> mono_font = get_theme_font(SNAME("mono_font")); ERR_FAIL_COND(mono_font.is_null()); - push_font(mono_font); + push_font(mono_font, get_theme_font_size(SNAME("mono_font_size"))); } void RichTextLabel::push_font_size(int p_font_size) { @@ -3552,9 +3608,9 @@ void RichTextLabel::append_text(const String &p_bbcode) { //use bold font in_bold = true; if (in_italics) { - push_font(bold_italics_font); + push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); } else { - push_font(bold_font); + push_font(bold_font, get_theme_font_size(SNAME("bold_font_size"))); } pos = brk_end + 1; tag_stack.push_front(tag); @@ -3562,15 +3618,15 @@ void RichTextLabel::append_text(const String &p_bbcode) { //use italics font in_italics = true; if (in_bold) { - push_font(bold_italics_font); + push_font(bold_italics_font, get_theme_font_size(SNAME("bold_italics_font_size"))); } else { - push_font(italics_font); + push_font(italics_font, get_theme_font_size(SNAME("italics_font_size"))); } pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "code") { //use monospace font - push_font(mono_font); + push_font(mono_font, get_theme_font_size(SNAME("mono_font_size"))); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag.begins_with("table=")) { @@ -3999,9 +4055,16 @@ void RichTextLabel::append_text(const String &p_bbcode) { String fnt_ftr = tag.substr(18, tag.length()); Vector<String> subtag = fnt_ftr.split(","); if (subtag.size() > 0) { - Ref<Font> font = _find_font(current); - if (font.is_null()) { - font = normal_font; + Ref<Font> font = normal_font; + int font_size = 0; + ItemFont *font_it = _find_font(current); + if (font_it) { + if (font_it->font.is_valid()) { + font = font_it->font; + } + if (font_it->font_size > 0) { + font_size = font_it->font_size; + } } Ref<FontVariation> fc; fc.instantiate(); @@ -4016,7 +4079,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } } fc->set_opentype_features(features); - push_font(fc); + push_font(fc, font_size); } pos = brk_end + 1; tag_stack.push_front("opentype_features"); @@ -4037,6 +4100,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { Ref<FontVariation> fc; fc.instantiate(); + int fnt_size = 0; for (int i = 1; i < subtag.size(); i++) { Vector<String> subtag_a = subtag[i].split("=", true, 2); if (subtag_a.size() == 2) { @@ -4047,10 +4111,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { fc->set_base_font(font_data); } } else if (subtag_a[0] == "size" || subtag_a[0] == "s") { - int fnt_size = subtag_a[1].to_int(); - if (fnt_size > 0) { - push_font_size(fnt_size); - } + fnt_size = subtag_a[1].to_int(); } else if (subtag_a[0] == "glyph_spacing" || subtag_a[0] == "gl") { int spacing = subtag_a[1].to_int(); fc->set_spacing(TextServer::SPACING_GLYPH, spacing); @@ -4101,7 +4162,7 @@ void RichTextLabel::append_text(const String &p_bbcode) { } } } - push_font(fc); + push_font(fc, fnt_size); pos = brk_end + 1; tag_stack.push_front("font"); @@ -4883,11 +4944,10 @@ void RichTextLabel::install_effect(const Variant effect) { Ref<RichTextEffect> rteffect; rteffect = effect; - if (rteffect.is_valid()) { - custom_effects.push_back(effect); - if ((!text.is_empty()) && use_bbcode) { - parse_bbcode(text); - } + ERR_FAIL_COND_MSG(rteffect.is_null(), "Invalid RichTextEffect resource."); + custom_effects.push_back(effect); + if ((!text.is_empty()) && use_bbcode) { + parse_bbcode(text); } } @@ -4930,7 +4990,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER)); ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline); ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line); - ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font); + ClassDB::bind_method(D_METHOD("push_font", "font", "font_size"), &RichTextLabel::push_font); ClassDB::bind_method(D_METHOD("push_font_size", "font_size"), &RichTextLabel::push_font_size); ClassDB::bind_method(D_METHOD("push_normal"), &RichTextLabel::push_normal); ClassDB::bind_method(D_METHOD("push_bold"), &RichTextLabel::push_bold); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index c123f38c01..e5f0469c01 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -178,6 +178,7 @@ private: struct ItemFont : public Item { Ref<Font> font; + int font_size = 0; ItemFont() { type = ITEM_FONT; } }; @@ -462,8 +463,8 @@ private: Item *_find_indentable(Item *p_item); Item *_get_item_at_pos(Item *p_item_from, Item *p_item_to, int p_position); void _find_frame(Item *p_item, ItemFrame **r_frame, int *r_line); - int _find_font_size(Item *p_item); - Ref<Font> _find_font(Item *p_item); + ItemFontSize *_find_font_size(Item *p_item); + ItemFont *_find_font(Item *p_item); int _find_outline_size(Item *p_item, int p_default); ItemList *_find_list_item(Item *p_item); ItemDropcap *_find_dc_item(Item *p_item); @@ -518,7 +519,7 @@ public: void add_newline(); bool remove_line(const int p_line); void push_dropcap(const String &p_string, const Ref<Font> &p_font, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Color &p_color = Color(1, 1, 1), int p_ol_size = 0, const Color &p_ol_color = Color(0, 0, 0, 0)); - void push_font(const Ref<Font> &p_font); + void push_font(const Ref<Font> &p_font, int p_size = 0); void push_font_size(int p_font_size); void push_outline_size(int p_font_size); void push_normal(); diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h index 651edd1a74..1823f86a67 100644 --- a/scene/gui/scroll_bar.h +++ b/scene/gui/scroll_bar.h @@ -128,4 +128,4 @@ public: ScrollBar(VERTICAL) { set_h_size_flags(0); } }; -#endif +#endif // SCROLL_BAR_H diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 871cc520e9..9efab27e3a 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -37,10 +37,11 @@ Size2 ScrollContainer::get_minimum_size() const { Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); Size2 min_size; + Size2 content_min_size; for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); - if (!c) { + if (!c || !c->is_visible()) { continue; } if (c->is_set_as_top_level()) { @@ -51,20 +52,26 @@ Size2 ScrollContainer::get_minimum_size() const { } Size2 minsize = c->get_combined_minimum_size(); - if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) { - min_size.x = MAX(min_size.x, minsize.x); - } - if (vertical_scroll_mode == SCROLL_MODE_DISABLED) { - min_size.y = MAX(min_size.y, minsize.y); - } + content_min_size.x = MAX(content_min_size.x, minsize.x); + content_min_size.y = MAX(content_min_size.y, minsize.y); + } + + if (horizontal_scroll_mode == SCROLL_MODE_DISABLED) { + min_size.x = MAX(min_size.x, content_min_size.x); + } + if (vertical_scroll_mode == SCROLL_MODE_DISABLED) { + min_size.y = MAX(min_size.y, content_min_size.y); } - if (h_scroll->is_visible_in_tree()) { + bool h_scroll_show = horizontal_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (horizontal_scroll_mode == SCROLL_MODE_AUTO && content_min_size.x > min_size.x); + bool v_scroll_show = vertical_scroll_mode == SCROLL_MODE_SHOW_ALWAYS || (vertical_scroll_mode == SCROLL_MODE_AUTO && content_min_size.y > min_size.y); + if (h_scroll_show) { min_size.y += h_scroll->get_minimum_size().y; } - if (v_scroll->is_visible_in_tree()) { + if (v_scroll_show) { min_size.x += v_scroll->get_minimum_size().x; } + min_size += sb->get_minimum_size(); return min_size; } @@ -274,7 +281,7 @@ void ScrollContainer::_update_dimensions() { for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); - if (!c) { + if (!c || !c->is_visible()) { continue; } if (c->is_set_as_top_level()) { @@ -312,6 +319,7 @@ void ScrollContainer::_update_dimensions() { fit_child_in_rect(c, r); } + update_scrollbars(); update(); } diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h index b9fcf64db6..7c8690538d 100644 --- a/scene/gui/scroll_container.h +++ b/scene/gui/scroll_container.h @@ -116,4 +116,4 @@ public: VARIANT_ENUM_CAST(ScrollContainer::ScrollMode); -#endif +#endif // SCROLL_CONTAINER_H diff --git a/scene/gui/separator.h b/scene/gui/separator.h index 1621bb3351..e6578a4d04 100644 --- a/scene/gui/separator.h +++ b/scene/gui/separator.h @@ -60,4 +60,4 @@ public: HSeparator(); }; -#endif +#endif // SEPARATOR_H diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h index 55b7802aa4..5b488fb79e 100644 --- a/scene/gui/subviewport_container.h +++ b/scene/gui/subviewport_container.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef VIEWPORTCONTAINER_H -#define VIEWPORTCONTAINER_H +#ifndef SUBVIEWPORT_CONTAINER_H +#define SUBVIEWPORT_CONTAINER_H #include "scene/gui/container.h" @@ -63,4 +63,4 @@ public: SubViewportContainer(); }; -#endif // VIEWPORTCONTAINER_H +#endif // SUBVIEWPORT_CONTAINER_H diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 06553cd0f6..630a3316d6 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -443,8 +443,10 @@ void TextEdit::_notification(int p_what) { case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: case NOTIFICATION_THEME_CHANGED: { - _update_caches(); - _update_wrap_at_column(true); + if (is_inside_tree()) { + _update_caches(); + _update_wrap_at_column(true); + } } break; case NOTIFICATION_WM_WINDOW_FOCUS_IN: { diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h index 5762949acd..9f6f7c1515 100644 --- a/scene/gui/texture_button.h +++ b/scene/gui/texture_button.h @@ -101,4 +101,5 @@ public: }; VARIANT_ENUM_CAST(TextureButton::StretchMode); + #endif // TEXTURE_BUTTON_H diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 2c4cba4954..1eb6c5a554 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -723,7 +723,12 @@ TreeItem *TreeItem::get_next_visible(bool p_wrap) { TreeItem *TreeItem::get_child(int p_idx) { _create_children_cache(); + + if (p_idx < 0) { + p_idx += children_cache.size(); + } ERR_FAIL_INDEX_V(p_idx, children_cache.size(), nullptr); + return children_cache.get(p_idx); } @@ -1844,15 +1849,16 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 p_item->set_meta("__focus_rect", Rect2(r.position, r.size)); - if (rtl) { - r.position.x = get_size().width - r.position.x - r.size.x; - } - - if (p_item->cells[i].selected) { - if (has_focus()) { - cache.selected_focus->draw(ci, r); - } else { - cache.selected->draw(ci, r); + if (select_mode != SELECT_ROW) { + if (rtl) { + r.position.x = get_size().width - r.position.x - r.size.x; + } + if (p_item->cells[i].selected) { + if (has_focus()) { + cache.selected_focus->draw(ci, r); + } else { + cache.selected->draw(ci, r); + } } } } diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 1690e7ac57..f0819e2980 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -719,4 +719,5 @@ public: VARIANT_ENUM_CAST(Tree::SelectMode); VARIANT_ENUM_CAST(Tree::DropModeFlags); -#endif + +#endif // TREE_H diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp index 86334882fa..f20a2ad67b 100644 --- a/scene/gui/video_stream_player.cpp +++ b/scene/gui/video_stream_player.cpp @@ -225,7 +225,7 @@ void VideoStreamPlayer::set_stream(const Ref<VideoStream> &p_stream) { stream = p_stream; if (stream.is_valid()) { stream->set_audio_track(audio_track); - playback = stream->instance_playback(); + playback = stream->instantiate_playback(); } else { playback = Ref<VideoStreamPlayback>(); } diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index 2cd7cf5648..ce204c6aeb 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -64,9 +64,6 @@ void CanvasItem::_propagate_visibility_changed(bool p_parent_visible_in_tree) { if (!visible) { return; } - if (p_parent_visible_in_tree && first_draw) { // Avoid propagating it twice. - first_draw = false; - } _handle_visibility_change(p_parent_visible_in_tree); } @@ -133,10 +130,6 @@ void CanvasItem::_update_callback() { RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item()); //todo updating = true - only allow drawing here if (is_visible_in_tree()) { - if (first_draw) { - notification(NOTIFICATION_VISIBILITY_CHANGED); - first_draw = false; - } drawing = true; current_item_drawn = this; notification(NOTIFICATION_DRAW); @@ -230,16 +223,16 @@ void CanvasItem::_enter_canvas() { RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, canvas); - group = "root_canvas" + itos(canvas.get_id()); + canvas_group = "root_canvas" + itos(canvas.get_id()); - add_to_group(group); + add_to_group(canvas_group); if (canvas_layer) { canvas_layer->reset_sort_index(); } else { get_viewport()->gui_reset_canvas_sort_index(); } - get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, group, SNAME("_top_level_raise_self")); + get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, SNAME("_top_level_raise_self")); } else { CanvasItem *parent = get_parent_item(); @@ -258,14 +251,16 @@ void CanvasItem::_exit_canvas() { notification(NOTIFICATION_EXIT_CANVAS, true); //reverse the notification RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, RID()); canvas_layer = nullptr; - group = StringName(); + if (canvas_group != StringName()) { + remove_from_group(canvas_group); + canvas_group = StringName(); + } } void CanvasItem::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { ERR_FAIL_COND(!is_inside_tree()); - first_draw = true; Node *parent = get_parent(); if (parent) { @@ -304,6 +299,10 @@ void CanvasItem::_notification(int p_what) { } } + RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, is_visible_in_tree()); // The visibility of the parent may change. + if (is_visible_in_tree()) { + notification(NOTIFICATION_VISIBILITY_CHANGED); // Considered invisible until entered. + } _enter_canvas(); _update_texture_filter_changed(false); @@ -319,8 +318,8 @@ void CanvasItem::_notification(int p_what) { break; } - if (group != StringName()) { - get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, group, "_top_level_raise_self"); + if (canvas_group != StringName()) { + get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE | SceneTree::GROUP_CALL_DEFERRED, canvas_group, "_top_level_raise_self"); } else { CanvasItem *p = get_parent_item(); ERR_FAIL_COND(!p); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index a4574dce61..38e0be1683 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -70,7 +70,7 @@ private: mutable SelfList<Node> xform_change; RID canvas_item; - StringName group; + StringName canvas_group; CanvasLayer *canvas_layer = nullptr; @@ -83,7 +83,6 @@ private: int light_mask = 1; Window *window = nullptr; - bool first_draw = false; bool visible = true; bool parent_visible_in_tree = false; bool clip_children = false; diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 49b4b1b30c..4b32188377 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef HTTPREQUEST_H -#define HTTPREQUEST_H +#ifndef HTTP_REQUEST_H +#define HTTP_REQUEST_H #include "core/io/http_client.h" #include "core/os/thread.h" @@ -162,4 +162,4 @@ public: VARIANT_ENUM_CAST(HTTPRequest::Result); -#endif // HTTPREQUEST_H +#endif // HTTP_REQUEST_H diff --git a/scene/main/multiplayer_api.cpp b/scene/main/multiplayer_api.cpp new file mode 100644 index 0000000000..95574042a8 --- /dev/null +++ b/scene/main/multiplayer_api.cpp @@ -0,0 +1,416 @@ +/*************************************************************************/ +/* multiplayer_api.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "multiplayer_api.h" + +#include "core/debugger/engine_debugger.h" +#include "core/io/marshalls.h" + +#include <stdint.h> + +#ifdef DEBUG_ENABLED +#include "core/os/os.h" +#endif + +StringName MultiplayerAPI::default_interface = StringName(); + +void MultiplayerAPI::set_default_interface(const StringName &p_interface) { + ERR_FAIL_COND_MSG(!ClassDB::is_parent_class(p_interface, MultiplayerAPI::get_class_static()), vformat("Can't make %s the default multiplayer interface since it does not extend MultiplayerAPI.", p_interface)); + default_interface = p_interface; +} + +StringName MultiplayerAPI::get_default_interface() { + return default_interface; +} + +Ref<MultiplayerAPI> MultiplayerAPI::create_default_interface() { + if (default_interface != StringName()) { + return Ref<MultiplayerAPI>(Object::cast_to<MultiplayerAPI>(ClassDB::instantiate(default_interface))); + } + return Ref<MultiplayerAPI>(memnew(MultiplayerAPIExtension)); +} + +// The variant is compressed and encoded; The first byte contains all the meta +// information and the format is: +// - The first LSB 5 bits are used for the variant type. +// - The next two bits are used to store the encoding mode. +// - The most significant is used to store the boolean value. +#define VARIANT_META_TYPE_MASK 0x1F +#define VARIANT_META_EMODE_MASK 0x60 +#define VARIANT_META_BOOL_MASK 0x80 +#define ENCODE_8 0 << 5 +#define ENCODE_16 1 << 5 +#define ENCODE_32 2 << 5 +#define ENCODE_64 3 << 5 +Error MultiplayerAPI::encode_and_compress_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_allow_object_decoding) { + // Unreachable because `VARIANT_MAX` == 27 and `ENCODE_VARIANT_MASK` == 31 + CRASH_COND(p_variant.get_type() > VARIANT_META_TYPE_MASK); + + uint8_t *buf = r_buffer; + r_len = 0; + uint8_t encode_mode = 0; + + switch (p_variant.get_type()) { + case Variant::BOOL: { + if (buf) { + // We still have 1 free bit in the meta, so let's use it. + buf[0] = (p_variant.operator bool()) ? (1 << 7) : 0; + buf[0] |= encode_mode | p_variant.get_type(); + } + r_len += 1; + } break; + case Variant::INT: { + if (buf) { + // Reserve the first byte for the meta. + buf += 1; + } + r_len += 1; + int64_t val = p_variant; + if (val <= (int64_t)INT8_MAX && val >= (int64_t)INT8_MIN) { + // Use 8 bit + encode_mode = ENCODE_8; + if (buf) { + buf[0] = val; + } + r_len += 1; + } else if (val <= (int64_t)INT16_MAX && val >= (int64_t)INT16_MIN) { + // Use 16 bit + encode_mode = ENCODE_16; + if (buf) { + encode_uint16(val, buf); + } + r_len += 2; + } else if (val <= (int64_t)INT32_MAX && val >= (int64_t)INT32_MIN) { + // Use 32 bit + encode_mode = ENCODE_32; + if (buf) { + encode_uint32(val, buf); + } + r_len += 4; + } else { + // Use 64 bit + encode_mode = ENCODE_64; + if (buf) { + encode_uint64(val, buf); + } + r_len += 8; + } + // Store the meta + if (buf) { + buf -= 1; + buf[0] = encode_mode | p_variant.get_type(); + } + } break; + default: + // Any other case is not yet compressed. + Error err = encode_variant(p_variant, r_buffer, r_len, p_allow_object_decoding); + if (err != OK) { + return err; + } + if (r_buffer) { + // The first byte is not used by the marshalling, so store the type + // so we know how to decompress and decode this variant. + r_buffer[0] = p_variant.get_type(); + } + } + + return OK; +} + +Error MultiplayerAPI::decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding) { + const uint8_t *buf = p_buffer; + int len = p_len; + + ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); + uint8_t type = buf[0] & VARIANT_META_TYPE_MASK; + uint8_t encode_mode = buf[0] & VARIANT_META_EMODE_MASK; + + ERR_FAIL_COND_V(type >= Variant::VARIANT_MAX, ERR_INVALID_DATA); + + switch (type) { + case Variant::BOOL: { + bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0; + r_variant = val; + if (r_len) { + *r_len = 1; + } + } break; + case Variant::INT: { + buf += 1; + len -= 1; + if (r_len) { + *r_len = 1; + } + if (encode_mode == ENCODE_8) { + // 8 bits. + ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA); + int8_t val = buf[0]; + r_variant = val; + if (r_len) { + (*r_len) += 1; + } + } else if (encode_mode == ENCODE_16) { + // 16 bits. + ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA); + int16_t val = decode_uint16(buf); + r_variant = val; + if (r_len) { + (*r_len) += 2; + } + } else if (encode_mode == ENCODE_32) { + // 32 bits. + ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); + int32_t val = decode_uint32(buf); + r_variant = val; + if (r_len) { + (*r_len) += 4; + } + } else { + // 64 bits. + ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); + int64_t val = decode_uint64(buf); + r_variant = val; + if (r_len) { + (*r_len) += 8; + } + } + } break; + default: + Error err = decode_variant(r_variant, p_buffer, p_len, r_len, p_allow_object_decoding); + if (err != OK) { + return err; + } + } + + return OK; +} + +Error MultiplayerAPI::encode_and_compress_variants(const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw, bool p_allow_object_decoding) { + r_len = 0; + int size = 0; + + if (p_count == 0) { + if (r_raw) { + *r_raw = true; + } + return OK; + } + + // Try raw encoding optimization. + if (r_raw && p_count == 1) { + *r_raw = false; + const Variant &v = *(p_variants[0]); + if (v.get_type() == Variant::PACKED_BYTE_ARRAY) { + *r_raw = true; + const PackedByteArray pba = v; + if (p_buffer) { + memcpy(p_buffer, pba.ptr(), pba.size()); + } + r_len += pba.size(); + } else { + encode_and_compress_variant(v, p_buffer, size, p_allow_object_decoding); + r_len += size; + } + return OK; + } + + // Regular encoding. + for (int i = 0; i < p_count; i++) { + const Variant &v = *(p_variants[i]); + encode_and_compress_variant(v, p_buffer ? p_buffer + r_len : nullptr, size, p_allow_object_decoding); + r_len += size; + } + return OK; +} + +Error MultiplayerAPI::decode_and_decompress_variants(Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw, bool p_allow_object_decoding) { + r_len = 0; + int argc = r_variants.size(); + if (argc == 0 && p_raw) { + return OK; + } + ERR_FAIL_COND_V(p_raw && argc != 1, ERR_INVALID_DATA); + if (p_raw) { + r_len = p_len; + PackedByteArray pba; + pba.resize(p_len); + memcpy(pba.ptrw(), p_buffer, p_len); + r_variants.write[0] = pba; + return OK; + } + + Vector<Variant> args; + Vector<const Variant *> argp; + args.resize(argc); + + for (int i = 0; i < argc; i++) { + ERR_FAIL_COND_V_MSG(r_len >= p_len, ERR_INVALID_DATA, "Invalid packet received. Size too small."); + + int vlen; + Error err = MultiplayerAPI::decode_and_decompress_variant(r_variants.write[i], &p_buffer[r_len], p_len - r_len, &vlen, p_allow_object_decoding); + ERR_FAIL_COND_V_MSG(err != OK, err, "Invalid packet received. Unable to decode state variable."); + r_len += vlen; + } + return OK; +} + +Error MultiplayerAPI::_rpc_bind(int p_peer, Object *p_object, const StringName &p_method, Array p_args) { + Vector<Variant> args; + Vector<const Variant *> argsp; + args.resize(p_args.size()); + argsp.resize(p_args.size()); + Variant *ptr = args.ptrw(); + const Variant **pptr = argsp.ptrw(); + for (int i = 0; i < p_args.size(); i++) { + ptr[i] = p_args[i]; + pptr[i] = &ptr[i]; + } + return rpcp(p_object, p_peer, p_method, argsp.size() ? argsp.ptrw() : nullptr, argsp.size()); +} + +void MultiplayerAPI::_bind_methods() { + ClassDB::bind_method(D_METHOD("has_multiplayer_peer"), &MultiplayerAPI::has_multiplayer_peer); + ClassDB::bind_method(D_METHOD("get_multiplayer_peer"), &MultiplayerAPI::get_multiplayer_peer); + ClassDB::bind_method(D_METHOD("set_multiplayer_peer", "peer"), &MultiplayerAPI::set_multiplayer_peer); + ClassDB::bind_method(D_METHOD("get_unique_id"), &MultiplayerAPI::get_unique_id); + ClassDB::bind_method(D_METHOD("is_server"), &MultiplayerAPI::is_server); + ClassDB::bind_method(D_METHOD("get_remote_sender_id"), &MultiplayerAPI::get_remote_sender_id); + ClassDB::bind_method(D_METHOD("poll"), &MultiplayerAPI::poll); + ClassDB::bind_method(D_METHOD("rpc", "peer", "object", "method", "arguments"), &MultiplayerAPI::_rpc_bind, DEFVAL(Array())); + ClassDB::bind_method(D_METHOD("object_configuration_add", "object", "configuration"), &MultiplayerAPI::object_configuration_add); + ClassDB::bind_method(D_METHOD("object_configuration_remove", "object", "configuration"), &MultiplayerAPI::object_configuration_remove); + + ClassDB::bind_method(D_METHOD("get_peers"), &MultiplayerAPI::get_peer_ids); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiplayer_peer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerPeer", PROPERTY_USAGE_NONE), "set_multiplayer_peer", "get_multiplayer_peer"); + + ClassDB::bind_static_method("MultiplayerAPI", D_METHOD("set_default_interface", "interface_name"), &MultiplayerAPI::set_default_interface); + ClassDB::bind_static_method("MultiplayerAPI", D_METHOD("get_default_interface"), &MultiplayerAPI::get_default_interface); + ClassDB::bind_static_method("MultiplayerAPI", D_METHOD("create_default_interface"), &MultiplayerAPI::create_default_interface); + + ADD_SIGNAL(MethodInfo("peer_connected", PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("peer_disconnected", PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("connected_to_server")); + ADD_SIGNAL(MethodInfo("connection_failed")); + ADD_SIGNAL(MethodInfo("server_disconnected")); + + BIND_ENUM_CONSTANT(RPC_MODE_DISABLED); + BIND_ENUM_CONSTANT(RPC_MODE_ANY_PEER); + BIND_ENUM_CONSTANT(RPC_MODE_AUTHORITY); +} + +/// MultiplayerAPIExtension + +Error MultiplayerAPIExtension::poll() { + int err; + if (GDVIRTUAL_CALL(_poll, err)) { + return (Error)err; + } + return OK; +} + +void MultiplayerAPIExtension::set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) { + GDVIRTUAL_CALL(_set_multiplayer_peer, p_peer); +} + +Ref<MultiplayerPeer> MultiplayerAPIExtension::get_multiplayer_peer() { + Ref<MultiplayerPeer> peer; + if (GDVIRTUAL_CALL(_get_multiplayer_peer, peer)) { + return peer; + } + return nullptr; +} + +int MultiplayerAPIExtension::get_unique_id() { + int id; + if (GDVIRTUAL_CALL(_get_unique_id, id)) { + return id; + } + return 1; +} + +Vector<int> MultiplayerAPIExtension::get_peer_ids() { + Vector<int> ids; + if (GDVIRTUAL_CALL(_get_peer_ids, ids)) { + return ids; + } + return Vector<int>(); +} + +Error MultiplayerAPIExtension::rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { + if (!GDVIRTUAL_IS_OVERRIDDEN(_rpc)) { + return ERR_UNAVAILABLE; + } + Array args; + for (int i = 0; i < p_argcount; i++) { + args.push_back(*p_arg[i]); + } + int ret; + if (GDVIRTUAL_CALL(_rpc, p_peer_id, p_obj, p_method, args, ret)) { + return (Error)ret; + } + return FAILED; +} + +int MultiplayerAPIExtension::get_remote_sender_id() { + int id; + if (GDVIRTUAL_CALL(_get_remote_sender_id, id)) { + return id; + } + return 0; +} + +Error MultiplayerAPIExtension::object_configuration_add(Object *p_object, Variant p_config) { + int err; + if (GDVIRTUAL_CALL(_object_configuration_add, p_object, p_config, err)) { + return (Error)err; + } + return ERR_UNAVAILABLE; +} + +Error MultiplayerAPIExtension::object_configuration_remove(Object *p_object, Variant p_config) { + int err; + if (GDVIRTUAL_CALL(_object_configuration_remove, p_object, p_config, err)) { + return (Error)err; + } + return ERR_UNAVAILABLE; +} + +void MultiplayerAPIExtension::_bind_methods() { + GDVIRTUAL_BIND(_poll); + GDVIRTUAL_BIND(_set_multiplayer_peer, "multiplayer_peer"); + GDVIRTUAL_BIND(_get_multiplayer_peer); + GDVIRTUAL_BIND(_get_unique_id); + GDVIRTUAL_BIND(_get_peer_ids); + GDVIRTUAL_BIND(_rpc, "peer", "object", "method", "args"); + GDVIRTUAL_BIND(_get_remote_sender_id); + GDVIRTUAL_BIND(_object_configuration_add, "object", "configuration"); + GDVIRTUAL_BIND(_object_configuration_remove, "object", "configuration"); +} diff --git a/scene/main/multiplayer_api.h b/scene/main/multiplayer_api.h new file mode 100644 index 0000000000..c1d90d651e --- /dev/null +++ b/scene/main/multiplayer_api.h @@ -0,0 +1,115 @@ +/*************************************************************************/ +/* multiplayer_api.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 MULTIPLAYER_API_H +#define MULTIPLAYER_API_H + +#include "core/object/ref_counted.h" +#include "scene/main/multiplayer_peer.h" + +class MultiplayerAPI : public RefCounted { + GDCLASS(MultiplayerAPI, RefCounted); + +private: + static StringName default_interface; + +protected: + static void _bind_methods(); + Error _rpc_bind(int p_peer, Object *p_obj, const StringName &p_method, Array args = Array()); + +public: + enum RPCMode { + RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default) + RPC_MODE_ANY_PEER, // Any peer can call this RPC + RPC_MODE_AUTHORITY, // Only the node's multiplayer authority (server by default) can call this RPC + }; + + static Ref<MultiplayerAPI> create_default_interface(); + static void set_default_interface(const StringName &p_interface); + static StringName get_default_interface(); + + static Error encode_and_compress_variant(const Variant &p_variant, uint8_t *p_buffer, int &r_len, bool p_allow_object_decoding); + static Error decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_object_decoding); + static Error encode_and_compress_variants(const Variant **p_variants, int p_count, uint8_t *p_buffer, int &r_len, bool *r_raw = nullptr, bool p_allow_object_decoding = false); + static Error decode_and_decompress_variants(Vector<Variant> &r_variants, const uint8_t *p_buffer, int p_len, int &r_len, bool p_raw = false, bool p_allow_object_decoding = false); + + virtual Error poll() = 0; + virtual void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) = 0; + virtual Ref<MultiplayerPeer> get_multiplayer_peer() = 0; + virtual int get_unique_id() = 0; + virtual Vector<int> get_peer_ids() = 0; + + virtual Error rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) = 0; + virtual int get_remote_sender_id() = 0; + + virtual Error object_configuration_add(Object *p_object, Variant p_config) = 0; + virtual Error object_configuration_remove(Object *p_object, Variant p_config) = 0; + + bool has_multiplayer_peer() { return get_multiplayer_peer().is_valid(); } + bool is_server() { return get_unique_id() == MultiplayerPeer::TARGET_PEER_SERVER; } + + MultiplayerAPI() {} + virtual ~MultiplayerAPI() {} +}; + +VARIANT_ENUM_CAST(MultiplayerAPI::RPCMode); + +class MultiplayerAPIExtension : public MultiplayerAPI { + GDCLASS(MultiplayerAPIExtension, MultiplayerAPI); + +protected: + static void _bind_methods(); + +public: + virtual Error poll() override; + virtual void set_multiplayer_peer(const Ref<MultiplayerPeer> &p_peer) override; + virtual Ref<MultiplayerPeer> get_multiplayer_peer() override; + virtual int get_unique_id() override; + virtual Vector<int> get_peer_ids() override; + + virtual Error rpcp(Object *p_obj, int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) override; + virtual int get_remote_sender_id() override; + + virtual Error object_configuration_add(Object *p_object, Variant p_config) override; + virtual Error object_configuration_remove(Object *p_object, Variant p_config) override; + + // Extensions + GDVIRTUAL0R(int, _poll); + GDVIRTUAL1(_set_multiplayer_peer, Ref<MultiplayerPeer>); + GDVIRTUAL0R(Ref<MultiplayerPeer>, _get_multiplayer_peer); + GDVIRTUAL0RC(int, _get_unique_id); + GDVIRTUAL0RC(PackedInt32Array, _get_peer_ids); + GDVIRTUAL4R(int, _rpc, int, Object *, StringName, Array); + GDVIRTUAL0RC(int, _get_remote_sender_id); + GDVIRTUAL2R(int, _object_configuration_add, Object *, Variant); + GDVIRTUAL2R(int, _object_configuration_remove, Object *, Variant); +}; + +#endif // MULTIPLAYER_API_H diff --git a/core/multiplayer/multiplayer_peer.cpp b/scene/main/multiplayer_peer.cpp index b262903ce8..aad5baccab 100644 --- a/core/multiplayer/multiplayer_peer.cpp +++ b/scene/main/multiplayer_peer.cpp @@ -62,11 +62,11 @@ int MultiplayerPeer::get_transfer_channel() const { return transfer_channel; } -void MultiplayerPeer::set_transfer_mode(Multiplayer::TransferMode p_mode) { +void MultiplayerPeer::set_transfer_mode(TransferMode p_mode) { transfer_mode = p_mode; } -Multiplayer::TransferMode MultiplayerPeer::get_transfer_mode() const { +MultiplayerPeer::TransferMode MultiplayerPeer::get_transfer_mode() const { return transfer_mode; } @@ -107,6 +107,10 @@ void MultiplayerPeer::_bind_methods() { BIND_CONSTANT(TARGET_PEER_BROADCAST); BIND_CONSTANT(TARGET_PEER_SERVER); + BIND_ENUM_CONSTANT(TRANSFER_MODE_UNRELIABLE); + BIND_ENUM_CONSTANT(TRANSFER_MODE_UNRELIABLE_ORDERED); + BIND_ENUM_CONSTANT(TRANSFER_MODE_RELIABLE); + ADD_SIGNAL(MethodInfo("peer_connected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("peer_disconnected", PropertyInfo(Variant::INT, "id"))); ADD_SIGNAL(MethodInfo("server_disconnected")); @@ -130,6 +134,20 @@ Error MultiplayerPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buff if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) { return (Error)err; } + if (GDVIRTUAL_IS_OVERRIDDEN(_get_packet_script)) { + if (!GDVIRTUAL_CALL(_get_packet_script, script_buffer)) { + return FAILED; + } + + if (script_buffer.size() == 0) { + return Error::ERR_UNAVAILABLE; + } + + *r_buffer = script_buffer.ptr(); + r_buffer_size = script_buffer.size(); + + return Error::OK; + } WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_packet_native is unimplemented!"); return FAILED; } @@ -139,6 +157,16 @@ Error MultiplayerPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) { return (Error)err; } + if (GDVIRTUAL_IS_OVERRIDDEN(_put_packet_script)) { + PackedByteArray a; + a.resize(p_buffer_size); + memcpy(a.ptrw(), p_buffer, p_buffer_size); + + if (!GDVIRTUAL_CALL(_put_packet_script, a, err)) { + return FAILED; + } + return (Error)err; + } WARN_PRINT_ONCE("MultiplayerPeerExtension::_put_packet_native is unimplemented!"); return FAILED; } @@ -167,17 +195,17 @@ int MultiplayerPeerExtension::get_transfer_channel() const { return MultiplayerPeer::get_transfer_channel(); } -void MultiplayerPeerExtension::set_transfer_mode(Multiplayer::TransferMode p_mode) { +void MultiplayerPeerExtension::set_transfer_mode(TransferMode p_mode) { if (GDVIRTUAL_CALL(_set_transfer_mode, p_mode)) { return; } MultiplayerPeer::set_transfer_mode(p_mode); } -Multiplayer::TransferMode MultiplayerPeerExtension::get_transfer_mode() const { +MultiplayerPeer::TransferMode MultiplayerPeerExtension::get_transfer_mode() const { int mode; if (GDVIRTUAL_CALL(_get_transfer_mode, mode)) { - return (Multiplayer::TransferMode)mode; + return (MultiplayerPeer::TransferMode)mode; } return MultiplayerPeer::get_transfer_mode(); } @@ -254,6 +282,9 @@ void MultiplayerPeerExtension::_bind_methods() { GDVIRTUAL_BIND(_get_available_packet_count); GDVIRTUAL_BIND(_get_max_packet_size); + GDVIRTUAL_BIND(_get_packet_script) + GDVIRTUAL_BIND(_put_packet_script, "p_buffer"); + GDVIRTUAL_BIND(_set_transfer_channel, "p_channel"); GDVIRTUAL_BIND(_get_transfer_channel); diff --git a/core/multiplayer/multiplayer_peer.h b/scene/main/multiplayer_peer.h index dee2be7b4b..8a012d7520 100644 --- a/core/multiplayer/multiplayer_peer.h +++ b/scene/main/multiplayer_peer.h @@ -28,11 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NETWORKED_MULTIPLAYER_PEER_H -#define NETWORKED_MULTIPLAYER_PEER_H +#ifndef MULTIPLAYER_PEER_H +#define MULTIPLAYER_PEER_H #include "core/io/packet_peer.h" -#include "core/multiplayer/multiplayer.h" #include "core/object/gdvirtual.gen.inc" #include "core/object/script_language.h" @@ -41,12 +40,19 @@ class MultiplayerPeer : public PacketPeer { GDCLASS(MultiplayerPeer, PacketPeer); +public: + enum TransferMode { + TRANSFER_MODE_UNRELIABLE, + TRANSFER_MODE_UNRELIABLE_ORDERED, + TRANSFER_MODE_RELIABLE + }; + protected: static void _bind_methods(); private: int transfer_channel = 0; - Multiplayer::TransferMode transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE; + TransferMode transfer_mode = TRANSFER_MODE_RELIABLE; bool refuse_connections = false; public: @@ -63,8 +69,8 @@ public: virtual void set_transfer_channel(int p_channel); virtual int get_transfer_channel() const; - virtual void set_transfer_mode(Multiplayer::TransferMode p_mode); - virtual Multiplayer::TransferMode get_transfer_mode() const; + virtual void set_transfer_mode(TransferMode p_mode); + virtual TransferMode get_transfer_mode() const; virtual void set_refuse_new_connections(bool p_enable); virtual bool is_refusing_new_connections() const; @@ -86,6 +92,7 @@ public: }; VARIANT_ENUM_CAST(MultiplayerPeer::ConnectionStatus); +VARIANT_ENUM_CAST(MultiplayerPeer::TransferMode); class MultiplayerPeerExtension : public MultiplayerPeer { GDCLASS(MultiplayerPeerExtension, MultiplayerPeer); @@ -93,6 +100,8 @@ class MultiplayerPeerExtension : public MultiplayerPeer { protected: static void _bind_methods(); + PackedByteArray script_buffer; + public: /* PacketPeer */ virtual int get_available_packet_count() const override; @@ -103,8 +112,8 @@ public: /* MultiplayerPeer */ virtual void set_transfer_channel(int p_channel) override; virtual int get_transfer_channel() const override; - virtual void set_transfer_mode(Multiplayer::TransferMode p_mode) override; - virtual Multiplayer::TransferMode get_transfer_mode() const override; + virtual void set_transfer_mode(TransferMode p_mode) override; + virtual TransferMode get_transfer_mode() const override; virtual void set_target_peer(int p_peer_id) override; virtual int get_packet_peer() const override; @@ -126,6 +135,10 @@ public: GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int); GDVIRTUAL0RC(int, _get_max_packet_size); + /* PacketPeer GDScript */ + GDVIRTUAL0R(PackedByteArray, _get_packet_script); + GDVIRTUAL1R(int, _put_packet_script, PackedByteArray); + /* MultiplayerPeer GDExtension */ GDVIRTUAL1(_set_transfer_channel, int); GDVIRTUAL0RC(int, _get_transfer_channel); @@ -141,4 +154,4 @@ public: GDVIRTUAL0RC(int, _get_connection_status); }; -#endif // NETWORKED_MULTIPLAYER_PEER_H +#endif // MULTIPLAYER_PEER_H diff --git a/scene/main/node.cpp b/scene/main/node.cpp index b4701637a4..4bf1936a65 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -33,12 +33,12 @@ #include "core/config/project_settings.h" #include "core/core_string_names.h" #include "core/io/resource_loader.h" -#include "core/multiplayer/multiplayer_api.h" #include "core/object/message_queue.h" #include "core/string/print_string.h" #include "instance_placeholder.h" #include "scene/animation/tween.h" #include "scene/debugger/scene_debugger.h" +#include "scene/main/multiplayer_api.h" #include "scene/resources/packed_scene.h" #include "scene/scene_string_names.h" #include "viewport.h" @@ -582,35 +582,30 @@ bool Node::is_multiplayer_authority() const { /***** RPC CONFIG ********/ -uint16_t Node::rpc_config(const StringName &p_method, Multiplayer::RPCMode p_rpc_mode, bool p_call_local, Multiplayer::TransferMode p_transfer_mode, int p_channel) { - for (int i = 0; i < data.rpc_methods.size(); i++) { - if (data.rpc_methods[i].name == p_method) { - Multiplayer::RPCConfig &nd = data.rpc_methods.write[i]; - nd.rpc_mode = p_rpc_mode; - nd.transfer_mode = p_transfer_mode; - nd.call_local = p_call_local; - nd.channel = p_channel; - return i | (1 << 15); - } +void Node::rpc_config(const StringName &p_method, const Variant &p_config) { + if (data.rpc_config.get_type() != Variant::DICTIONARY) { + data.rpc_config = Dictionary(); + } + Dictionary node_config = data.rpc_config; + if (p_config.get_type() == Variant::NIL) { + node_config.erase(p_method); + } else { + ERR_FAIL_COND(p_config.get_type() != Variant::DICTIONARY); + node_config[p_method] = p_config; } - // New method - Multiplayer::RPCConfig nd; - nd.name = p_method; - nd.rpc_mode = p_rpc_mode; - nd.transfer_mode = p_transfer_mode; - nd.channel = p_channel; - nd.call_local = p_call_local; - data.rpc_methods.push_back(nd); - return ((uint16_t)data.rpc_methods.size() - 1) | (1 << 15); +} + +const Variant Node::get_node_rpc_config() const { + return data.rpc_config; } /***** RPC FUNCTIONS ********/ -void Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Error Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 1) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; - return; + return ERR_INVALID_PARAMETER; } Variant::Type type = p_args[0]->get_type(); @@ -618,28 +613,28 @@ void Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING_NAME; - return; + return ERR_INVALID_PARAMETER; } StringName method = (*p_args[0]).operator StringName(); - rpcp(0, method, &p_args[1], p_argcount - 1); - + Error err = rpcp(0, method, &p_args[1], p_argcount - 1); r_error.error = Callable::CallError::CALL_OK; + return err; } -void Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Error Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { if (p_argcount < 2) { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 2; - return; + return ERR_INVALID_PARAMETER; } if (p_args[0]->get_type() != Variant::INT) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::INT; - return; + return ERR_INVALID_PARAMETER; } Variant::Type type = p_args[1]->get_type(); @@ -647,20 +642,35 @@ void Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallEr r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING_NAME; - return; + return ERR_INVALID_PARAMETER; } int peer_id = *p_args[0]; StringName method = (*p_args[1]).operator StringName(); - rpcp(peer_id, method, &p_args[2], p_argcount - 2); - + Error err = rpcp(peer_id, method, &p_args[2], p_argcount - 2); r_error.error = Callable::CallError::CALL_OK; + return err; } -void Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { - ERR_FAIL_COND(!is_inside_tree()); - get_multiplayer()->rpcp(this, p_peer_id, p_method, p_arg, p_argcount); +template <typename... VarArgs> +Error Node::rpc(const StringName &p_method, VarArgs... p_args) { + return rpc_id(0, p_method, p_args...); +} + +template <typename... VarArgs> +Error Node::rpc_id(int p_peer_id, const StringName &p_method, VarArgs... p_args) { + Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + return rpcp(p_peer_id, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); +} + +Error Node::rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount) { + ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED); + return get_multiplayer()->rpcp(this, p_peer_id, p_method, p_arg, p_argcount); } Ref<MultiplayerAPI> Node::get_multiplayer() const { @@ -670,10 +680,6 @@ Ref<MultiplayerAPI> Node::get_multiplayer() const { return get_tree()->get_multiplayer(get_path()); } -Vector<Multiplayer::RPCConfig> Node::get_node_rpc_methods() const { - return data.rpc_methods; -} - //////////// end of rpc bool Node::can_process_notification(int p_what) const { @@ -2888,7 +2894,7 @@ void Node::_bind_methods() { ClassDB::bind_method(D_METHOD("is_multiplayer_authority"), &Node::is_multiplayer_authority); ClassDB::bind_method(D_METHOD("get_multiplayer"), &Node::get_multiplayer); - ClassDB::bind_method(D_METHOD("rpc_config", "method", "rpc_mode", "call_local", "transfer_mode", "channel"), &Node::rpc_config, DEFVAL(false), DEFVAL(Multiplayer::TRANSFER_MODE_RELIABLE), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("rpc_config", "method", "config"), &Node::rpc_config); ClassDB::bind_method(D_METHOD("set_editor_description", "editor_description"), &Node::set_editor_description); ClassDB::bind_method(D_METHOD("get_editor_description"), &Node::get_editor_description); diff --git a/scene/main/node.h b/scene/main/node.h index 3c4727f11c..0645c68eb9 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -127,7 +127,7 @@ private: Node *process_owner = nullptr; int multiplayer_authority = 1; // Server by default. - Vector<Multiplayer::RPCConfig> rpc_methods; + Variant rpc_config; // Variables used to properly sort the node when processing, ignored otherwise. // TODO: Should move all the stuff below to bits. @@ -183,8 +183,8 @@ private: TypedArray<Node> _get_children(bool p_include_internal = true) const; Array _get_groups() const; - void _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - void _rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Error _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Error _rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); _FORCE_INLINE_ bool _is_internal_front() const { return data.parent && data.pos < data.parent->data.internal_children_front; } _FORCE_INLINE_ bool _is_internal_back() const { return data.parent && data.pos >= data.parent->data.children.size() - data.parent->data.internal_children_back; } @@ -491,30 +491,16 @@ public: int get_multiplayer_authority() const; bool is_multiplayer_authority() const; - uint16_t rpc_config(const StringName &p_method, Multiplayer::RPCMode p_rpc_mode, bool p_call_local = false, Multiplayer::TransferMode p_transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE, int p_channel = 0); // config a local method for RPC - Vector<Multiplayer::RPCConfig> get_node_rpc_methods() const; + void rpc_config(const StringName &p_method, const Variant &p_config); // config a local method for RPC + const Variant get_node_rpc_config() const; template <typename... VarArgs> - void rpc(const StringName &p_method, VarArgs... p_args) { - Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. - const Variant *argptrs[sizeof...(p_args) + 1]; - for (uint32_t i = 0; i < sizeof...(p_args); i++) { - argptrs[i] = &args[i]; - } - rpcp(0, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); - } + Error rpc(const StringName &p_method, VarArgs... p_args); template <typename... VarArgs> - void rpc_id(int p_peer_id, const StringName &p_method, VarArgs... p_args) { - Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. - const Variant *argptrs[sizeof...(p_args) + 1]; - for (uint32_t i = 0; i < sizeof...(p_args); i++) { - argptrs[i] = &args[i]; - } - rpcp(p_peer_id, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); - } + Error rpc_id(int p_peer_id, const StringName &p_method, VarArgs... p_args); - void rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); + Error rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount); Ref<MultiplayerAPI> get_multiplayer() const; @@ -526,4 +512,4 @@ VARIANT_ENUM_CAST(Node::DuplicateFlags); typedef HashSet<Node *, Node::Comparator> NodeSet; -#endif +#endif // NODE_H diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 66482f65dc..644fb3e9cc 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -37,7 +37,6 @@ #include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/resource_loader.h" -#include "core/multiplayer/multiplayer_api.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" @@ -45,6 +44,7 @@ #include "node.h" #include "scene/animation/tween.h" #include "scene/debugger/scene_debugger.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/viewport.h" #include "scene/resources/font.h" #include "scene/resources/material.h" @@ -1213,19 +1213,17 @@ void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer, const NodePat if (p_root_path.is_empty()) { ERR_FAIL_COND(!p_multiplayer.is_valid()); if (multiplayer.is_valid()) { - multiplayer->set_root_path(NodePath()); + multiplayer->object_configuration_remove(nullptr, NodePath("/" + root->get_name())); } multiplayer = p_multiplayer; - multiplayer->set_root_path("/" + root->get_name()); + multiplayer->object_configuration_add(nullptr, NodePath("/" + root->get_name())); } else { + if (custom_multiplayers.has(p_root_path)) { + custom_multiplayers[p_root_path]->object_configuration_remove(nullptr, p_root_path); + } if (p_multiplayer.is_valid()) { custom_multiplayers[p_root_path] = p_multiplayer; - p_multiplayer->set_root_path(p_root_path); - } else { - if (custom_multiplayers.has(p_root_path)) { - custom_multiplayers[p_root_path]->set_root_path(NodePath()); - custom_multiplayers.erase(p_root_path); - } + p_multiplayer->object_configuration_add(nullptr, p_root_path); } } } @@ -1415,7 +1413,7 @@ SceneTree::SceneTree() { #endif // _3D_DISABLED // Initialize network state. - set_multiplayer(Ref<MultiplayerAPI>(memnew(MultiplayerAPI))); + set_multiplayer(MultiplayerAPI::create_default_interface()); root->set_as_audio_listener_2d(true); current_scene = nullptr; diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 0049359cad..a621aea9c8 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -64,9 +64,9 @@ bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_valu if (active) { if (o->override.get_type() == Variant::OBJECT) { RID tex_rid = p_value; - RS::get_singleton()->global_variable_set_override(*r, tex_rid); + RS::get_singleton()->global_shader_uniform_set_override(*r, tex_rid); } else { - RS::get_singleton()->global_variable_set_override(*r, p_value); + RS::get_singleton()->global_shader_uniform_set_override(*r, p_value); } } o->in_use = p_value.get_type() != Variant::NIL; @@ -93,13 +93,13 @@ bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const { Vector<StringName> variables; - variables = RS::get_singleton()->global_variable_get_list(); + variables = RS::get_singleton()->global_shader_uniform_get_list(); for (int i = 0; i < variables.size(); i++) { PropertyInfo pinfo; pinfo.name = "params/" + variables[i]; pinfo.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE; - switch (RS::get_singleton()->global_variable_get_type(variables[i])) { + switch (RS::get_singleton()->global_shader_uniform_get_type(variables[i])) { case RS::GLOBAL_VAR_TYPE_BOOL: { pinfo.type = Variant::BOOL; } break; @@ -155,7 +155,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const pinfo.type = Variant::VECTOR3; } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - pinfo.type = Variant::QUATERNION; + pinfo.type = Variant::VECTOR4; } break; case RS::GLOBAL_VAR_TYPE_RECT2: { pinfo.type = Variant::RECT2; @@ -169,15 +169,15 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const case RS::GLOBAL_VAR_TYPE_MAT3: { pinfo.type = Variant::BASIS; } break; + case RS::GLOBAL_VAR_TYPE_MAT4: { + pinfo.type = Variant::PROJECTION; + } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { pinfo.type = Variant::TRANSFORM2D; } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { pinfo.type = Variant::TRANSFORM3D; } break; - case RS::GLOBAL_VAR_TYPE_MAT4: { - pinfo.type = Variant::PACKED_INT32_ARRAY; - } break; case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { pinfo.type = Variant::OBJECT; pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; @@ -234,9 +234,9 @@ void ShaderGlobalsOverride::_activate() { if (o->in_use && o->override.get_type() != Variant::NIL) { if (o->override.get_type() == Variant::OBJECT) { RID tex_rid = o->override; - RS::get_singleton()->global_variable_set_override(E.key, tex_rid); + RS::get_singleton()->global_shader_uniform_set_override(E.key, tex_rid); } else { - RS::get_singleton()->global_variable_set_override(E.key, o->override); + RS::get_singleton()->global_shader_uniform_set_override(E.key, o->override); } } @@ -258,7 +258,7 @@ void ShaderGlobalsOverride::_notification(int p_what) { for (const KeyValue<StringName, Override> &E : overrides) { const Override *o = &E.value; if (o->in_use) { - RS::get_singleton()->global_variable_set_override(E.key, Variant()); + RS::get_singleton()->global_shader_uniform_set_override(E.key, Variant()); } } } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index c2fa1ace8d..4dd4c8419c 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1234,13 +1234,23 @@ void Viewport::_gui_show_tooltip() { Rect2i vr = window->get_usable_parent_rect(); if (r.size.x + r.position.x > vr.size.x + vr.position.x) { - r.position.x = vr.position.x + vr.size.x - r.size.x; + // Place it in the opposite direction. If it fails, just hug the border. + r.position.x = gui.tooltip_pos.x - r.size.x - tooltip_offset.x; + + if (r.position.x < vr.position.x) { + r.position.x = vr.position.x + vr.size.x - r.size.x; + } } else if (r.position.x < vr.position.x) { r.position.x = vr.position.x; } if (r.size.y + r.position.y > vr.size.y + vr.position.y) { - r.position.y = vr.position.y + vr.size.y - r.size.y; + // Same as above. + r.position.y = gui.tooltip_pos.y - r.size.y - tooltip_offset.y; + + if (r.position.y < vr.position.y) { + r.position.y = vr.position.y + vr.size.y - r.size.y; + } } else if (r.position.y < vr.position.y) { r.position.y = vr.position.y; } @@ -3621,17 +3631,17 @@ float Viewport::get_fsr_sharpness() const { return fsr_sharpness; } -void Viewport::set_fsr_mipmap_bias(float p_fsr_mipmap_bias) { - if (fsr_mipmap_bias == p_fsr_mipmap_bias) { +void Viewport::set_texture_mipmap_bias(float p_texture_mipmap_bias) { + if (texture_mipmap_bias == p_texture_mipmap_bias) { return; } - fsr_mipmap_bias = p_fsr_mipmap_bias; - RS::get_singleton()->viewport_set_fsr_mipmap_bias(viewport, p_fsr_mipmap_bias); + texture_mipmap_bias = p_texture_mipmap_bias; + RS::get_singleton()->viewport_set_texture_mipmap_bias(viewport, p_texture_mipmap_bias); } -float Viewport::get_fsr_mipmap_bias() const { - return fsr_mipmap_bias; +float Viewport::get_texture_mipmap_bias() const { + return texture_mipmap_bias; } #endif // _3D_DISABLED @@ -3773,8 +3783,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fsr_sharpness", "fsr_sharpness"), &Viewport::set_fsr_sharpness); ClassDB::bind_method(D_METHOD("get_fsr_sharpness"), &Viewport::get_fsr_sharpness); - ClassDB::bind_method(D_METHOD("set_fsr_mipmap_bias", "fsr_mipmap_bias"), &Viewport::set_fsr_mipmap_bias); - ClassDB::bind_method(D_METHOD("get_fsr_mipmap_bias"), &Viewport::get_fsr_mipmap_bias); + ClassDB::bind_method(D_METHOD("set_texture_mipmap_bias", "texture_mipmap_bias"), &Viewport::set_texture_mipmap_bias); + ClassDB::bind_method(D_METHOD("get_texture_mipmap_bias"), &Viewport::get_texture_mipmap_bias); ClassDB::bind_method(D_METHOD("set_vrs_mode", "mode"), &Viewport::set_vrs_mode); ClassDB::bind_method(D_METHOD("get_vrs_mode"), &Viewport::get_vrs_mode); @@ -3804,7 +3814,7 @@ void Viewport::_bind_methods() { ADD_GROUP("Scaling 3D", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Bilinear (Fastest),FSR 1.0 (Fast)"), "set_scaling_3d_mode", "get_scaling_3d_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "scaling_3d_scale", PROPERTY_HINT_RANGE, "0.25,2.0,0.01"), "set_scaling_3d_scale", "get_scaling_3d_scale"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_mipmap_bias", PROPERTY_HINT_RANGE, "-2,2,0.1"), "set_fsr_mipmap_bias", "get_fsr_mipmap_bias"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_mipmap_bias", PROPERTY_HINT_RANGE, "-2,2,0.001"), "set_texture_mipmap_bias", "get_texture_mipmap_bias"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1"), "set_fsr_sharpness", "get_fsr_sharpness"); #endif ADD_GROUP("Variable Rate Shading", "vrs_"); @@ -3978,8 +3988,8 @@ Viewport::Viewport() { float fsr_sharpness = GLOBAL_GET("rendering/scaling_3d/fsr_sharpness"); set_fsr_sharpness(fsr_sharpness); - float fsr_mipmap_bias = GLOBAL_GET("rendering/scaling_3d/fsr_mipmap_bias"); - set_fsr_mipmap_bias(fsr_mipmap_bias); + float texture_mipmap_bias = GLOBAL_GET("rendering/textures/default_filters/texture_mipmap_bias"); + set_texture_mipmap_bias(texture_mipmap_bias); #endif // _3D_DISABLED set_sdf_oversize(sdf_oversize); // Set to server. diff --git a/scene/main/viewport.h b/scene/main/viewport.h index a43e3f3ee2..4221baff06 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -304,7 +304,7 @@ private: Scaling3DMode scaling_3d_mode = SCALING_3D_MODE_BILINEAR; float scaling_3d_scale = 1.0; float fsr_sharpness = 0.2f; - float fsr_mipmap_bias = 0.0f; + float texture_mipmap_bias = 0.0f; bool use_debanding = false; float mesh_lod_threshold = 1.0; bool use_occlusion_culling = false; @@ -540,8 +540,8 @@ public: void set_fsr_sharpness(float p_fsr_sharpness); float get_fsr_sharpness() const; - void set_fsr_mipmap_bias(float p_fsr_mipmap_bias); - float get_fsr_mipmap_bias() const; + void set_texture_mipmap_bias(float p_texture_mipmap_bias); + float get_texture_mipmap_bias() const; void set_use_debanding(bool p_use_debanding); bool is_using_debanding() const; @@ -779,4 +779,4 @@ VARIANT_ENUM_CAST(Viewport::RenderInfoType); VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureFilter); VARIANT_ENUM_CAST(Viewport::DefaultCanvasItemTextureRepeat); -#endif +#endif // VIEWPORT_H diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 73e8f537d9..bd72858ae6 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1516,7 +1516,7 @@ void Window::_validate_property(PropertyInfo &property) const { Transform2D Window::get_screen_transform() const { Transform2D embedder_transform = Transform2D(); if (_get_embedder()) { - embedder_transform.translate(get_position()); + embedder_transform.translate_local(get_position()); embedder_transform = _get_embedder()->get_screen_transform() * embedder_transform; } return embedder_transform * Viewport::get_screen_transform(); diff --git a/scene/multiplayer/SCsub b/scene/multiplayer/SCsub deleted file mode 100644 index fc61250247..0000000000 --- a/scene/multiplayer/SCsub +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index a37f81fe22..0878a9f78f 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -130,18 +130,14 @@ #include "scene/main/http_request.h" #include "scene/main/instance_placeholder.h" #include "scene/main/missing_node.h" +#include "scene/main/multiplayer_api.h" #include "scene/main/resource_preloader.h" #include "scene/main/scene_tree.h" #include "scene/main/timer.h" #include "scene/main/viewport.h" #include "scene/main/window.h" -#include "scene/multiplayer/multiplayer_spawner.h" -#include "scene/multiplayer/multiplayer_synchronizer.h" -#include "scene/multiplayer/scene_cache_interface.h" -#include "scene/multiplayer/scene_replication_interface.h" -#include "scene/multiplayer/scene_rpc_interface.h" #include "scene/resources/animation_library.h" -#include "scene/resources/audio_stream_sample.h" +#include "scene/resources/audio_stream_wav.h" #include "scene/resources/bit_map.h" #include "scene/resources/bone_map.h" #include "scene/resources/box_shape_3d.h" @@ -159,6 +155,7 @@ #include "scene/resources/gradient.h" #include "scene/resources/height_map_shape_3d.h" #include "scene/resources/immediate_mesh.h" +#include "scene/resources/label_settings.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/mesh_data_tool.h" @@ -173,6 +170,7 @@ #include "scene/resources/segment_shape_2d.h" #include "scene/resources/separation_ray_shape_2d.h" #include "scene/resources/separation_ray_shape_3d.h" +#include "scene/resources/shader_include.h" #include "scene/resources/skeleton_modification_2d.h" #include "scene/resources/skeleton_modification_2d_ccdik.h" #include "scene/resources/skeleton_modification_2d_fabrik.h" @@ -273,6 +271,9 @@ static Ref<ResourceFormatLoaderCompressedTexture3D> resource_loader_texture_3d; static Ref<ResourceFormatSaverShader> resource_saver_shader; static Ref<ResourceFormatLoaderShader> resource_loader_shader; +static Ref<ResourceFormatSaverShaderInclude> resource_saver_shader_include; +static Ref<ResourceFormatLoaderShaderInclude> resource_loader_shader_include; + void register_scene_types() { SceneStringNames::create(); @@ -301,6 +302,12 @@ void register_scene_types() { resource_loader_shader.instantiate(); ResourceLoader::add_resource_format_loader(resource_loader_shader, true); + resource_saver_shader_include.instantiate(); + ResourceSaver::add_resource_format_saver(resource_saver_shader_include, true); + + resource_loader_shader_include.instantiate(); + ResourceLoader::add_resource_format_loader(resource_loader_shader_include, true); + OS::get_singleton()->yield(); // may take time to init GDREGISTER_CLASS(Object); @@ -312,9 +319,13 @@ void register_scene_types() { GDREGISTER_ABSTRACT_CLASS(Viewport); GDREGISTER_CLASS(SubViewport); GDREGISTER_CLASS(ViewportTexture); + + GDREGISTER_ABSTRACT_CLASS(MultiplayerPeer); + GDREGISTER_CLASS(MultiplayerPeerExtension); + GDREGISTER_ABSTRACT_CLASS(MultiplayerAPI); + GDREGISTER_CLASS(MultiplayerAPIExtension); + GDREGISTER_CLASS(HTTPRequest); - GDREGISTER_CLASS(MultiplayerSpawner); - GDREGISTER_CLASS(MultiplayerSynchronizer); GDREGISTER_CLASS(Timer); GDREGISTER_CLASS(CanvasLayer); GDREGISTER_CLASS(CanvasModulate); @@ -570,6 +581,7 @@ void register_scene_types() { GDREGISTER_CLASS(Shader); GDREGISTER_CLASS(VisualShader); + GDREGISTER_CLASS(ShaderInclude); GDREGISTER_ABSTRACT_CLASS(VisualShaderNode); GDREGISTER_CLASS(VisualShaderNodeCustom); GDREGISTER_CLASS(VisualShaderNodeInput); @@ -860,10 +872,11 @@ void register_scene_types() { GDREGISTER_ABSTRACT_CLASS(Font); GDREGISTER_CLASS(FontFile); GDREGISTER_CLASS(FontVariation); + GDREGISTER_CLASS(SystemFont); GDREGISTER_CLASS(Curve); - GDREGISTER_CLASS(SceneReplicationConfig); + GDREGISTER_CLASS(LabelSettings); GDREGISTER_CLASS(TextLine); GDREGISTER_CLASS(TextParagraph); @@ -891,7 +904,7 @@ void register_scene_types() { GDREGISTER_CLASS(AudioStreamPlayer3D); #endif GDREGISTER_ABSTRACT_CLASS(VideoStream); - GDREGISTER_CLASS(AudioStreamSample); + GDREGISTER_CLASS(AudioStreamWAV); OS::get_singleton()->yield(); // may take time to init @@ -1078,6 +1091,9 @@ void register_scene_types() { ClassDB::add_compatibility_class("World", "World3D"); // Renamed during 4.0 alpha, added to ease transition between alphas. + ClassDB::add_compatibility_class("AudioStreamOGGVorbis", "AudioStreamOggVorbis"); + ClassDB::add_compatibility_class("AudioStreamSample", "AudioStreamWAV"); + ClassDB::add_compatibility_class("OGGPacketSequence", "OggPacketSequence"); ClassDB::add_compatibility_class("StreamCubemap", "CompressedCubemap"); ClassDB::add_compatibility_class("StreamCubemapArray", "CompressedCubemapArray"); ClassDB::add_compatibility_class("StreamTexture2D", "CompressedTexture2D"); @@ -1105,9 +1121,6 @@ void register_scene_types() { } SceneDebugger::initialize(); - SceneReplicationInterface::make_default(); - SceneRPCInterface::make_default(); - SceneCacheInterface::make_default(); } void initialize_theme() { @@ -1184,6 +1197,12 @@ void unregister_scene_types() { ResourceLoader::remove_resource_format_loader(resource_loader_shader); resource_loader_shader.unref(); + ResourceSaver::remove_resource_format_saver(resource_saver_shader_include); + resource_saver_shader_include.unref(); + + ResourceLoader::remove_resource_format_loader(resource_loader_shader_include); + resource_loader_shader_include.unref(); + // StandardMaterial3D is not initialised when 3D is disabled, so it shouldn't be cleaned up either #ifndef _3D_DISABLED BaseMaterial3D::finish_shaders(); diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h index f0a14387c1..dce8713976 100644 --- a/scene/register_scene_types.h +++ b/scene/register_scene_types.h @@ -36,4 +36,4 @@ void unregister_scene_types(); void initialize_theme(); -#endif +#endif // REGISTER_SCENE_TYPES_H diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 7183accc66..19545167c8 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -2302,7 +2302,7 @@ Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a } Quaternion Animation::_cubic_interpolate(const Quaternion &p_pre_a, const Quaternion &p_a, const Quaternion &p_b, const Quaternion &p_post_b, real_t p_c) const { - return p_a.cubic_slerp(p_b, p_pre_a, p_post_b, p_c); + return p_a.spherical_cubic_interpolate(p_b, p_pre_a, p_post_b, p_c); } Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, real_t p_c) const { @@ -2363,7 +2363,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a Quaternion pa = p_pre_a; Quaternion pb = p_post_b; - return a.cubic_slerp(b, pa, pb, p_c); + return a.spherical_cubic_interpolate(b, pa, pb, p_c); } case Variant::AABB: { AABB a = p_a; diff --git a/scene/resources/animation.h b/scene/resources/animation.h index b4528ccd3a..abbcaa92bc 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -488,4 +488,4 @@ VARIANT_ENUM_CAST(Animation::UpdateMode); VARIANT_ENUM_CAST(Animation::HandleMode); VARIANT_ENUM_CAST(Animation::LoopMode); -#endif +#endif // ANIMATION_H diff --git a/scene/resources/animation_library.h b/scene/resources/animation_library.h index 7a69cd140a..d63807b6d7 100644 --- a/scene/resources/animation_library.h +++ b/scene/resources/animation_library.h @@ -63,4 +63,4 @@ public: AnimationLibrary(); }; -#endif // ANIMATIONLIBRARY_H +#endif // ANIMATION_LIBRARY_H diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_wav.cpp index 30c222bdff..a87c8272ea 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_wav.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_stream_sample.cpp */ +/* audio_stream_wav.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "audio_stream_sample.h" +#include "audio_stream_wav.h" #include "core/io/file_access.h" #include "core/io/marshalls.h" -void AudioStreamPlaybackSample::start(float p_from_pos) { - if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) { +void AudioStreamPlaybackWAV::start(float p_from_pos) { + if (base->format == AudioStreamWAV::FORMAT_IMA_ADPCM) { //no seeking in IMA_ADPCM for (int i = 0; i < 2; i++) { ima_adpcm[i].step_index = 0; @@ -55,24 +55,24 @@ void AudioStreamPlaybackSample::start(float p_from_pos) { active = true; } -void AudioStreamPlaybackSample::stop() { +void AudioStreamPlaybackWAV::stop() { active = false; } -bool AudioStreamPlaybackSample::is_playing() const { +bool AudioStreamPlaybackWAV::is_playing() const { return active; } -int AudioStreamPlaybackSample::get_loop_count() const { +int AudioStreamPlaybackWAV::get_loop_count() const { return 0; } -float AudioStreamPlaybackSample::get_playback_position() const { +float AudioStreamPlaybackWAV::get_playback_position() const { return float(offset >> MIX_FRAC_BITS) / base->mix_rate; } -void AudioStreamPlaybackSample::seek(float p_time) { - if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) { +void AudioStreamPlaybackWAV::seek(float p_time) { + if (base->format == AudioStreamWAV::FORMAT_IMA_ADPCM) { return; //no seeking in ima-adpcm } @@ -87,7 +87,7 @@ void AudioStreamPlaybackSample::seek(float p_time) { } template <class Depth, bool is_stereo, bool is_ima_adpcm> -void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) { +void AudioStreamPlaybackWAV::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) { // this function will be compiled branchless by any decent compiler int32_t final, final_r, next, next_r; @@ -124,7 +124,7 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds ima_adpcm[i].last_nibble++; const uint8_t *src_ptr = (const uint8_t *)base->data; - src_ptr += AudioStreamSample::DATA_PAD; + src_ptr += AudioStreamWAV::DATA_PAD; uint8_t nbb = src_ptr[(ima_adpcm[i].last_nibble >> 1) * (is_stereo ? 2 : 1) + i]; nibble = (ima_adpcm[i].last_nibble & 1) ? (nbb >> 4) : (nbb & 0xF); @@ -221,7 +221,7 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds } } -int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { +int AudioStreamPlaybackWAV::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { if (!base->data || !active) { for (int i = 0; i < p_frames; i++) { p_buffer[i] = AudioFrame(0, 0); @@ -231,13 +231,13 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int int len = base->data_bytes; switch (base->format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: len /= 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: len /= 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: len *= 2; break; } @@ -251,13 +251,13 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int int64_t loop_begin_fp = ((int64_t)base->loop_begin << MIX_FRAC_BITS); int64_t loop_end_fp = ((int64_t)base->loop_end << MIX_FRAC_BITS); int64_t length_fp = ((int64_t)len << MIX_FRAC_BITS); - int64_t begin_limit = (base->loop_mode != AudioStreamSample::LOOP_DISABLED) ? loop_begin_fp : 0; - int64_t end_limit = (base->loop_mode != AudioStreamSample::LOOP_DISABLED) ? loop_end_fp : length_fp; + int64_t begin_limit = (base->loop_mode != AudioStreamWAV::LOOP_DISABLED) ? loop_begin_fp : 0; + int64_t end_limit = (base->loop_mode != AudioStreamWAV::LOOP_DISABLED) ? loop_end_fp : length_fp; bool is_stereo = base->stereo; int32_t todo = p_frames; - if (base->loop_mode == AudioStreamSample::LOOP_BACKWARD) { + if (base->loop_mode == AudioStreamWAV::LOOP_BACKWARD) { sign = -1; } @@ -271,20 +271,20 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int //looping - AudioStreamSample::LoopMode loop_format = base->loop_mode; - AudioStreamSample::Format format = base->format; + AudioStreamWAV::LoopMode loop_format = base->loop_mode; + AudioStreamWAV::Format format = base->format; /* audio data */ uint8_t *dataptr = (uint8_t *)base->data; - const void *data = dataptr + AudioStreamSample::DATA_PAD; + const void *data = dataptr + AudioStreamWAV::DATA_PAD; AudioFrame *dst_buff = p_buffer; - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { - if (loop_format != AudioStreamSample::LOOP_DISABLED) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED) { ima_adpcm[0].loop_pos = loop_begin_fp >> MIX_FRAC_BITS; ima_adpcm[1].loop_pos = loop_begin_fp >> MIX_FRAC_BITS; - loop_format = AudioStreamSample::LOOP_FORWARD; + loop_format = AudioStreamWAV::LOOP_FORWARD; } } @@ -297,9 +297,9 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int if (increment < 0) { /* going backwards */ - if (loop_format != AudioStreamSample::LOOP_DISABLED && offset < loop_begin_fp) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED && offset < loop_begin_fp) { /* loopstart reached */ - if (loop_format == AudioStreamSample::LOOP_PINGPONG) { + if (loop_format == AudioStreamWAV::LOOP_PINGPONG) { /* bounce ping pong */ offset = loop_begin_fp + (loop_begin_fp - offset); increment = -increment; @@ -317,10 +317,10 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } } else { /* going forward */ - if (loop_format != AudioStreamSample::LOOP_DISABLED && offset >= loop_end_fp) { + if (loop_format != AudioStreamWAV::LOOP_DISABLED && offset >= loop_end_fp) { /* loopend reached */ - if (loop_format == AudioStreamSample::LOOP_PINGPONG) { + if (loop_format == AudioStreamWAV::LOOP_PINGPONG) { /* bounce ping pong */ offset = loop_end_fp - (offset - loop_end_fp); increment = -increment; @@ -328,7 +328,7 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } else { /* go to loop-begin */ - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { for (int i = 0; i < 2; i++) { ima_adpcm[i].step_index = ima_adpcm[i].loop_step_index; ima_adpcm[i].predictor = ima_adpcm[i].loop_predictor; @@ -366,14 +366,14 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int todo -= target; switch (base->format) { - case AudioStreamSample::FORMAT_8_BITS: { + case AudioStreamWAV::FORMAT_8_BITS: { if (is_stereo) { do_resample<int8_t, true, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { do_resample<int8_t, false, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } } break; - case AudioStreamSample::FORMAT_16_BITS: { + case AudioStreamWAV::FORMAT_16_BITS: { if (is_stereo) { do_resample<int16_t, true, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { @@ -381,7 +381,7 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int } } break; - case AudioStreamSample::FORMAT_IMA_ADPCM: { + case AudioStreamWAV::FORMAT_IMA_ADPCM: { if (is_stereo) { do_resample<int8_t, true, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm); } else { @@ -406,69 +406,73 @@ int AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int return p_frames; } -AudioStreamPlaybackSample::AudioStreamPlaybackSample() {} +void AudioStreamPlaybackWAV::tag_used_streams() { + base->tag_used(get_playback_position()); +} + +AudioStreamPlaybackWAV::AudioStreamPlaybackWAV() {} ///////////////////// -void AudioStreamSample::set_format(Format p_format) { +void AudioStreamWAV::set_format(Format p_format) { format = p_format; } -AudioStreamSample::Format AudioStreamSample::get_format() const { +AudioStreamWAV::Format AudioStreamWAV::get_format() const { return format; } -void AudioStreamSample::set_loop_mode(LoopMode p_loop_mode) { +void AudioStreamWAV::set_loop_mode(LoopMode p_loop_mode) { loop_mode = p_loop_mode; } -AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const { +AudioStreamWAV::LoopMode AudioStreamWAV::get_loop_mode() const { return loop_mode; } -void AudioStreamSample::set_loop_begin(int p_frame) { +void AudioStreamWAV::set_loop_begin(int p_frame) { loop_begin = p_frame; } -int AudioStreamSample::get_loop_begin() const { +int AudioStreamWAV::get_loop_begin() const { return loop_begin; } -void AudioStreamSample::set_loop_end(int p_frame) { +void AudioStreamWAV::set_loop_end(int p_frame) { loop_end = p_frame; } -int AudioStreamSample::get_loop_end() const { +int AudioStreamWAV::get_loop_end() const { return loop_end; } -void AudioStreamSample::set_mix_rate(int p_hz) { +void AudioStreamWAV::set_mix_rate(int p_hz) { ERR_FAIL_COND(p_hz == 0); mix_rate = p_hz; } -int AudioStreamSample::get_mix_rate() const { +int AudioStreamWAV::get_mix_rate() const { return mix_rate; } -void AudioStreamSample::set_stereo(bool p_enable) { +void AudioStreamWAV::set_stereo(bool p_enable) { stereo = p_enable; } -bool AudioStreamSample::is_stereo() const { +bool AudioStreamWAV::is_stereo() const { return stereo; } -float AudioStreamSample::get_length() const { +float AudioStreamWAV::get_length() const { int len = data_bytes; switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: len /= 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: len /= 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: len *= 2; break; } @@ -480,11 +484,11 @@ float AudioStreamSample::get_length() const { return float(len) / mix_rate; } -bool AudioStreamSample::is_monophonic() const { +bool AudioStreamWAV::is_monophonic() const { return false; } -void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { +void AudioStreamWAV::set_data(const Vector<uint8_t> &p_data) { AudioServer::get_singleton()->lock(); if (data) { memfree(data); @@ -506,7 +510,7 @@ void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) { AudioServer::get_singleton()->unlock(); } -Vector<uint8_t> AudioStreamSample::get_data() const { +Vector<uint8_t> AudioStreamWAV::get_data() const { Vector<uint8_t> pv; if (data) { @@ -521,8 +525,8 @@ Vector<uint8_t> AudioStreamSample::get_data() const { return pv; } -Error AudioStreamSample::save_to_wav(const String &p_path) { - if (format == AudioStreamSample::FORMAT_IMA_ADPCM) { +Error AudioStreamWAV::save_to_wav(const String &p_path) { + if (format == AudioStreamWAV::FORMAT_IMA_ADPCM) { WARN_PRINT("Saving IMA_ADPC samples are not supported yet"); return ERR_UNAVAILABLE; } @@ -540,13 +544,13 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { int byte_pr_sample = 0; switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: byte_pr_sample = 1; break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: byte_pr_sample = 2; break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: byte_pr_sample = 4; break; } @@ -579,19 +583,19 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { Vector<uint8_t> data = get_data(); const uint8_t *read_data = data.ptr(); switch (format) { - case AudioStreamSample::FORMAT_8_BITS: + case AudioStreamWAV::FORMAT_8_BITS: for (unsigned int i = 0; i < data_bytes; i++) { uint8_t data_point = (read_data[i] + 128); file->store_8(data_point); } break; - case AudioStreamSample::FORMAT_16_BITS: + case AudioStreamWAV::FORMAT_16_BITS: for (unsigned int i = 0; i < data_bytes / 2; i++) { uint16_t data_point = decode_uint16(&read_data[i * 2]); file->store_16(data_point); } break; - case AudioStreamSample::FORMAT_IMA_ADPCM: + case AudioStreamWAV::FORMAT_IMA_ADPCM: //Unimplemented break; } @@ -599,40 +603,40 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { return OK; } -Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() { - Ref<AudioStreamPlaybackSample> sample; +Ref<AudioStreamPlayback> AudioStreamWAV::instantiate_playback() { + Ref<AudioStreamPlaybackWAV> sample; sample.instantiate(); - sample->base = Ref<AudioStreamSample>(this); + sample->base = Ref<AudioStreamWAV>(this); return sample; } -String AudioStreamSample::get_stream_name() const { +String AudioStreamWAV::get_stream_name() const { return ""; } -void AudioStreamSample::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamSample::set_data); - ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamSample::get_data); +void AudioStreamWAV::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamWAV::set_data); + ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamWAV::get_data); - ClassDB::bind_method(D_METHOD("set_format", "format"), &AudioStreamSample::set_format); - ClassDB::bind_method(D_METHOD("get_format"), &AudioStreamSample::get_format); + ClassDB::bind_method(D_METHOD("set_format", "format"), &AudioStreamWAV::set_format); + ClassDB::bind_method(D_METHOD("get_format"), &AudioStreamWAV::get_format); - ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &AudioStreamSample::set_loop_mode); - ClassDB::bind_method(D_METHOD("get_loop_mode"), &AudioStreamSample::get_loop_mode); + ClassDB::bind_method(D_METHOD("set_loop_mode", "loop_mode"), &AudioStreamWAV::set_loop_mode); + ClassDB::bind_method(D_METHOD("get_loop_mode"), &AudioStreamWAV::get_loop_mode); - ClassDB::bind_method(D_METHOD("set_loop_begin", "loop_begin"), &AudioStreamSample::set_loop_begin); - ClassDB::bind_method(D_METHOD("get_loop_begin"), &AudioStreamSample::get_loop_begin); + ClassDB::bind_method(D_METHOD("set_loop_begin", "loop_begin"), &AudioStreamWAV::set_loop_begin); + ClassDB::bind_method(D_METHOD("get_loop_begin"), &AudioStreamWAV::get_loop_begin); - ClassDB::bind_method(D_METHOD("set_loop_end", "loop_end"), &AudioStreamSample::set_loop_end); - ClassDB::bind_method(D_METHOD("get_loop_end"), &AudioStreamSample::get_loop_end); + ClassDB::bind_method(D_METHOD("set_loop_end", "loop_end"), &AudioStreamWAV::set_loop_end); + ClassDB::bind_method(D_METHOD("get_loop_end"), &AudioStreamWAV::get_loop_end); - ClassDB::bind_method(D_METHOD("set_mix_rate", "mix_rate"), &AudioStreamSample::set_mix_rate); - ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioStreamSample::get_mix_rate); + ClassDB::bind_method(D_METHOD("set_mix_rate", "mix_rate"), &AudioStreamWAV::set_mix_rate); + ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioStreamWAV::get_mix_rate); - ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamSample::set_stereo); - ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamSample::is_stereo); + ClassDB::bind_method(D_METHOD("set_stereo", "stereo"), &AudioStreamWAV::set_stereo); + ClassDB::bind_method(D_METHOD("is_stereo"), &AudioStreamWAV::is_stereo); - ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamSample::save_to_wav); + ClassDB::bind_method(D_METHOD("save_to_wav", "path"), &AudioStreamWAV::save_to_wav); ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_data", "get_data"); ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format"); @@ -652,9 +656,9 @@ void AudioStreamSample::_bind_methods() { BIND_ENUM_CONSTANT(LOOP_BACKWARD); } -AudioStreamSample::AudioStreamSample() {} +AudioStreamWAV::AudioStreamWAV() {} -AudioStreamSample::~AudioStreamSample() { +AudioStreamWAV::~AudioStreamWAV() { if (data) { memfree(data); data = nullptr; diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_wav.h index 357febc27a..d800388d96 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_wav.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* audio_stream_sample.h */ +/* audio_stream_wav.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIO_STREAM_SAMPLE_H -#define AUDIO_STREAM_SAMPLE_H +#ifndef AUDIO_STREAM_WAV_H +#define AUDIO_STREAM_WAV_H #include "servers/audio/audio_stream.h" -class AudioStreamSample; +class AudioStreamWAV; -class AudioStreamPlaybackSample : public AudioStreamPlayback { - GDCLASS(AudioStreamPlaybackSample, AudioStreamPlayback); +class AudioStreamPlaybackWAV : public AudioStreamPlayback { + GDCLASS(AudioStreamPlaybackWAV, AudioStreamPlayback); enum { MIX_FRAC_BITS = 13, MIX_FRAC_LEN = (1 << MIX_FRAC_BITS), @@ -57,8 +57,8 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback { int64_t offset = 0; int sign = 1; bool active = false; - friend class AudioStreamSample; - Ref<AudioStreamSample> base; + friend class AudioStreamWAV; + Ref<AudioStreamWAV> base; template <class Depth, bool is_stereo, bool is_ima_adpcm> void do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm); @@ -75,11 +75,13 @@ public: virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override; - AudioStreamPlaybackSample(); + virtual void tag_used_streams() override; + + AudioStreamPlaybackWAV(); }; -class AudioStreamSample : public AudioStream { - GDCLASS(AudioStreamSample, AudioStream); +class AudioStreamWAV : public AudioStream { + GDCLASS(AudioStreamWAV, AudioStream); RES_BASE_EXTENSION("sample") public: @@ -98,7 +100,7 @@ public: }; private: - friend class AudioStreamPlaybackSample; + friend class AudioStreamPlaybackWAV; enum { DATA_PAD = 16 //padding for interpolation @@ -144,14 +146,14 @@ public: Error save_to_wav(const String &p_path); - virtual Ref<AudioStreamPlayback> instance_playback() override; + virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; - AudioStreamSample(); - ~AudioStreamSample(); + AudioStreamWAV(); + ~AudioStreamWAV(); }; -VARIANT_ENUM_CAST(AudioStreamSample::Format) -VARIANT_ENUM_CAST(AudioStreamSample::LoopMode) +VARIANT_ENUM_CAST(AudioStreamWAV::Format) +VARIANT_ENUM_CAST(AudioStreamWAV::LoopMode) -#endif // AUDIO_STREAM_SAMPLE_H +#endif // AUDIO_STREAM_WAV_H diff --git a/scene/resources/box_shape_3d.h b/scene/resources/box_shape_3d.h index 4e6db893af..3dd0bb6cb7 100644 --- a/scene/resources/box_shape_3d.h +++ b/scene/resources/box_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BOX_SHAPE_H -#define BOX_SHAPE_H +#ifndef BOX_SHAPE_3D_H +#define BOX_SHAPE_3D_H #include "scene/resources/shape_3d.h" @@ -56,4 +56,4 @@ public: BoxShape3D(); }; -#endif // BOX_SHAPE_H +#endif // BOX_SHAPE_3D_H diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h index 4c039ab326..ad7f2e5b74 100644 --- a/scene/resources/capsule_shape_3d.h +++ b/scene/resources/capsule_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAPSULE_SHAPE_H -#define CAPSULE_SHAPE_H +#ifndef CAPSULE_SHAPE_3D_H +#define CAPSULE_SHAPE_3D_H #include "scene/resources/shape_3d.h" @@ -55,4 +55,4 @@ public: CapsuleShape3D(); }; -#endif // CAPSULE_SHAPE_H +#endif // CAPSULE_SHAPE_3D_H diff --git a/scene/resources/concave_polygon_shape_2d.h b/scene/resources/concave_polygon_shape_2d.h index 0f49a0d80f..d350d753b0 100644 --- a/scene/resources/concave_polygon_shape_2d.h +++ b/scene/resources/concave_polygon_shape_2d.h @@ -52,4 +52,4 @@ public: ConcavePolygonShape2D(); }; -#endif +#endif // CONCAVE_POLYGON_SHAPE_2D_H diff --git a/scene/resources/concave_polygon_shape_3d.h b/scene/resources/concave_polygon_shape_3d.h index a265590edd..68feacfa25 100644 --- a/scene/resources/concave_polygon_shape_3d.h +++ b/scene/resources/concave_polygon_shape_3d.h @@ -77,4 +77,4 @@ public: ConcavePolygonShape3D(); }; -#endif // CONCAVE_POLYGON_SHAPE_H +#endif // CONCAVE_POLYGON_SHAPE_3D_H diff --git a/scene/resources/convex_polygon_shape_3d.h b/scene/resources/convex_polygon_shape_3d.h index 930edb015d..5ca4d2a713 100644 --- a/scene/resources/convex_polygon_shape_3d.h +++ b/scene/resources/convex_polygon_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CONVEX_POLYGON_SHAPE_H -#define CONVEX_POLYGON_SHAPE_H +#ifndef CONVEX_POLYGON_SHAPE_3D_H +#define CONVEX_POLYGON_SHAPE_3D_H #include "scene/resources/shape_3d.h" @@ -52,4 +52,4 @@ public: ConvexPolygonShape3D(); }; -#endif // CONVEX_POLYGON_SHAPE_H +#endif // CONVEX_POLYGON_SHAPE_3D_H diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h index 65427423c8..f554358044 100644 --- a/scene/resources/cylinder_shape_3d.h +++ b/scene/resources/cylinder_shape_3d.h @@ -54,4 +54,4 @@ public: CylinderShape3D(); }; -#endif // CYLINDER_SHAPE_H +#endif // CYLINDER_SHAPE_3D_H diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index f777330a07..9b070a90cc 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -39,4 +39,4 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const void make_default_theme(float p_scale, Ref<Font> p_font, TextServer::SubpixelPositioning p_font_subpixel = TextServer::SUBPIXEL_POSITIONING_AUTO, TextServer::Hinting p_font_hinting = TextServer::HINTING_LIGHT, bool p_font_antialiased = true, bool p_font_msdf = false, bool p_font_generate_mipmaps = false); void clear_default_theme(); -#endif +#endif // DEFAULT_THEME_H diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 854bd34d6a..a8d4903dad 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1423,7 +1423,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_fog_light_energy", "get_fog_light_energy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_scatter", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_fog_sun_scatter", "get_fog_sun_scatter"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,16,0.0001"), "set_fog_density", "get_fog_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater"), "set_fog_density", "get_fog_density"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_aerial_perspective", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_aerial_perspective", "get_fog_aerial_perspective"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater,suffix:m"), "set_fog_height", "get_fog_height"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_lesser,or_greater"), "set_fog_height_density", "get_fog_height_density"); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index f61ac7fcaa..c469946b45 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -79,9 +79,9 @@ void Font::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_multiline_string_outline", "canvas_item", "pos", "text", "alignment", "width", "font_size", "max_lines", "size", "modulate", "brk_flags", "jst_flags", "direction", "orientation"), &Font::draw_multiline_string_outline, DEFVAL(HORIZONTAL_ALIGNMENT_LEFT), DEFVAL(-1), DEFVAL(DEFAULT_FONT_SIZE), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND), DEFVAL(TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND), DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(TextServer::ORIENTATION_HORIZONTAL)); // Drawing char. - ClassDB::bind_method(D_METHOD("get_char_size", "char"), &Font::get_char_size); - ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "modulate"), &Font::draw_char, DEFVAL(Color(1.0, 1.0, 1.0))); - ClassDB::bind_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "size", "modulate"), &Font::draw_char_outline, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0))); + ClassDB::bind_method(D_METHOD("get_char_size", "char", "font_size"), &Font::get_char_size); + ClassDB::bind_method(D_METHOD("draw_char", "canvas_item", "pos", "char", "font_size", "modulate"), &Font::draw_char, DEFVAL(Color(1.0, 1.0, 1.0))); + ClassDB::bind_method(D_METHOD("draw_char_outline", "canvas_item", "pos", "char", "font_size", "size", "modulate"), &Font::draw_char_outline, DEFVAL(-1), DEFVAL(Color(1.0, 1.0, 1.0))); // Helper functions. ClassDB::bind_method(D_METHOD("has_char", "char"), &Font::has_char); @@ -2693,3 +2693,374 @@ FontVariation::FontVariation() { FontVariation::~FontVariation() { reset_state(); } + +/*************************************************************************/ +/* SystemFont */ +/*************************************************************************/ + +void SystemFont::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &SystemFont::set_antialiased); + ClassDB::bind_method(D_METHOD("is_antialiased"), &SystemFont::is_antialiased); + + ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "generate_mipmaps"), &SystemFont::set_generate_mipmaps); + ClassDB::bind_method(D_METHOD("get_generate_mipmaps"), &SystemFont::get_generate_mipmaps); + + ClassDB::bind_method(D_METHOD("set_force_autohinter", "force_autohinter"), &SystemFont::set_force_autohinter); + ClassDB::bind_method(D_METHOD("is_force_autohinter"), &SystemFont::is_force_autohinter); + + ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &SystemFont::set_hinting); + ClassDB::bind_method(D_METHOD("get_hinting"), &SystemFont::get_hinting); + + ClassDB::bind_method(D_METHOD("set_subpixel_positioning", "subpixel_positioning"), &SystemFont::set_subpixel_positioning); + ClassDB::bind_method(D_METHOD("get_subpixel_positioning"), &SystemFont::get_subpixel_positioning); + + ClassDB::bind_method(D_METHOD("set_oversampling", "oversampling"), &SystemFont::set_oversampling); + ClassDB::bind_method(D_METHOD("get_oversampling"), &SystemFont::get_oversampling); + + ClassDB::bind_method(D_METHOD("get_font_names"), &SystemFont::get_font_names); + ClassDB::bind_method(D_METHOD("set_font_names", "names"), &SystemFont::set_font_names); + + ClassDB::bind_method(D_METHOD("set_font_style", "style"), &SystemFont::set_font_style); + + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "font_names"), "set_font_names", "get_font_names"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_FLAGS, "Bold,Italic"), "set_font_style", "get_font_style"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased"), "set_antialiased", "is_antialiased"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_mipmaps"), "set_generate_mipmaps", "get_generate_mipmaps"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter"), "set_force_autohinter", "is_force_autohinter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal"), "set_hinting", "get_hinting"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subpixel_positioning", PROPERTY_HINT_ENUM, "Disabled,Auto,One half of a pixel,One quarter of a pixel"), "set_subpixel_positioning", "get_subpixel_positioning"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), "set_oversampling", "get_oversampling"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Font")), "set_fallbacks", "get_fallbacks"); +} + +void SystemFont::_update_rids() const { + Ref<Font> f = _get_base_font_or_default(); + + rids.clear(); + if (fallbacks.is_empty() && f.is_valid()) { + RID rid = _get_rid(); + if (rid.is_valid()) { + rids.push_back(rid); + } + + const TypedArray<Font> &base_fallbacks = f->get_fallbacks(); + for (int i = 0; i < base_fallbacks.size(); i++) { + _update_rids_fb(base_fallbacks[i], 0); + } + } else { + _update_rids_fb(const_cast<SystemFont *>(this), 0); + } + dirty_rids = false; +} + +void SystemFont::_update_base_font() { + if (base_font.is_valid()) { + base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + base_font.unref(); + } + + face_indeces.clear(); + ftr_weight = 0; + ftr_italic = 0; + for (const String &E : names) { + if (E.is_empty()) { + continue; + } + + String path = OS::get_singleton()->get_system_font_path(E, style & TextServer::FONT_BOLD, style & TextServer::FONT_ITALIC); + if (path.is_empty()) { + continue; + } + Ref<FontFile> file; + file.instantiate(); + Error err = file->load_dynamic_font(path); + if (err != OK) { + continue; + } + + // If it's a font collection check all faces to match requested style. + for (int i = 0; i < file->get_face_count(); i++) { + file->set_face_index(0, i); + if (((file->get_font_style() & TextServer::FONT_BOLD) == (style & TextServer::FONT_BOLD)) && ((file->get_font_style() & TextServer::FONT_ITALIC) == (style & TextServer::FONT_ITALIC))) { + face_indeces.push_back(i); + } + } + if (face_indeces.is_empty()) { + face_indeces.push_back(0); + } + file->set_face_index(0, face_indeces[0]); + + // If it's a variable font, apply weight and italic coordinates to match requested style. + Dictionary ftr = file->get_supported_variation_list(); + if ((style & TextServer::FONT_BOLD) && ftr.has(TS->name_to_tag("weight"))) { + ftr_weight = 700; + } + if ((style & TextServer::FONT_ITALIC) && ftr.has(TS->name_to_tag("italic"))) { + ftr_italic = 1; + } + + // Apply font rendering settings. + file->set_antialiased(antialiased); + file->set_generate_mipmaps(mipmaps); + file->set_force_autohinter(force_autohinter); + file->set_hinting(hinting); + file->set_subpixel_positioning(subpixel_positioning); + file->set_oversampling(oversampling); + + base_font = file; + } + + if (base_font.is_valid()) { + base_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + } + + _invalidate_rids(); + notify_property_list_changed(); +} + +void SystemFont::reset_state() { + if (base_font.is_valid()) { + base_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + base_font.unref(); + } + + if (theme_font.is_valid()) { + theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(this), &Font::_invalidate_rids)); + theme_font.unref(); + } + + names.clear(); + face_indeces.clear(); + ftr_weight = 0; + ftr_italic = 0; + style = 0; + antialiased = true; + mipmaps = false; + force_autohinter = false; + hinting = TextServer::HINTING_LIGHT; + subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_DISABLED; + oversampling = 0.f; + + Font::reset_state(); +} + +Ref<Font> SystemFont::_get_base_font_or_default() const { + if (theme_font.is_valid()) { + theme_font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids)); + theme_font.unref(); + } + + if (base_font.is_valid()) { + return base_font; + } + + // Check the project-defined Theme resource. + if (Theme::get_project_default().is_valid()) { + List<StringName> theme_types; + Theme::get_project_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + + for (const StringName &E : theme_types) { + if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + } + return f; + } + } + } + + // Lastly, fall back on the items defined in the default Theme, if they exist. + if (Theme::get_default().is_valid()) { + List<StringName> theme_types; + Theme::get_default()->get_type_dependencies(get_class_name(), StringName(), &theme_types); + + for (const StringName &E : theme_types) { + if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) { + Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + } + return f; + } + } + + // If they don't exist, use any type to return the default/empty value. + Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName()); + if (f.is_valid()) { + theme_font = f; + theme_font->connect(CoreStringNames::get_singleton()->changed, callable_mp(reinterpret_cast<Font *>(const_cast<SystemFont *>(this)), &Font::_invalidate_rids), varray(), CONNECT_REFERENCE_COUNTED); + } + return f; + } + + return Ref<Font>(); +} + +void SystemFont::set_antialiased(bool p_antialiased) { + if (antialiased != p_antialiased) { + antialiased = p_antialiased; + if (base_font.is_valid()) { + base_font->set_antialiased(antialiased); + } + emit_changed(); + } +} + +bool SystemFont::is_antialiased() const { + return antialiased; +} + +void SystemFont::set_generate_mipmaps(bool p_generate_mipmaps) { + if (mipmaps != p_generate_mipmaps) { + mipmaps = p_generate_mipmaps; + if (base_font.is_valid()) { + base_font->set_generate_mipmaps(mipmaps); + } + emit_changed(); + } +} + +bool SystemFont::get_generate_mipmaps() const { + return mipmaps; +} + +void SystemFont::set_force_autohinter(bool p_force_autohinter) { + if (force_autohinter != p_force_autohinter) { + force_autohinter = p_force_autohinter; + if (base_font.is_valid()) { + base_font->set_force_autohinter(force_autohinter); + } + emit_changed(); + } +} + +bool SystemFont::is_force_autohinter() const { + return force_autohinter; +} + +void SystemFont::set_hinting(TextServer::Hinting p_hinting) { + if (hinting != p_hinting) { + hinting = p_hinting; + if (base_font.is_valid()) { + base_font->set_hinting(hinting); + } + emit_changed(); + } +} + +TextServer::Hinting SystemFont::get_hinting() const { + return hinting; +} + +void SystemFont::set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel) { + if (subpixel_positioning != p_subpixel) { + subpixel_positioning = p_subpixel; + if (base_font.is_valid()) { + base_font->set_subpixel_positioning(subpixel_positioning); + } + emit_changed(); + } +} + +TextServer::SubpixelPositioning SystemFont::get_subpixel_positioning() const { + return subpixel_positioning; +} + +void SystemFont::set_oversampling(real_t p_oversampling) { + if (oversampling != p_oversampling) { + oversampling = p_oversampling; + if (base_font.is_valid()) { + base_font->set_oversampling(oversampling); + } + emit_changed(); + } +} + +real_t SystemFont::get_oversampling() const { + return oversampling; +} + +void SystemFont::set_font_names(const PackedStringArray &p_names) { + if (names != p_names) { + names = p_names; + _update_base_font(); + } +} + +PackedStringArray SystemFont::get_font_names() const { + return names; +} + +void SystemFont::set_font_style(BitField<TextServer::FontStyle> p_style) { + if (style != p_style) { + style = p_style; + _update_base_font(); + } +} + +BitField<TextServer::FontStyle> SystemFont::get_font_style() const { + return style; +} + +int SystemFont::get_spacing(TextServer::SpacingType p_spacing) const { + if (base_font.is_valid()) { + return base_font->get_spacing(p_spacing); + } else { + return 0; + } +} + +RID SystemFont::find_variation(const Dictionary &p_variation_coordinates, int p_face_index, float p_strength, Transform2D p_transform) const { + Ref<Font> f = _get_base_font_or_default(); + if (f.is_valid()) { + Dictionary var = p_variation_coordinates; + if (ftr_weight > 0 && !var.has(TS->name_to_tag("weight"))) { + var[TS->name_to_tag("weight")] = ftr_weight; + } + if (ftr_italic > 0 && !var.has(TS->name_to_tag("italic"))) { + var[TS->name_to_tag("italic")] = ftr_italic; + } + + if (!face_indeces.is_empty()) { + int face_index = CLAMP(p_face_index, 0, face_indeces.size() - 1); + return f->find_variation(var, face_indeces[face_index], p_strength, p_transform); + } else { + return f->find_variation(var, 0, p_strength, p_transform); + } + } + return RID(); +} + +RID SystemFont::_get_rid() const { + Ref<Font> f = _get_base_font_or_default(); + if (f.is_valid()) { + if (!face_indeces.is_empty()) { + Dictionary var; + if (ftr_weight > 0) { + var[TS->name_to_tag("weight")] = ftr_weight; + } + if (ftr_italic > 0) { + var[TS->name_to_tag("italic")] = ftr_italic; + } + return f->find_variation(var, face_indeces[0]); + } else { + return f->_get_rid(); + } + } + return RID(); +} + +int64_t SystemFont::get_face_count() const { + return face_indeces.size(); +} + +SystemFont::SystemFont() { + /* NOP */ +} + +SystemFont::~SystemFont() { + reset_state(); +} diff --git a/scene/resources/font.h b/scene/resources/font.h index 7a42a4dfea..260b4e521f 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -41,7 +41,7 @@ class TextLine; class TextParagraph; /*************************************************************************/ -/* Font */ +/* Font */ /*************************************************************************/ class Font : public Resource { @@ -381,4 +381,74 @@ public: ~FontVariation(); }; -#endif /* FONT_H */ +/*************************************************************************/ +/* SystemFont */ +/*************************************************************************/ + +class SystemFont : public Font { + GDCLASS(SystemFont, Font); + + PackedStringArray names; + BitField<TextServer::FontStyle> style = 0; + + mutable Ref<Font> theme_font; + + Ref<FontFile> base_font; + Vector<int> face_indeces; + int ftr_weight = 0; + int ftr_italic = 0; + + bool antialiased = true; + bool mipmaps = false; + bool force_autohinter = false; + TextServer::Hinting hinting = TextServer::HINTING_LIGHT; + TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO; + real_t oversampling = 0.f; + +protected: + static void _bind_methods(); + + virtual void _update_base_font(); + virtual void _update_rids() const override; + + virtual void reset_state() override; + +public: + virtual Ref<Font> _get_base_font_or_default() const; + + virtual void set_antialiased(bool p_antialiased); + virtual bool is_antialiased() const; + + virtual void set_generate_mipmaps(bool p_generate_mipmaps); + virtual bool get_generate_mipmaps() const; + + virtual void set_force_autohinter(bool p_force_autohinter); + virtual bool is_force_autohinter() const; + + virtual void set_hinting(TextServer::Hinting p_hinting); + virtual TextServer::Hinting get_hinting() const; + + virtual void set_subpixel_positioning(TextServer::SubpixelPositioning p_subpixel); + virtual TextServer::SubpixelPositioning get_subpixel_positioning() const; + + virtual void set_oversampling(real_t p_oversampling); + virtual real_t get_oversampling() const; + + virtual void set_font_names(const PackedStringArray &p_names); + virtual PackedStringArray get_font_names() const; + + virtual void set_font_style(BitField<TextServer::FontStyle> p_style); + virtual BitField<TextServer::FontStyle> get_font_style() const override; + + virtual int get_spacing(TextServer::SpacingType p_spacing) const override; + + virtual RID find_variation(const Dictionary &p_variation_coordinates, int p_face_index = 0, float p_strength = 0.0, Transform2D p_transform = Transform2D()) const override; + virtual RID _get_rid() const override; + + int64_t get_face_count() const override; + + SystemFont(); + ~SystemFont(); +}; + +#endif // FONT_H diff --git a/scene/resources/height_map_shape_3d.h b/scene/resources/height_map_shape_3d.h index 79d1b15674..633238030b 100644 --- a/scene/resources/height_map_shape_3d.h +++ b/scene/resources/height_map_shape_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef HEIGHT_MAP_SHAPE_H -#define HEIGHT_MAP_SHAPE_H +#ifndef HEIGHT_MAP_SHAPE_3D_H +#define HEIGHT_MAP_SHAPE_3D_H #include "scene/resources/shape_3d.h" @@ -60,4 +60,4 @@ public: HeightMapShape3D(); }; -#endif /* !HEIGHT_MAP_SHAPE_H */ +#endif // HEIGHT_MAP_SHAPE_3D_H diff --git a/scene/resources/immediate_mesh.h b/scene/resources/immediate_mesh.h index e5f627ae8e..de10fdbfbe 100644 --- a/scene/resources/immediate_mesh.h +++ b/scene/resources/immediate_mesh.h @@ -115,4 +115,4 @@ public: ~ImmediateMesh(); }; -#endif // IMMEDIATEMESH_H +#endif // IMMEDIATE_MESH_H diff --git a/scene/resources/importer_mesh.h b/scene/resources/importer_mesh.h index 8f77597a58..bf1d0301d1 100644 --- a/scene/resources/importer_mesh.h +++ b/scene/resources/importer_mesh.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SCENE_IMPORTER_MESH_H -#define SCENE_IMPORTER_MESH_H +#ifndef IMPORTER_MESH_H +#define IMPORTER_MESH_H #include "core/io/resource.h" #include "core/templates/local_vector.h" @@ -130,4 +130,5 @@ public: Ref<ArrayMesh> get_mesh(const Ref<ArrayMesh> &p_base = Ref<ArrayMesh>()); void clear(); }; -#endif // SCENE_IMPORTER_MESH_H + +#endif // IMPORTER_MESH_H diff --git a/scene/resources/label_settings.cpp b/scene/resources/label_settings.cpp new file mode 100644 index 0000000000..e8b986b431 --- /dev/null +++ b/scene/resources/label_settings.cpp @@ -0,0 +1,187 @@ +/*************************************************************************/ +/* label_settings.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "label_settings.h" + +#include "core/core_string_names.h" + +void LabelSettings::_font_changed() { + emit_changed(); +} + +void LabelSettings::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_line_spacing", "spacing"), &LabelSettings::set_line_spacing); + ClassDB::bind_method(D_METHOD("get_line_spacing"), &LabelSettings::get_line_spacing); + + ClassDB::bind_method(D_METHOD("set_font", "font"), &LabelSettings::set_font); + ClassDB::bind_method(D_METHOD("get_font"), &LabelSettings::get_font); + + ClassDB::bind_method(D_METHOD("set_font_size", "size"), &LabelSettings::set_font_size); + ClassDB::bind_method(D_METHOD("get_font_size"), &LabelSettings::get_font_size); + + ClassDB::bind_method(D_METHOD("set_font_color", "color"), &LabelSettings::set_font_color); + ClassDB::bind_method(D_METHOD("get_font_color"), &LabelSettings::get_font_color); + + ClassDB::bind_method(D_METHOD("set_outline_size", "size"), &LabelSettings::set_outline_size); + ClassDB::bind_method(D_METHOD("get_outline_size"), &LabelSettings::get_outline_size); + + ClassDB::bind_method(D_METHOD("set_outline_color", "color"), &LabelSettings::set_outline_color); + ClassDB::bind_method(D_METHOD("get_outline_color"), &LabelSettings::get_outline_color); + + ClassDB::bind_method(D_METHOD("set_shadow_size", "size"), &LabelSettings::set_shadow_size); + ClassDB::bind_method(D_METHOD("get_shadow_size"), &LabelSettings::get_shadow_size); + + ClassDB::bind_method(D_METHOD("set_shadow_color", "color"), &LabelSettings::set_shadow_color); + ClassDB::bind_method(D_METHOD("get_shadow_color"), &LabelSettings::get_shadow_color); + + ClassDB::bind_method(D_METHOD("set_shadow_offset", "offset"), &LabelSettings::set_shadow_offset); + ClassDB::bind_method(D_METHOD("get_shadow_offset"), &LabelSettings::get_shadow_offset); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "line_spacing", PROPERTY_HINT_NONE, "suffix:px"), "set_line_spacing", "get_line_spacing"); + + ADD_GROUP("Font", "font"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_font", "get_font"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "font_size", PROPERTY_HINT_RANGE, "1,1024,1,or_greater,suffix:px"), "set_font_size", "get_font_size"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "font_color"), "set_font_color", "get_font_color"); + + ADD_GROUP("Outline", "outline"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,127,1,or_greater,suffix:px"), "set_outline_size", "get_outline_size"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color"); + + ADD_GROUP("Shadow", "shadow"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size", PROPERTY_HINT_RANGE, "0,127,1,or_greater,suffix:px"), "set_shadow_size", "get_shadow_size"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shadow_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_shadow_offset", "get_shadow_offset"); +} + +void LabelSettings::set_line_spacing(real_t p_spacing) { + if (line_spacing != p_spacing) { + line_spacing = p_spacing; + emit_changed(); + } +} + +real_t LabelSettings::get_line_spacing() const { + return line_spacing; +} + +void LabelSettings::set_font(const Ref<Font> &p_font) { + if (font != p_font) { + if (font.is_valid()) { + font->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed)); + } + font = p_font; + if (font.is_valid()) { + font->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &LabelSettings::_font_changed), varray(), CONNECT_REFERENCE_COUNTED); + } + emit_changed(); + } +} + +Ref<Font> LabelSettings::get_font() const { + return font; +} + +void LabelSettings::set_font_size(int p_size) { + if (font_size != p_size) { + font_size = p_size; + emit_changed(); + } +} + +int LabelSettings::get_font_size() const { + return font_size; +} + +void LabelSettings::set_font_color(const Color &p_color) { + if (font_color != p_color) { + font_color = p_color; + emit_changed(); + } +} + +Color LabelSettings::get_font_color() const { + return font_color; +} + +void LabelSettings::set_outline_size(int p_size) { + if (outline_size != p_size) { + outline_size = p_size; + emit_changed(); + } +} + +int LabelSettings::get_outline_size() const { + return outline_size; +} + +void LabelSettings::set_outline_color(const Color &p_color) { + if (outline_color != p_color) { + outline_color = p_color; + emit_changed(); + } +} + +Color LabelSettings::get_outline_color() const { + return outline_color; +} + +void LabelSettings::set_shadow_size(int p_size) { + if (shadow_size != p_size) { + shadow_size = p_size; + emit_changed(); + } +} + +int LabelSettings::get_shadow_size() const { + return shadow_size; +} + +void LabelSettings::set_shadow_color(const Color &p_color) { + if (shadow_color != p_color) { + shadow_color = p_color; + emit_changed(); + } +} + +Color LabelSettings::get_shadow_color() const { + return shadow_color; +} + +void LabelSettings::set_shadow_offset(const Vector2 &p_offset) { + if (shadow_offset != p_offset) { + shadow_offset = p_offset; + emit_changed(); + } +} + +Vector2 LabelSettings::get_shadow_offset() const { + return shadow_offset; +} diff --git a/scene/resources/label_settings.h b/scene/resources/label_settings.h new file mode 100644 index 0000000000..d2644a7484 --- /dev/null +++ b/scene/resources/label_settings.h @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* label_settings.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 LABEL_SETTINGS_H +#define LABEL_SETTINGS_H + +#include "core/io/resource.h" +#include "font.h" + +/*************************************************************************/ + +class LabelSettings : public Resource { + GDCLASS(LabelSettings, Resource); + + real_t line_spacing = 0; + + Ref<Font> font; + int font_size = Font::DEFAULT_FONT_SIZE; + Color font_color = Color(0.875, 0.875, 0.875); + + int outline_size = 0; + Color outline_color = Color(1, 1, 1); + + int shadow_size = 0; + Color shadow_color = Color(1, 1, 1); + Vector2 shadow_offset = Vector2(1, 1); + + void _font_changed(); + +protected: + static void _bind_methods(); + +public: + void set_line_spacing(real_t p_spacing); + real_t get_line_spacing() const; + + void set_font(const Ref<Font> &p_font); + Ref<Font> get_font() const; + + void set_font_size(int p_size); + int get_font_size() const; + + void set_font_color(const Color &p_color); + Color get_font_color() const; + + void set_outline_size(int p_size); + int get_outline_size() const; + + void set_outline_color(const Color &p_color); + Color get_outline_color() const; + + void set_shadow_size(int p_size); + int get_shadow_size() const; + + void set_shadow_color(const Color &p_color); + Color get_shadow_color() const; + + void set_shadow_offset(const Vector2 &p_offset); + Vector2 get_shadow_offset() const; +}; + +#endif // LABEL_SETTINGS_H diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index b7a3b677f5..f07232a3ad 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -202,7 +202,98 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { if (!shader.is_null()) { - shader->get_param_list(p_list); + List<PropertyInfo> list; + shader->get_param_list(&list, true); + + HashMap<String, HashMap<String, List<PropertyInfo>>> groups; + { + HashMap<String, List<PropertyInfo>> none_subgroup; + none_subgroup.insert("<None>", List<PropertyInfo>()); + groups.insert("<None>", none_subgroup); + } + + String last_group = "<None>"; + String last_subgroup = "<None>"; + + bool is_none_group_undefined = true; + bool is_none_group = true; + + for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) { + if (E->get().usage == PROPERTY_USAGE_GROUP) { + if (!E->get().name.is_empty()) { + Vector<String> vgroup = E->get().name.split("::"); + last_group = vgroup[0]; + if (vgroup.size() > 1) { + last_subgroup = vgroup[1]; + } else { + last_subgroup = "<None>"; + } + is_none_group = false; + + if (!groups.has(last_group)) { + PropertyInfo info; + info.usage = PROPERTY_USAGE_GROUP; + info.name = last_group; + + List<PropertyInfo> none_subgroup; + none_subgroup.push_back(info); + + HashMap<String, List<PropertyInfo>> subgroup_map; + subgroup_map.insert("<None>", none_subgroup); + + groups.insert(last_group, subgroup_map); + } + + if (!groups[last_group].has(last_subgroup)) { + PropertyInfo info; + info.usage = PROPERTY_USAGE_SUBGROUP; + info.name = last_subgroup; + + List<PropertyInfo> subgroup; + subgroup.push_back(info); + + groups[last_group].insert(last_subgroup, subgroup); + } + } else { + last_group = "<None>"; + last_subgroup = "<None>"; + is_none_group = true; + } + continue; // Pass group. + } + + if (is_none_group_undefined && is_none_group) { + is_none_group_undefined = false; + + PropertyInfo info; + info.usage = PROPERTY_USAGE_GROUP; + info.name = "Shader Param"; + groups["<None>"]["<None>"].push_back(info); + } + + PropertyInfo info = E->get(); + info.name = info.name; + groups[last_group][last_subgroup].push_back(info); + } + + // Sort groups alphabetically. + List<UniformProp> props; + for (HashMap<String, HashMap<String, List<PropertyInfo>>>::Iterator group = groups.begin(); group; ++group) { + for (HashMap<String, List<PropertyInfo>>::Iterator subgroup = group->value.begin(); subgroup; ++subgroup) { + for (List<PropertyInfo>::Element *item = subgroup->value.front(); item; item = item->next()) { + if (subgroup->key == "<None>") { + props.push_back({ group->key, item->get() }); + } else { + props.push_back({ group->key + "::" + subgroup->key, item->get() }); + } + } + } + } + props.sort_custom<UniformPropComparator>(); + + for (List<UniformProp>::Element *E = props.front(); E; E = E->next()) { + p_list->push_back(E->get().info); + } } } diff --git a/scene/resources/material.h b/scene/resources/material.h index b845fd68c8..8c04817c6b 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -84,6 +84,17 @@ class ShaderMaterial : public Material { HashMap<StringName, Variant> param_cache; + struct UniformProp { + String str; + PropertyInfo info; + }; + + struct UniformPropComparator { + bool operator()(const UniformProp &p_a, const UniformProp &p_b) const { + return p_a.str.naturalnocasecmp_to(p_b.str) < 0; + } + }; + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -809,4 +820,4 @@ public: ////////////////////// -#endif +#endif // MATERIAL_H diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 3e7b0a2808..ec9db89794 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -260,6 +260,64 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { return triangle_mesh; } +Ref<TriangleMesh> Mesh::generate_surface_triangle_mesh(int p_surface) const { + ERR_FAIL_INDEX_V(p_surface, get_surface_count(), Ref<TriangleMesh>()); + + if (surface_triangle_meshes.size() != get_surface_count()) { + surface_triangle_meshes.resize(get_surface_count()); + } + + if (surface_triangle_meshes[p_surface].is_valid()) { + return surface_triangle_meshes[p_surface]; + } + + int facecount = 0; + + if (surface_get_primitive_type(p_surface) != PRIMITIVE_TRIANGLES) { + return Ref<TriangleMesh>(); + } + + if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { + facecount += surface_get_array_index_len(p_surface); + } else { + facecount += surface_get_array_len(p_surface); + } + + Vector<Vector3> faces; + faces.resize(facecount); + Vector3 *facesw = faces.ptrw(); + + Array a = surface_get_arrays(p_surface); + ERR_FAIL_COND_V(a.is_empty(), Ref<TriangleMesh>()); + + int vc = surface_get_array_len(p_surface); + Vector<Vector3> vertices = a[ARRAY_VERTEX]; + const Vector3 *vr = vertices.ptr(); + int widx = 0; + + if (surface_get_format(p_surface) & ARRAY_FORMAT_INDEX) { + int ic = surface_get_array_index_len(p_surface); + Vector<int> indices = a[ARRAY_INDEX]; + const int *ir = indices.ptr(); + + for (int j = 0; j < ic; j++) { + int index = ir[j]; + facesw[widx++] = vr[index]; + } + + } else { + for (int j = 0; j < vc; j++) { + facesw[widx++] = vr[j]; + } + } + + Ref<TriangleMesh> triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); + triangle_mesh->create(faces); + surface_triangle_meshes.set(p_surface, triangle_mesh); + + return triangle_mesh; +} + void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) { if (debug_lines.size() > 0) { r_lines = debug_lines; @@ -320,6 +378,14 @@ Vector<Face3> Mesh::get_faces() const { return Vector<Face3>(); } +Vector<Face3> Mesh::get_surface_faces(int p_surface) const { + Ref<TriangleMesh> tm = generate_surface_triangle_mesh(p_surface); + if (tm.is_valid()) { + return tm->get_faces(); + } + return Vector<Face3>(); +} + Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const { if (p_simplify) { ConvexDecompositionSettings settings; diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index b166d12ead..142373ce7f 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -42,6 +42,7 @@ class Mesh : public Resource { GDCLASS(Mesh, Resource); mutable Ref<TriangleMesh> triangle_mesh; //cached + mutable Vector<Ref<TriangleMesh>> surface_triangle_meshes; //cached mutable Vector<Vector3> debug_lines; Size2i lightmap_size_hint; @@ -161,7 +162,9 @@ public: virtual AABB get_aabb() const; Vector<Face3> get_faces() const; + Vector<Face3> get_surface_faces(int p_surface) const; Ref<TriangleMesh> generate_triangle_mesh() const; + Ref<TriangleMesh> generate_surface_triangle_mesh(int p_surface) const; void generate_debug_mesh_lines(Vector<Vector3> &r_lines); void generate_debug_mesh_indices(Vector<Vector3> &r_points); @@ -362,4 +365,4 @@ public: ~PlaceholderMesh(); }; -#endif +#endif // MESH_H diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 30ada5365f..0f8cc76173 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -113,4 +113,4 @@ public: VARIANT_ENUM_CAST(MultiMesh::TransformFormat); -#endif // MULTI_MESH_H +#endif // MULTIMESH_H diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 5f8001c871..8e1a1d29b6 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -249,4 +249,4 @@ public: VARIANT_ENUM_CAST(PackedScene::GenEditState) -#endif // SCENE_PRELOADER_H +#endif // PACKED_SCENE_H diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index cb93211756..ec124e379f 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -595,4 +595,5 @@ public: }; VARIANT_ENUM_CAST(RibbonTrailMesh::Shape) -#endif + +#endif // PRIMITIVE_MESHES_H diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 66afb001fb..100e8ea7c6 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -65,14 +65,18 @@ Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, Varia return ERR_PARSE_ERROR; } - String unique_id = token.value; + if (p_data->no_placeholders) { + r_res.unref(); + } else { + String unique_id = token.value; - if (!p_data->resource_map.has(unique_id)) { - r_err_str = "Found unique_id reference before mapping, sub-resources stored out of order in resource file"; - return ERR_PARSE_ERROR; - } + if (!p_data->resource_map.has(unique_id)) { + r_err_str = "Found unique_id reference before mapping, sub-resources stored out of order in resource file"; + return ERR_PARSE_ERROR; + } - r_res = p_data->resource_map[unique_id]; + r_res = p_data->resource_map[unique_id]; + } VariantParser::get_token(p_stream, token, line, r_err_str); if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { @@ -91,11 +95,15 @@ Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, Varia return ERR_PARSE_ERROR; } - String id = token.value; + if (p_data->no_placeholders) { + r_res.unref(); + } else { + String id = token.value; - ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR); + ERR_FAIL_COND_V(!p_data->rev_external_resources.has(id), ERR_PARSE_ERROR); - r_res = p_data->rev_external_resources[id]; + r_res = p_data->rev_external_resources[id]; + } VariantParser::get_token(p_stream, token, line, r_err_str); if (token.type != VariantParser::TK_PARENTHESIS_CLOSE) { @@ -1066,7 +1074,7 @@ static void bs_save_unicode_string(Ref<FileAccess> p_f, const String &p_string, p_f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1); } -Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_path) { +Error ResourceLoaderText::save_as_binary(const String &p_path) { if (error) { return error; } @@ -1271,7 +1279,7 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa } if (next_tag.name == "node") { - //this is a node, must save one more! + // This is a node, must save one more! if (!is_scene) { error_text += "found the 'node' tag on a resource file!"; @@ -1346,6 +1354,126 @@ Error ResourceLoaderText::save_as_binary(Ref<FileAccess> p_f, const String &p_pa return OK; } +Error ResourceLoaderText::get_classes_used(HashSet<StringName> *r_classes) { + if (error) { + return error; + } + + ignore_resource_parsing = true; + + DummyReadData dummy_read; + dummy_read.no_placeholders = true; + VariantParser::ResourceParser rp; + rp.ext_func = _parse_ext_resource_dummys; + rp.sub_func = _parse_sub_resource_dummys; + rp.userdata = &dummy_read; + + while (next_tag.name == "ext_resource") { + error = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp); + + if (error) { + _printerr(); + return error; + } + } + + while (next_tag.name == "sub_resource" || next_tag.name == "resource") { + if (next_tag.name == "sub_resource") { + if (!next_tag.fields.has("type")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'type' in external resource tag"; + _printerr(); + return error; + } + + r_classes->insert(next_tag.fields["type"]); + + } else { + r_classes->insert(next_tag.fields["res_type"]); + } + + while (true) { + String assign; + Variant value; + + error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp); + + if (error) { + if (error == ERR_FILE_EOF) { + return OK; + } + + _printerr(); + return error; + } + + if (!assign.is_empty()) { + continue; + } else if (!next_tag.name.is_empty()) { + error = OK; + break; + } else { + error = ERR_FILE_CORRUPT; + error_text = "Premature end of file while parsing [sub_resource]"; + _printerr(); + return error; + } + } + } + + while (next_tag.name == "node") { + // This is a node, must save one more! + + if (!is_scene) { + error_text += "found the 'node' tag on a resource file!"; + _printerr(); + error = ERR_FILE_CORRUPT; + return error; + } + + if (!next_tag.fields.has("type")) { + error = ERR_FILE_CORRUPT; + error_text = "Missing 'type' in external resource tag"; + _printerr(); + return error; + } + + r_classes->insert(next_tag.fields["type"]); + + while (true) { + String assign; + Variant value; + + error = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, &rp); + + if (error) { + if (error == ERR_FILE_MISSING_DEPENDENCIES) { + // Resource loading error, just skip it. + } else if (error != ERR_FILE_EOF) { + _printerr(); + return error; + } else { + return OK; + } + } + + if (!assign.is_empty()) { + continue; + } else if (!next_tag.name.is_empty()) { + error = OK; + break; + } else { + error = ERR_FILE_CORRUPT; + error_text = "Premature end of file while parsing [sub_resource]"; + _printerr(); + return error; + } + } + } + + return OK; +} + String ResourceLoaderText::recognize(Ref<FileAccess> p_f) { error = OK; @@ -1473,6 +1601,26 @@ bool ResourceFormatLoaderText::handles_type(const String &p_type) const { return true; } +void ResourceFormatLoaderText::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) { + String ext = p_path.get_extension().to_lower(); + if (ext == "tscn") { + r_classes->insert("PackedScene"); + } + + // ...for anything else must test... + + Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); + if (f.is_null()) { + return; // Could not read. + } + + ResourceLoaderText loader; + loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); + loader.res_path = loader.local_path; + loader.open(f); + loader.get_classes_used(r_classes); +} + String ResourceFormatLoaderText::get_resource_type(const String &p_path) const { String ext = p_path.get_extension().to_lower(); if (ext == "tscn") { @@ -1561,7 +1709,7 @@ Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, loader.local_path = ProjectSettings::get_singleton()->localize_path(path); loader.res_path = loader.local_path; loader.open(f); - return loader.save_as_binary(f, p_dst_path); + return loader.save_as_binary(p_dst_path); } /*****************************************************************************************************/ diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 5c6a937bf2..69bb40502f 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -90,6 +90,7 @@ class ResourceLoaderText { }; struct DummyReadData { + bool no_placeholders = false; HashMap<Ref<Resource>, int> external_resources; HashMap<String, Ref<Resource>> rev_external_resources; HashMap<Ref<Resource>, int> resource_index_map; @@ -125,8 +126,9 @@ public: ResourceUID::ID get_uid(Ref<FileAccess> p_f); void get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types); Error rename_dependencies(Ref<FileAccess> p_f, const String &p_path, const HashMap<String, String> &p_map); + Error get_classes_used(HashSet<StringName> *r_classes); - Error save_as_binary(Ref<FileAccess> p_f, const String &p_path); + Error save_as_binary(const String &p_path); ResourceLoaderText(); }; @@ -137,6 +139,8 @@ public: 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; + virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes); + virtual String get_resource_type(const String &p_path) const; virtual ResourceUID::ID get_resource_uid(const String &p_path) const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); diff --git a/scene/resources/separation_ray_shape_2d.cpp b/scene/resources/separation_ray_shape_2d.cpp index 0d6aee47d8..fea41061fd 100644 --- a/scene/resources/separation_ray_shape_2d.cpp +++ b/scene/resources/separation_ray_shape_2d.cpp @@ -57,7 +57,7 @@ void SeparationRayShape2D::draw(const RID &p_to_rid, const Color &p_color) { Transform2D xf; xf.rotate(target_position.angle()); - xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); + xf.translate_local(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0)); Vector<Vector2> pts = { xf.xform(Vector2(arrow_size, 0)), diff --git a/scene/resources/separation_ray_shape_3d.h b/scene/resources/separation_ray_shape_3d.h index 0e750a48e6..ae08ff7887 100644 --- a/scene/resources/separation_ray_shape_3d.h +++ b/scene/resources/separation_ray_shape_3d.h @@ -28,8 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SEPARATION_RAY_SHAPE_H -#define SEPARATION_RAY_SHAPE_H +#ifndef SEPARATION_RAY_SHAPE_3D_H +#define SEPARATION_RAY_SHAPE_3D_H + #include "scene/resources/shape_3d.h" class SeparationRayShape3D : public Shape3D { @@ -53,4 +54,5 @@ public: SeparationRayShape3D(); }; -#endif // SEPARATION_RAY_SHAPE_H + +#endif // SEPARATION_RAY_SHAPE_3D_H diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index d49157b1b8..74031e02d7 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -33,6 +33,7 @@ #include "core/io/file_access.h" #include "scene/scene_string_names.h" #include "servers/rendering/shader_language.h" +#include "servers/rendering/shader_preprocessor.h" #include "servers/rendering_server.h" #include "texture.h" @@ -40,7 +41,23 @@ Shader::Mode Shader::get_mode() const { return mode; } +void Shader::_dependency_changed() { + RenderingServer::get_singleton()->shader_set_code(shader, RenderingServer::get_singleton()->shader_get_code(shader)); + params_cache_dirty = true; + + emit_changed(); +} + +void Shader::set_path(const String &p_path, bool p_take_over) { + Resource::set_path(p_path, p_take_over); + RS::get_singleton()->shader_set_path_hint(shader, p_path); +} + void Shader::set_code(const String &p_code) { + for (Ref<ShaderInclude> E : include_dependencies) { + E->disconnect(SNAME("changed"), callable_mp(this, &Shader::_dependency_changed)); + } + String type = ShaderLanguage::get_shader_type(p_code); if (type == "canvas_item") { @@ -55,7 +72,27 @@ void Shader::set_code(const String &p_code) { mode = MODE_SPATIAL; } - RenderingServer::get_singleton()->shader_set_code(shader, p_code); + code = p_code; + String pp_code = p_code; + + HashSet<Ref<ShaderInclude>> new_include_dependencies; + + { + // Preprocessor must run here and not in the server because: + // 1) Need to keep track of include dependencies at resource level + // 2) Server does not do interaction with Resource filetypes, this is a scene level feature. + ShaderPreprocessor preprocessor; + preprocessor.preprocess(p_code, pp_code, nullptr, nullptr, &new_include_dependencies); + } + + // This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower) + include_dependencies = new_include_dependencies; + + for (Ref<ShaderInclude> E : include_dependencies) { + E->connect(SNAME("changed"), callable_mp(this, &Shader::_dependency_changed)); + } + + RenderingServer::get_singleton()->shader_set_code(shader, pp_code); params_cache_dirty = true; emit_changed(); @@ -63,10 +100,10 @@ void Shader::set_code(const String &p_code) { String Shader::get_code() const { _update_shader(); - return RenderingServer::get_singleton()->shader_get_code(shader); + return code; } -void Shader::get_param_list(List<PropertyInfo> *p_params) const { +void Shader::get_param_list(List<PropertyInfo> *p_params, bool p_get_groups) const { _update_shader(); List<PropertyInfo> local; @@ -75,12 +112,16 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const { params_cache_dirty = false; for (PropertyInfo &pi : local) { - if (default_textures.has(pi.name)) { //do not show default textures + bool is_group = pi.usage == PROPERTY_USAGE_GROUP || pi.usage == PROPERTY_USAGE_SUBGROUP; + if (!p_get_groups && is_group) { continue; } - String original_name = pi.name; - pi.name = "shader_param/" + pi.name; - params_cache[pi.name] = original_name; + if (!is_group) { + if (default_textures.has(pi.name)) { //do not show default textures + continue; + } + params_cache[pi.name] = pi.name; + } if (p_params) { //small little hack if (pi.type == Variant::RID) { diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 11c9f60ce8..7aa14651a5 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -35,6 +35,7 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "scene/resources/texture.h" +#include "shader_include.h" class Shader : public Resource { GDCLASS(Shader, Resource); @@ -53,6 +54,8 @@ public: private: RID shader; Mode mode = MODE_SPATIAL; + HashSet<Ref<ShaderInclude>> include_dependencies; + String code; // hack the name of performance // shaders keep a list of ShaderMaterial -> RenderingServer name translations, to make @@ -61,6 +64,7 @@ private: mutable HashMap<StringName, StringName> params_cache; //map a shader param to a material param.. HashMap<StringName, HashMap<int, Ref<Texture2D>>> default_textures; + void _dependency_changed(); virtual void _update_shader() const; //used for visual shader protected: static void _bind_methods(); @@ -69,10 +73,12 @@ public: //void set_mode(Mode p_mode); virtual Mode get_mode() const; + virtual void set_path(const String &p_path, bool p_take_over = false) override; + void set_code(const String &p_code); String get_code() const; - void get_param_list(List<PropertyInfo> *p_params) const; + void get_param_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const; bool has_param(const StringName &p_param) const; void set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture, int p_index = 0); diff --git a/scene/resources/shader_include.cpp b/scene/resources/shader_include.cpp new file mode 100644 index 0000000000..b819128af3 --- /dev/null +++ b/scene/resources/shader_include.cpp @@ -0,0 +1,144 @@ +/*************************************************************************/ +/* shader_include.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "shader_include.h" +#include "servers/rendering/shader_language.h" +#include "servers/rendering/shader_preprocessor.h" + +void ShaderInclude::_dependency_changed() { + emit_changed(); +} + +void ShaderInclude::set_code(const String &p_code) { + HashSet<Ref<ShaderInclude>> new_dependencies; + code = p_code; + + for (Ref<ShaderInclude> E : dependencies) { + E->disconnect(SNAME("changed"), callable_mp(this, &ShaderInclude::_dependency_changed)); + } + + { + String pp_code; + ShaderPreprocessor preprocessor; + preprocessor.preprocess(p_code, pp_code, nullptr, nullptr, &new_dependencies); + } + + // This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower) + dependencies = new_dependencies; + + for (Ref<ShaderInclude> E : dependencies) { + E->connect(SNAME("changed"), callable_mp(this, &ShaderInclude::_dependency_changed)); + } + + emit_changed(); +} + +String ShaderInclude::get_code() const { + return code; +} + +void ShaderInclude::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_code", "code"), &ShaderInclude::set_code); + ClassDB::bind_method(D_METHOD("get_code"), &ShaderInclude::get_code); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code"); +} + +// ResourceFormatLoaderShaderInclude + +Ref<Resource> ResourceFormatLoaderShaderInclude::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; + } + + Ref<ShaderInclude> shader_inc; + shader_inc.instantiate(); + + Vector<uint8_t> buffer = FileAccess::get_file_as_array(p_path); + + String str; + str.parse_utf8((const char *)buffer.ptr(), buffer.size()); + + shader_inc->set_code(str); + + if (r_error) { + *r_error = OK; + } + + return shader_inc; +} + +void ResourceFormatLoaderShaderInclude::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("gdshaderinc"); +} + +bool ResourceFormatLoaderShaderInclude::handles_type(const String &p_type) const { + return (p_type == "ShaderInclude"); +} + +String ResourceFormatLoaderShaderInclude::get_resource_type(const String &p_path) const { + String extension = p_path.get_extension().to_lower(); + if (extension == "gdshaderinc") { + return "ShaderInclude"; + } + return ""; +} + +// ResourceFormatSaverShaderInclude + +Error ResourceFormatSaverShaderInclude::save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags) { + Ref<ShaderInclude> shader_inc = p_resource; + ERR_FAIL_COND_V(shader_inc.is_null(), ERR_INVALID_PARAMETER); + + String source = shader_inc->get_code(); + + Error error; + Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &error); + + ERR_FAIL_COND_V_MSG(error, error, "Cannot save shader include '" + p_path + "'."); + + file->store_string(source); + if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) { + return ERR_CANT_CREATE; + } + + return OK; +} + +void ResourceFormatSaverShaderInclude::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const { + const ShaderInclude *shader_inc = Object::cast_to<ShaderInclude>(*p_resource); + if (shader_inc != nullptr) { + p_extensions->push_back("gdshaderinc"); + } +} + +bool ResourceFormatSaverShaderInclude::recognize(const Ref<Resource> &p_resource) const { + return p_resource->get_class_name() == "ShaderInclude"; //only shader, not inherited +} diff --git a/scene/resources/shader_include.h b/scene/resources/shader_include.h new file mode 100644 index 0000000000..6f0deeef4e --- /dev/null +++ b/scene/resources/shader_include.h @@ -0,0 +1,71 @@ +/*************************************************************************/ +/* shader_include.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 SHADER_INCLUDE_H +#define SHADER_INCLUDE_H + +#include "core/io/resource.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/templates/hash_set.h" + +class ShaderInclude : public Resource { + GDCLASS(ShaderInclude, Resource); + OBJ_SAVE_TYPE(ShaderInclude); + +private: + String code; + HashSet<Ref<ShaderInclude>> dependencies; + void _dependency_changed(); + +protected: + static void _bind_methods(); + +public: + void set_code(const String &p_text); + String get_code() const; +}; + +class ResourceFormatLoaderShaderInclude : public ResourceFormatLoader { +public: + virtual Ref<Resource> 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; +}; + +class ResourceFormatSaverShaderInclude : public ResourceFormatSaver { +public: + virtual Error save(const String &p_path, const Ref<Resource> &p_resource, uint32_t p_flags = 0); + virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const; + virtual bool recognize(const Ref<Resource> &p_resource) const; +}; + +#endif // SHADER_INCLUDE_H diff --git a/scene/resources/shape_3d.h b/scene/resources/shape_3d.h index 77e79a269d..58fe723d89 100644 --- a/scene/resources/shape_3d.h +++ b/scene/resources/shape_3d.h @@ -73,4 +73,4 @@ public: ~Shape3D(); }; -#endif // SHAPE_H +#endif // SHAPE_3D_H diff --git a/scene/resources/skeleton_modification_2d.h b/scene/resources/skeleton_modification_2d.h index 3b9235ffd8..4c49119df0 100644 --- a/scene/resources/skeleton_modification_2d.h +++ b/scene/resources/skeleton_modification_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2D_H -#define SKELETONMODIFICATION2D_H +#ifndef SKELETON_MODIFICATION_2D_H +#define SKELETON_MODIFICATION_2D_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_stack_2d.h" @@ -86,4 +86,4 @@ public: SkeletonModification2D(); }; -#endif // SKELETONMODIFICATION2D_H +#endif // SKELETON_MODIFICATION_2D_H diff --git a/scene/resources/skeleton_modification_2d_ccdik.h b/scene/resources/skeleton_modification_2d_ccdik.h index 31485fa31f..e49dfca5b5 100644 --- a/scene/resources/skeleton_modification_2d_ccdik.h +++ b/scene/resources/skeleton_modification_2d_ccdik.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DCCDIK_H -#define SKELETONMODIFICATION2DCCDIK_H +#ifndef SKELETON_MODIFICATION_2D_CCDIK_H +#define SKELETON_MODIFICATION_2D_CCDIK_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -113,4 +113,4 @@ public: ~SkeletonModification2DCCDIK(); }; -#endif // SKELETONMODIFICATION2DCCDIK_H +#endif // SKELETON_MODIFICATION_2D_CCDIK_H diff --git a/scene/resources/skeleton_modification_2d_fabrik.h b/scene/resources/skeleton_modification_2d_fabrik.h index d5077084ef..4a875d039f 100644 --- a/scene/resources/skeleton_modification_2d_fabrik.h +++ b/scene/resources/skeleton_modification_2d_fabrik.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DFABRIK_H -#define SKELETONMODIFICATION2DFABRIK_H +#ifndef SKELETON_MODIFICATION_2D_FABRIK_H +#define SKELETON_MODIFICATION_2D_FABRIK_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -105,4 +105,4 @@ public: ~SkeletonModification2DFABRIK(); }; -#endif // SKELETONMODIFICATION2DFABRIK_H +#endif // SKELETON_MODIFICATION_2D_FABRIK_H diff --git a/scene/resources/skeleton_modification_2d_jiggle.h b/scene/resources/skeleton_modification_2d_jiggle.h index a1abca6564..b9080eafa9 100644 --- a/scene/resources/skeleton_modification_2d_jiggle.h +++ b/scene/resources/skeleton_modification_2d_jiggle.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DJIGGLE_H -#define SKELETONMODIFICATION2DJIGGLE_H +#ifndef SKELETON_MODIFICATION_2D_JIGGLE_H +#define SKELETON_MODIFICATION_2D_JIGGLE_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -136,4 +136,4 @@ public: ~SkeletonModification2DJiggle(); }; -#endif // SKELETONMODIFICATION2DJIGGLE_H +#endif // SKELETON_MODIFICATION_2D_JIGGLE_H diff --git a/scene/resources/skeleton_modification_2d_lookat.h b/scene/resources/skeleton_modification_2d_lookat.h index ff91b92e7d..e4d7afa605 100644 --- a/scene/resources/skeleton_modification_2d_lookat.h +++ b/scene/resources/skeleton_modification_2d_lookat.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DLOOKAT_H -#define SKELETONMODIFICATION2DLOOKAT_H +#ifndef SKELETON_MODIFICATION_2D_LOOKAT_H +#define SKELETON_MODIFICATION_2D_LOOKAT_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -97,4 +97,4 @@ public: ~SkeletonModification2DLookAt(); }; -#endif // SKELETONMODIFICATION2DLOOKAT_H +#endif // SKELETON_MODIFICATION_2D_LOOKAT_H diff --git a/scene/resources/skeleton_modification_2d_physicalbones.h b/scene/resources/skeleton_modification_2d_physicalbones.h index 373ff666ee..55482b2cca 100644 --- a/scene/resources/skeleton_modification_2d_physicalbones.h +++ b/scene/resources/skeleton_modification_2d_physicalbones.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DPHYSICALBONES_H -#define SKELETONMODIFICATION2DPHYSICALBONES_H +#ifndef SKELETON_MODIFICATION_2D_PHYSICALBONES_H +#define SKELETON_MODIFICATION_2D_PHYSICALBONES_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -79,4 +79,4 @@ public: ~SkeletonModification2DPhysicalBones(); }; -#endif // SKELETONMODIFICATION2DPHYSICALBONES_H +#endif // SKELETON_MODIFICATION_2D_PHYSICALBONES_H diff --git a/scene/resources/skeleton_modification_2d_stackholder.h b/scene/resources/skeleton_modification_2d_stackholder.h index 99d9f6f381..4da9fcc1f6 100644 --- a/scene/resources/skeleton_modification_2d_stackholder.h +++ b/scene/resources/skeleton_modification_2d_stackholder.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DSTACKHOLDER_H -#define SKELETONMODIFICATION2DSTACKHOLDER_H +#ifndef SKELETON_MODIFICATION_2D_STACKHOLDER_H +#define SKELETON_MODIFICATION_2D_STACKHOLDER_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -61,4 +61,4 @@ public: ~SkeletonModification2DStackHolder(); }; -#endif // SKELETONMODIFICATION2DSTACKHOLDER_H +#endif // SKELETON_MODIFICATION_2D_STACKHOLDER_H diff --git a/scene/resources/skeleton_modification_2d_twoboneik.h b/scene/resources/skeleton_modification_2d_twoboneik.h index fc14d35f70..e1dbb6cfda 100644 --- a/scene/resources/skeleton_modification_2d_twoboneik.h +++ b/scene/resources/skeleton_modification_2d_twoboneik.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION2DTWOBONEIK_H -#define SKELETONMODIFICATION2DTWOBONEIK_H +#ifndef SKELETON_MODIFICATION_2D_TWOBONEIK_H +#define SKELETON_MODIFICATION_2D_TWOBONEIK_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -104,4 +104,4 @@ public: ~SkeletonModification2DTwoBoneIK(); }; -#endif // SKELETONMODIFICATION2DTWOBONEIK_H +#endif // SKELETON_MODIFICATION_2D_TWOBONEIK_H diff --git a/scene/resources/skeleton_modification_3d.h b/scene/resources/skeleton_modification_3d.h index ab736fcbd2..6daf5efcd9 100644 --- a/scene/resources/skeleton_modification_3d.h +++ b/scene/resources/skeleton_modification_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATION3D_H -#define SKELETONMODIFICATION3D_H +#ifndef SKELETON_MODIFICATION_3D_H +#define SKELETON_MODIFICATION_3D_H #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_stack_3d.h" @@ -76,4 +76,4 @@ public: SkeletonModification3D(); }; -#endif // SKELETONMODIFICATION3D_H +#endif // SKELETON_MODIFICATION_3D_H diff --git a/scene/resources/skeleton_modification_3d_ccdik.h b/scene/resources/skeleton_modification_3d_ccdik.h index 873ab8aa5a..7098794038 100644 --- a/scene/resources/skeleton_modification_3d_ccdik.h +++ b/scene/resources/skeleton_modification_3d_ccdik.h @@ -32,8 +32,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DCCDIK_H -#define SKELETONMODIFICATION3DCCDIK_H +#ifndef SKELETON_MODIFICATION_3D_CCDIK_H +#define SKELETON_MODIFICATION_3D_CCDIK_H class SkeletonModification3DCCDIK : public SkeletonModification3D { GDCLASS(SkeletonModification3DCCDIK, SkeletonModification3D); @@ -111,4 +111,4 @@ public: ~SkeletonModification3DCCDIK(); }; -#endif //SKELETONMODIFICATION3DCCDIK_H +#endif // SKELETON_MODIFICATION_3D_CCDIK_H diff --git a/scene/resources/skeleton_modification_3d_fabrik.h b/scene/resources/skeleton_modification_3d_fabrik.h index cc4d3a5e20..3d66bb6d99 100644 --- a/scene/resources/skeleton_modification_3d_fabrik.h +++ b/scene/resources/skeleton_modification_3d_fabrik.h @@ -32,8 +32,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DFABRIK_H -#define SKELETONMODIFICATION3DFABRIK_H +#ifndef SKELETON_MODIFICATION_3D_FABRIK_H +#define SKELETON_MODIFICATION_3D_FABRIK_H class SkeletonModification3DFABRIK : public SkeletonModification3D { GDCLASS(SkeletonModification3DFABRIK, SkeletonModification3D); @@ -121,4 +121,4 @@ public: ~SkeletonModification3DFABRIK(); }; -#endif //SKELETONMODIFICATION3DFABRIK_H +#endif // SKELETON_MODIFICATION_3D_FABRIK_H diff --git a/scene/resources/skeleton_modification_3d_jiggle.h b/scene/resources/skeleton_modification_3d_jiggle.h index 7ec5ed4f11..f41ffcd58d 100644 --- a/scene/resources/skeleton_modification_3d_jiggle.h +++ b/scene/resources/skeleton_modification_3d_jiggle.h @@ -32,8 +32,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DJIGGLE_H -#define SKELETONMODIFICATION3DJIGGLE_H +#ifndef SKELETON_MODIFICATION_3D_JIGGLE_H +#define SKELETON_MODIFICATION_3D_JIGGLE_H class SkeletonModification3DJiggle : public SkeletonModification3D { GDCLASS(SkeletonModification3DJiggle, SkeletonModification3D); @@ -135,4 +135,4 @@ public: ~SkeletonModification3DJiggle(); }; -#endif //SKELETONMODIFICATION3DJIGGLE_H +#endif // SKELETON_MODIFICATION_3D_JIGGLE_H diff --git a/scene/resources/skeleton_modification_3d_lookat.h b/scene/resources/skeleton_modification_3d_lookat.h index 9f5120a0fd..4e5714b5dc 100644 --- a/scene/resources/skeleton_modification_3d_lookat.h +++ b/scene/resources/skeleton_modification_3d_lookat.h @@ -31,8 +31,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DLOOKAT_H -#define SKELETONMODIFICATION3DLOOKAT_H +#ifndef SKELETON_MODIFICATION_3D_LOOKAT_H +#define SKELETON_MODIFICATION_3D_LOOKAT_H class SkeletonModification3DLookAt : public SkeletonModification3D { GDCLASS(SkeletonModification3DLookAt, SkeletonModification3D); @@ -86,4 +86,4 @@ public: ~SkeletonModification3DLookAt(); }; -#endif //SKELETONMODIFICATION3DLOOKAT_H +#endif // SKELETON_MODIFICATION_3D_LOOKAT_H diff --git a/scene/resources/skeleton_modification_3d_stackholder.h b/scene/resources/skeleton_modification_3d_stackholder.h index 5780d7d43f..ae22099158 100644 --- a/scene/resources/skeleton_modification_3d_stackholder.h +++ b/scene/resources/skeleton_modification_3d_stackholder.h @@ -31,8 +31,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DSTACKHOLDER_H -#define SKELETONMODIFICATION3DSTACKHOLDER_H +#ifndef SKELETON_MODIFICATION_3D_STACKHOLDER_H +#define SKELETON_MODIFICATION_3D_STACKHOLDER_H class SkeletonModification3DStackHolder : public SkeletonModification3D { GDCLASS(SkeletonModification3DStackHolder, SkeletonModification3D); @@ -56,4 +56,4 @@ public: ~SkeletonModification3DStackHolder(); }; -#endif //SKELETONMODIFICATION3DSTACKHOLDER_H +#endif // SKELETON_MODIFICATION_3D_STACKHOLDER_H diff --git a/scene/resources/skeleton_modification_3d_twoboneik.h b/scene/resources/skeleton_modification_3d_twoboneik.h index a4ddc6cee7..57e8237511 100644 --- a/scene/resources/skeleton_modification_3d_twoboneik.h +++ b/scene/resources/skeleton_modification_3d_twoboneik.h @@ -31,8 +31,8 @@ #include "scene/3d/skeleton_3d.h" #include "scene/resources/skeleton_modification_3d.h" -#ifndef SKELETONMODIFICATION3DTWOBONEIK_H -#define SKELETONMODIFICATION3DTWOBONEIK_H +#ifndef SKELETON_MODIFICATION_3D_TWOBONEIK_H +#define SKELETON_MODIFICATION_3D_TWOBONEIK_H class SkeletonModification3DTwoBoneIK : public SkeletonModification3D { GDCLASS(SkeletonModification3DTwoBoneIK, SkeletonModification3D); @@ -115,4 +115,4 @@ public: ~SkeletonModification3DTwoBoneIK(); }; -#endif //SKELETONMODIFICATION3DTWOBONEIK_H +#endif // SKELETON_MODIFICATION_3D_TWOBONEIK_H diff --git a/scene/resources/skeleton_modification_stack_2d.h b/scene/resources/skeleton_modification_stack_2d.h index 7b5f8e0322..ceffd71368 100644 --- a/scene/resources/skeleton_modification_stack_2d.h +++ b/scene/resources/skeleton_modification_stack_2d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATIONSTACK2D_H -#define SKELETONMODIFICATIONSTACK2D_H +#ifndef SKELETON_MODIFICATION_STACK_2D_H +#define SKELETON_MODIFICATION_STACK_2D_H #include "scene/2d/skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" @@ -96,4 +96,4 @@ public: SkeletonModificationStack2D(); }; -#endif // SKELETONMODIFICATION2D_H +#endif // SKELETON_MODIFICATION_STACK_2D_H diff --git a/scene/resources/skeleton_modification_stack_3d.h b/scene/resources/skeleton_modification_stack_3d.h index 2c17fba2c5..4ff1bd1e33 100644 --- a/scene/resources/skeleton_modification_stack_3d.h +++ b/scene/resources/skeleton_modification_stack_3d.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SKELETONMODIFICATIONSTACK3D_H -#define SKELETONMODIFICATIONSTACK3D_H +#ifndef SKELETON_MODIFICATION_STACK_3D_H +#define SKELETON_MODIFICATION_STACK_3D_H #include "core/templates/local_vector.h" #include "scene/3d/skeleton_3d.h" @@ -88,4 +88,4 @@ public: SkeletonModificationStack3D(); }; -#endif // SKELETONMODIFICATIONSTACK3D_H +#endif // SKELETON_MODIFICATION_STACK_3D_H diff --git a/scene/resources/skeleton_profile.cpp b/scene/resources/skeleton_profile.cpp index 0714de470c..bfb4bb6e2b 100644 --- a/scene/resources/skeleton_profile.cpp +++ b/scene/resources/skeleton_profile.cpp @@ -123,12 +123,20 @@ bool SkeletonProfile::_get(const StringName &p_path, Variant &r_ret) const { void SkeletonProfile::_validate_property(PropertyInfo &property) const { if (is_read_only) { - if (property.name == ("group_size") || property.name == ("bone_size")) { + if (property.name == ("group_size") || property.name == ("bone_size") || property.name == ("root_bone") || property.name == ("scale_base_bone")) { property.usage = PROPERTY_USAGE_NO_EDITOR; return; } } + if (property.name == ("root_bone") || property.name == ("scale_base_bone")) { + String hint = ""; + for (int i = 0; i < bones.size(); i++) { + hint += i == 0 ? String(bones[i].bone_name) : "," + String(bones[i].bone_name); + } + property.hint_string = hint; + } + PackedStringArray split = property.name.split("/"); if (split.size() == 3 && split[0] == "bones") { if (split[2] == "bone_tail" && get_tail_direction(split[1].to_int()) != TAIL_DIRECTION_SPECIFIC_CHILD) { @@ -168,6 +176,28 @@ void SkeletonProfile::_get_property_list(List<PropertyInfo> *p_list) const { } } +StringName SkeletonProfile::get_root_bone() { + return root_bone; +} + +void SkeletonProfile::set_root_bone(StringName p_bone_name) { + if (is_read_only) { + return; + } + root_bone = p_bone_name; +} + +StringName SkeletonProfile::get_scale_base_bone() { + return scale_base_bone; +} + +void SkeletonProfile::set_scale_base_bone(StringName p_bone_name) { + if (is_read_only) { + return; + } + scale_base_bone = p_bone_name; +} + int SkeletonProfile::get_group_size() { return groups.size(); } @@ -361,6 +391,12 @@ bool SkeletonProfile::has_bone(StringName p_bone_name) { } void SkeletonProfile::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_root_bone", "bone_name"), &SkeletonProfile::set_root_bone); + ClassDB::bind_method(D_METHOD("get_root_bone"), &SkeletonProfile::get_root_bone); + + ClassDB::bind_method(D_METHOD("set_scale_base_bone", "bone_name"), &SkeletonProfile::set_scale_base_bone); + ClassDB::bind_method(D_METHOD("get_scale_base_bone"), &SkeletonProfile::get_scale_base_bone); + ClassDB::bind_method(D_METHOD("set_group_size", "size"), &SkeletonProfile::set_group_size); ClassDB::bind_method(D_METHOD("get_group_size"), &SkeletonProfile::get_group_size); @@ -396,6 +432,9 @@ void SkeletonProfile::_bind_methods() { ClassDB::bind_method(D_METHOD("get_group", "bone_idx"), &SkeletonProfile::get_group); ClassDB::bind_method(D_METHOD("set_group", "bone_idx", "group"), &SkeletonProfile::set_group); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "root_bone", PROPERTY_HINT_ENUM_SUGGESTION, ""), "set_root_bone", "get_root_bone"); + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "scale_base_bone", PROPERTY_HINT_ENUM_SUGGESTION, ""), "set_scale_base_bone", "get_scale_base_bone"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "group_size", PROPERTY_HINT_RANGE, "0,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Groups,groups/"), "set_group_size", "get_group_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_size", PROPERTY_HINT_RANGE, "0,100,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Bones,bones/"), "set_bone_size", "get_bone_size"); @@ -415,6 +454,9 @@ SkeletonProfile::~SkeletonProfile() { SkeletonProfileHumanoid::SkeletonProfileHumanoid() { is_read_only = true; + root_bone = "Root"; + scale_base_bone = "Hips"; + groups.resize(4); groups.write[0].group_name = "Body"; diff --git a/scene/resources/skeleton_profile.h b/scene/resources/skeleton_profile.h index d305311538..84dfca458e 100644 --- a/scene/resources/skeleton_profile.h +++ b/scene/resources/skeleton_profile.h @@ -64,6 +64,9 @@ protected: bool require = false; }; + StringName root_bone; + StringName scale_base_bone; + Vector<SkeletonProfileGroup> groups; Vector<SkeletonProfileBone> bones; @@ -74,6 +77,12 @@ protected: static void _bind_methods(); public: + StringName get_root_bone(); + void set_root_bone(StringName p_bone_name); + + StringName get_scale_base_bone(); + void set_scale_base_bone(StringName p_bone_name); + int get_group_size(); void set_group_size(int p_size); diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 5be8922ba4..61999af3c4 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -219,4 +219,4 @@ public: ~PhysicalSkyMaterial(); }; -#endif /* !SKY_MATERIAL_H */ +#endif // SKY_MATERIAL_H diff --git a/scene/resources/sphere_shape_3d.h b/scene/resources/sphere_shape_3d.h index 8f77378ef4..91d72e01ec 100644 --- a/scene/resources/sphere_shape_3d.h +++ b/scene/resources/sphere_shape_3d.h @@ -52,4 +52,4 @@ public: SphereShape3D(); }; -#endif // SPHERE_SHAPE_H +#endif // SPHERE_SHAPE_3D_H diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 3b3654775f..9f4f69d3ba 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -264,4 +264,4 @@ public: ~StyleBoxLine(); }; -#endif +#endif // STYLE_BOX_H diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 2d399ca3bf..6735d6623f 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -207,4 +207,4 @@ public: VARIANT_ENUM_CAST(SurfaceTool::CustomFormat) VARIANT_ENUM_CAST(SurfaceTool::SkinWeightCount) -#endif +#endif // SURFACE_TOOL_H diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h index 1243a9dbf7..69131ffbee 100644 --- a/scene/resources/syntax_highlighter.h +++ b/scene/resources/syntax_highlighter.h @@ -142,4 +142,4 @@ public: Color get_member_variable_color() const; }; -#endif +#endif // SYNTAX_HIGHLIGHTER_H diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h index 0c8cf855f0..168e4f5879 100644 --- a/scene/resources/text_file.h +++ b/scene/resources/text_file.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TEXTFILE_H -#define TEXTFILE_H +#ifndef TEXT_FILE_H +#define TEXT_FILE_H #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" @@ -51,4 +51,4 @@ public: Error load_text(const String &p_path); }; -#endif // TEXTFILE_H +#endif // TEXT_FILE_H diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index 4e7ec9315a..823d742d72 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -74,7 +74,7 @@ void TextLine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextLine::set_flags); ClassDB::bind_method(D_METHOD("get_flags"), &TextLine::get_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justication,Trim Edge Spaces After Justication,Justify Only After Last Tab,Constrain Ellipsis"), "set_flags", "get_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justification,Trim Edge Spaces After Justification,Justify Only After Last Tab,Constrain Ellipsis"), "set_flags", "get_flags"); ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &TextLine::set_text_overrun_behavior); ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &TextLine::get_text_overrun_behavior); diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 2d9e0066e1..43d3f329fa 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -77,12 +77,12 @@ void TextParagraph::_bind_methods() { ClassDB::bind_method(D_METHOD("set_break_flags", "flags"), &TextParagraph::set_break_flags); ClassDB::bind_method(D_METHOD("get_break_flags"), &TextParagraph::get_break_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "break_flags", PROPERTY_HINT_FLAGS, "Mandatory,Word Bouns,Grapheme Bound,Adaptive"), "set_break_flags", "get_break_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "break_flags", PROPERTY_HINT_FLAGS, "Mandatory,Word Bound,Grapheme Bound,Adaptive"), "set_break_flags", "get_break_flags"); ClassDB::bind_method(D_METHOD("set_justification_flags", "flags"), &TextParagraph::set_justification_flags); ClassDB::bind_method(D_METHOD("get_justification_flags"), &TextParagraph::get_justification_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "justification_flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justication,Trim Edge Spaces After Justication,Justify Only After Last Tab,Constrain Ellipsis"), "set_justification_flags", "get_justification_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "justification_flags", PROPERTY_HINT_FLAGS, "Kashida Justification,Word Justification,Trim Edge Spaces After Justification,Justify Only After Last Tab,Constrain Ellipsis"), "set_justification_flags", "get_justification_flags"); ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &TextParagraph::set_text_overrun_behavior); ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &TextParagraph::get_text_overrun_behavior); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 21ae62c92e..0aefe34f7d 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -323,6 +323,7 @@ void ImageTexture::_bind_methods() { ClassDB::bind_static_method("ImageTexture", D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image); ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format); + ClassDB::bind_method(D_METHOD("set_image", "image"), &ImageTexture::set_image); ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update); ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override); } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index b107a2a70d..36b193c5d4 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -1106,4 +1106,4 @@ public: PlaceholderTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {} }; -#endif +#endif // TEXTURE_H diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 87d7d2fdea..a2aca5e61f 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -256,4 +256,4 @@ public: VARIANT_ENUM_CAST(Theme::DataType); -#endif +#endif // THEME_H diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 22b5ef0108..a59870f4a9 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -2467,9 +2467,42 @@ Vector<Point2> TileSet::_get_half_offset_side_terrain_peering_bit_polygon(Vector } void TileSet::reset_state() { + // Rendering occlusion_layers.clear(); + tile_lines_mesh.instantiate(); + tile_filled_mesh.instantiate(); + tile_meshes_dirty = true; + + // Physics physics_layers.clear(); + + // Terrains + terrain_sets.clear(); + terrain_meshes.clear(); + terrain_peering_bits_meshes.clear(); + per_terrain_pattern_tiles.clear(); + terrains_cache_dirty = true; + + // Navigation + navigation_layers.clear(); + custom_data_layers.clear(); + custom_data_layers_by_name.clear(); + + // Proxies + source_level_proxies.clear(); + coords_level_proxies.clear(); + alternative_level_proxies.clear(); + +#ifndef DISABLE_DEPRECATED + for (const KeyValue<int, CompatibilityTileData *> &E : compatibility_data) { + memdelete(E.value); + } + compatibility_data.clear(); +#endif // DISABLE_DEPRECATED + while (!source_ids.is_empty()) { + remove_source(source_ids[0]); + } } const Vector2i TileSetSource::INVALID_ATLAS_COORDS = Vector2i(-1, -1); @@ -3457,6 +3490,10 @@ void TileSetSource::set_tile_set(const TileSet *p_tile_set) { tile_set = p_tile_set; } +void TileSetSource::reset_state() { + tile_set = nullptr; +}; + void TileSetSource::_bind_methods() { // Base tiles ClassDB::bind_method(D_METHOD("get_tiles_count"), &TileSetSource::get_tiles_count); @@ -3640,12 +3677,17 @@ void TileSetAtlasSource::remove_custom_data_layer(int p_index) { } void TileSetAtlasSource::reset_state() { - // Reset all TileData. + tile_set = nullptr; + for (KeyValue<Vector2i, TileAlternativesData> &E_tile : tiles) { - for (KeyValue<int, TileData *> &E_alternative : E_tile.value.alternatives) { - E_alternative.value->reset_state(); + for (const KeyValue<int, TileData *> &E_tile_data : E_tile.value.alternatives) { + memdelete(E_tile_data.value); } } + _coords_mapping_cache.clear(); + tiles.clear(); + tiles_ids.clear(); + _queue_update_padded_texture(); } void TileSetAtlasSource::set_texture(Ref<Texture2D> p_texture) { @@ -4975,13 +5017,6 @@ void TileData::remove_custom_data_layer(int p_index) { custom_data.remove_at(p_index); } -void TileData::reset_state() { - occluders.clear(); - physics.clear(); - navigation.clear(); - custom_data.clear(); -} - void TileData::set_allow_transform(bool p_allow_transform) { allow_transform = p_allow_transform; } diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 7368d2bd87..bfd21190d8 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -569,7 +569,7 @@ public: virtual void add_custom_data_layer(int p_index){}; virtual void move_custom_data_layer(int p_from_index, int p_to_pos){}; virtual void remove_custom_data_layer(int p_index){}; - virtual void reset_state() override{}; + virtual void reset_state() override; // Tiles. virtual int get_tiles_count() const = 0; @@ -847,7 +847,6 @@ public: void add_custom_data_layer(int p_index); void move_custom_data_layer(int p_from_index, int p_to_pos); void remove_custom_data_layer(int p_index); - void reset_state(); void set_allow_transform(bool p_allow_transform); bool is_allowing_transform() const; diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h index 3e154d539b..35686b293c 100644 --- a/scene/resources/video_stream.h +++ b/scene/resources/video_stream.h @@ -72,7 +72,7 @@ class VideoStream : public Resource { public: virtual void set_audio_track(int p_track) = 0; - virtual Ref<VideoStreamPlayback> instance_playback() = 0; + virtual Ref<VideoStreamPlayback> instantiate_playback() = 0; }; -#endif +#endif // VIDEO_STREAM_H diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index b68cce9dda..5e0627a7d9 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -967,6 +967,12 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from ERR_FAIL_COND(!g->nodes.has(p_to_node)); ERR_FAIL_INDEX(p_to_port, g->nodes[p_to_node].node->get_input_port_count()); + for (const Connection &E : g->connections) { + if (E.from_node == p_from_node && E.from_port == p_from_port && E.to_node == p_to_node && E.to_port == p_to_port) { + return; + } + } + Connection c; c.from_node = p_from_node; c.from_port = p_from_port; @@ -3745,7 +3751,7 @@ String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::T } return vformat(RTR("This uniform type does not support the '%s' qualifier."), qualifier_str); } else if (qualifier == Qualifier::QUAL_GLOBAL) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(uniform_name); + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(uniform_name); if (gvt == RS::GLOBAL_VAR_TYPE_MAX) { return vformat(RTR("Global uniform '%s' does not exist.\nCreate it in the Project Settings."), uniform_name); } diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h index 05a059373b..64acb6d18f 100644 --- a/scene/resources/visual_shader_particle_nodes.h +++ b/scene/resources/visual_shader_particle_nodes.h @@ -352,4 +352,4 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeParticleEmit::EmitFlags) -#endif +#endif // VISUAL_SHADER_PARTICLE_NODES_H diff --git a/scene/resources/world_boundary_shape_3d.h b/scene/resources/world_boundary_shape_3d.h index 5378bc52c7..5c34767106 100644 --- a/scene/resources/world_boundary_shape_3d.h +++ b/scene/resources/world_boundary_shape_3d.h @@ -53,4 +53,5 @@ public: WorldBoundaryShape3D(); }; -#endif // WORLD_BOUNDARY_SHAPE_H + +#endif // WORLD_BOUNDARY_SHAPE_3D_H diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h index 232a8d5e1f..8f47e64d8b 100644 --- a/servers/audio/audio_driver_dummy.h +++ b/servers/audio/audio_driver_dummy.h @@ -85,4 +85,4 @@ public: ~AudioDriverDummy() {} }; -#endif +#endif // AUDIO_DRIVER_DUMMY_H diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h index 3a0578679d..653d04595e 100644 --- a/servers/audio/audio_effect.h +++ b/servers/audio/audio_effect.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECT_H -#define AUDIOEFFECT_H +#ifndef AUDIO_EFFECT_H +#define AUDIO_EFFECT_H #include "core/io/resource.h" #include "core/math/audio_frame.h" @@ -62,4 +62,4 @@ public: AudioEffect(); }; -#endif // AUDIOEFFECT_H +#endif // AUDIO_EFFECT_H diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 0408db2539..80485845c9 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -83,6 +83,10 @@ int AudioStreamPlayback::mix(AudioFrame *p_buffer, float p_rate_scale, int p_fra return 0; } +void AudioStreamPlayback::tag_used_streams() { + GDVIRTUAL_CALL(_tag_used_streams); +} + void AudioStreamPlayback::_bind_methods() { GDVIRTUAL_BIND(_start, "from_pos") GDVIRTUAL_BIND(_stop) @@ -91,6 +95,7 @@ void AudioStreamPlayback::_bind_methods() { GDVIRTUAL_BIND(_get_playback_position) GDVIRTUAL_BIND(_seek, "position") GDVIRTUAL_BIND(_mix, "buffer", "rate_scale", "frames"); + GDVIRTUAL_BIND(_tag_used_streams); } ////////////////////////////// @@ -187,9 +192,9 @@ int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, //////////////////////////////// -Ref<AudioStreamPlayback> AudioStream::instance_playback() { +Ref<AudioStreamPlayback> AudioStream::instantiate_playback() { Ref<AudioStreamPlayback> ret; - if (GDVIRTUAL_CALL(_instance_playback, ret)) { + if (GDVIRTUAL_CALL(_instantiate_playback, ret)) { return ret; } ERR_FAIL_V_MSG(Ref<AudioStreamPlayback>(), "Method must be implemented!"); @@ -218,19 +223,74 @@ bool AudioStream::is_monophonic() const { return true; } +double AudioStream::get_bpm() const { + double ret = 0; + if (GDVIRTUAL_CALL(_get_bpm, ret)) { + return ret; + } + return 0; +} + +bool AudioStream::has_loop() const { + bool ret = 0; + if (GDVIRTUAL_CALL(_has_loop, ret)) { + return ret; + } + return 0; +} + +int AudioStream::get_bar_beats() const { + int ret = 0; + if (GDVIRTUAL_CALL(_get_bar_beats, ret)) { + return ret; + } + return 0; +} + +int AudioStream::get_beat_count() const { + int ret = 0; + if (GDVIRTUAL_CALL(_get_beat_count, ret)) { + return ret; + } + return 0; +} + +void AudioStream::tag_used(float p_offset) { + if (tagged_frame != AudioServer::get_singleton()->get_mixed_frames()) { + offset_count = 0; + tagged_frame = AudioServer::get_singleton()->get_mixed_frames(); + } + if (offset_count < MAX_TAGGED_OFFSETS) { + tagged_offsets[offset_count++] = p_offset; + } +} + +uint64_t AudioStream::get_tagged_frame() const { + return tagged_frame; +} +uint32_t AudioStream::get_tagged_frame_count() const { + return offset_count; +} +float AudioStream::get_tagged_frame_offset(int p_index) const { + ERR_FAIL_INDEX_V(p_index, MAX_TAGGED_OFFSETS, 0); + return tagged_offsets[p_index]; +} + void AudioStream::_bind_methods() { ClassDB::bind_method(D_METHOD("get_length"), &AudioStream::get_length); ClassDB::bind_method(D_METHOD("is_monophonic"), &AudioStream::is_monophonic); - ClassDB::bind_method(D_METHOD("instance_playback"), &AudioStream::instance_playback); - GDVIRTUAL_BIND(_instance_playback); + ClassDB::bind_method(D_METHOD("instantiate_playback"), &AudioStream::instantiate_playback); + GDVIRTUAL_BIND(_instantiate_playback); GDVIRTUAL_BIND(_get_stream_name); GDVIRTUAL_BIND(_get_length); GDVIRTUAL_BIND(_is_monophonic); + GDVIRTUAL_BIND(_get_bpm) + GDVIRTUAL_BIND(_get_beat_count) } //////////////////////////////// -Ref<AudioStreamPlayback> AudioStreamMicrophone::instance_playback() { +Ref<AudioStreamPlayback> AudioStreamMicrophone::instantiate_playback() { Ref<AudioStreamPlaybackMicrophone> playback; playback.instantiate(); @@ -363,6 +423,10 @@ void AudioStreamPlaybackMicrophone::seek(float p_time) { // Can't seek a microphone input } +void AudioStreamPlaybackMicrophone::tag_used_streams() { + microphone->tag_used(0); +} + AudioStreamPlaybackMicrophone::~AudioStreamPlaybackMicrophone() { microphone->playbacks.erase(this); stop(); @@ -490,7 +554,7 @@ Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_random() { for (PoolEntry &entry : local_pool) { cumulative_weight += entry.weight; if (cumulative_weight > chosen_cumulative_weight) { - playback->playback = entry.stream->instance_playback(); + playback->playback = entry.stream->instantiate_playback(); last_playback = entry.stream; break; } @@ -498,7 +562,7 @@ Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_random() { if (playback->playback.is_null()) { // This indicates a floating point error. Take the last element. last_playback = local_pool[local_pool.size() - 1].stream; - playback->playback = local_pool.write[local_pool.size() - 1].stream->instance_playback(); + playback->playback = local_pool.write[local_pool.size() - 1].stream->instantiate_playback(); } return playback; } @@ -532,14 +596,14 @@ Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_no_repeats() { cumulative_weight += entry.weight; if (cumulative_weight > chosen_cumulative_weight) { last_playback = entry.stream; - playback->playback = entry.stream->instance_playback(); + playback->playback = entry.stream->instantiate_playback(); break; } } if (playback->playback.is_null()) { // This indicates a floating point error. Take the last element. last_playback = local_pool[local_pool.size() - 1].stream; - playback->playback = local_pool.write[local_pool.size() - 1].stream->instance_playback(); + playback->playback = local_pool.write[local_pool.size() - 1].stream->instantiate_playback(); } return playback; } @@ -568,7 +632,7 @@ Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_sequential() { for (Ref<AudioStream> &entry : local_pool) { if (found_last_stream) { last_playback = entry; - playback->playback = entry->instance_playback(); + playback->playback = entry->instantiate_playback(); break; } if (entry == last_playback) { @@ -578,12 +642,12 @@ Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_sequential() { if (playback->playback.is_null()) { // Wrap around last_playback = local_pool[0]; - playback->playback = local_pool.write[0]->instance_playback(); + playback->playback = local_pool.write[0]->instantiate_playback(); } return playback; } -Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback() { +Ref<AudioStreamPlayback> AudioStreamRandomizer::instantiate_playback() { switch (playback_mode) { case PLAYBACK_RANDOM: return instance_playback_random(); @@ -762,6 +826,14 @@ void AudioStreamPlaybackRandomizer::seek(float p_time) { } } +void AudioStreamPlaybackRandomizer::tag_used_streams() { + Ref<AudioStreamPlayback> p = playing; // Thread safety + if (p.is_valid()) { + p->tag_used_streams(); + } + randomizer->tag_used(0); +} + int AudioStreamPlaybackRandomizer::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { if (playing.is_valid()) { return playing->mix(p_buffer, p_rate_scale * pitch_scale, p_frames); diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index bf200e7ecf..7c4577977d 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -40,6 +40,8 @@ #include "core/object/script_language.h" #include "core/variant/native_ptr.h" +class AudioStream; + class AudioStreamPlayback : public RefCounted { GDCLASS(AudioStreamPlayback, RefCounted); @@ -52,6 +54,7 @@ protected: GDVIRTUAL0RC(float, _get_playback_position) GDVIRTUAL1(_seek, float) GDVIRTUAL3R(int, _mix, GDNativePtr<AudioFrame>, float, int) + GDVIRTUAL0(_tag_used_streams) public: virtual void start(float p_from_pos = 0.0); virtual void stop(); @@ -62,6 +65,8 @@ public: virtual float get_playback_position() const; virtual void seek(float p_time); + virtual void tag_used_streams(); + virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames); }; @@ -72,7 +77,7 @@ class AudioStreamPlaybackResampled : public AudioStreamPlayback { FP_BITS = 16, //fixed point used for resampling FP_LEN = (1 << FP_BITS), FP_MASK = FP_LEN - 1, - INTERNAL_BUFFER_LEN = 256, + INTERNAL_BUFFER_LEN = 128, // 128 warrants 3ms positional jitter at much at 44100hz CUBIC_INTERP_HISTORY = 4 }; @@ -101,20 +106,42 @@ class AudioStream : public Resource { GDCLASS(AudioStream, Resource); OBJ_SAVE_TYPE(AudioStream); // Saves derived classes with common type so they can be interchanged. + enum { + MAX_TAGGED_OFFSETS = 8 + }; + + uint64_t tagged_frame = 0; + uint64_t offset_count = 0; + float tagged_offsets[MAX_TAGGED_OFFSETS]; + protected: static void _bind_methods(); - GDVIRTUAL0RC(Ref<AudioStreamPlayback>, _instance_playback) + GDVIRTUAL0RC(Ref<AudioStreamPlayback>, _instantiate_playback) GDVIRTUAL0RC(String, _get_stream_name) GDVIRTUAL0RC(float, _get_length) GDVIRTUAL0RC(bool, _is_monophonic) + GDVIRTUAL0RC(double, _get_bpm) + GDVIRTUAL0RC(bool, _has_loop) + GDVIRTUAL0RC(int, _get_bar_beats) + GDVIRTUAL0RC(int, _get_beat_count) public: - virtual Ref<AudioStreamPlayback> instance_playback(); + virtual Ref<AudioStreamPlayback> instantiate_playback(); virtual String get_stream_name() const; + virtual double get_bpm() const; + virtual bool has_loop() const; + virtual int get_bar_beats() const; + virtual int get_beat_count() const; + virtual float get_length() const; virtual bool is_monophonic() const; + + void tag_used(float p_offset); + uint64_t get_tagged_frame() const; + uint32_t get_tagged_frame_count() const; + float get_tagged_frame_offset(int p_index) const; }; // Microphone @@ -131,7 +158,7 @@ protected: static void _bind_methods(); public: - virtual Ref<AudioStreamPlayback> instance_playback() override; + virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; virtual float get_length() const override; //if supported, otherwise return 0 @@ -153,6 +180,7 @@ class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled { protected: virtual int _mix_internal(AudioFrame *p_buffer, int p_frames) override; virtual float get_stream_sampling_rate() override; + virtual float get_playback_position() const override; public: virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override; @@ -163,9 +191,10 @@ public: virtual int get_loop_count() const override; //times it looped - virtual float get_playback_position() const override; virtual void seek(float p_time) override; + virtual void tag_used_streams() override; + ~AudioStreamPlaybackMicrophone(); AudioStreamPlaybackMicrophone(); }; @@ -233,7 +262,7 @@ public: void set_playback_mode(PlaybackMode p_playback_mode); PlaybackMode get_playback_mode() const; - virtual Ref<AudioStreamPlayback> instance_playback() override; + virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; virtual float get_length() const override; //if supported, otherwise return 0 @@ -265,6 +294,8 @@ public: virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override; + virtual void tag_used_streams() override; + ~AudioStreamPlaybackRandomizer(); }; diff --git a/servers/audio/effects/audio_effect_amplify.h b/servers/audio/effects/audio_effect_amplify.h index bd0fcaa94d..fd424cbe9a 100644 --- a/servers/audio/effects/audio_effect_amplify.h +++ b/servers/audio/effects/audio_effect_amplify.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTAMPLIFY_H -#define AUDIOEFFECTAMPLIFY_H +#ifndef AUDIO_EFFECT_AMPLIFY_H +#define AUDIO_EFFECT_AMPLIFY_H #include "servers/audio/audio_effect.h" @@ -63,4 +63,4 @@ public: AudioEffectAmplify(); }; -#endif // AUDIOEFFECTAMPLIFY_H +#endif // AUDIO_EFFECT_AMPLIFY_H diff --git a/servers/audio/effects/audio_effect_chorus.h b/servers/audio/effects/audio_effect_chorus.h index 19035222c5..72b495f7f9 100644 --- a/servers/audio/effects/audio_effect_chorus.h +++ b/servers/audio/effects/audio_effect_chorus.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTCHORUS_H -#define AUDIOEFFECTCHORUS_H +#ifndef AUDIO_EFFECT_CHORUS_H +#define AUDIO_EFFECT_CHORUS_H #include "servers/audio/audio_effect.h" @@ -133,4 +133,4 @@ public: AudioEffectChorus(); }; -#endif // AUDIOEFFECTCHORUS_H +#endif // AUDIO_EFFECT_CHORUS_H diff --git a/servers/audio/effects/audio_effect_compressor.h b/servers/audio/effects/audio_effect_compressor.h index 53c448e5db..998bd3c978 100644 --- a/servers/audio/effects/audio_effect_compressor.h +++ b/servers/audio/effects/audio_effect_compressor.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTCOMPRESSOR_H -#define AUDIOEFFECTCOMPRESSOR_H +#ifndef AUDIO_EFFECT_COMPRESSOR_H +#define AUDIO_EFFECT_COMPRESSOR_H #include "servers/audio/audio_effect.h" @@ -91,4 +91,4 @@ public: AudioEffectCompressor(); }; -#endif // AUDIOEFFECTCOMPRESSOR_H +#endif // AUDIO_EFFECT_COMPRESSOR_H diff --git a/servers/audio/effects/audio_effect_delay.h b/servers/audio/effects/audio_effect_delay.h index 5cc6d72c99..137a4e7dbe 100644 --- a/servers/audio/effects/audio_effect_delay.h +++ b/servers/audio/effects/audio_effect_delay.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTDELAY_H -#define AUDIOEFFECTDELAY_H +#ifndef AUDIO_EFFECT_DELAY_H +#define AUDIO_EFFECT_DELAY_H #include "servers/audio/audio_effect.h" @@ -131,4 +131,4 @@ public: AudioEffectDelay(); }; -#endif // AUDIOEFFECTDELAY_H +#endif // AUDIO_EFFECT_DELAY_H diff --git a/servers/audio/effects/audio_effect_distortion.h b/servers/audio/effects/audio_effect_distortion.h index 487babbdda..c845a0e53c 100644 --- a/servers/audio/effects/audio_effect_distortion.h +++ b/servers/audio/effects/audio_effect_distortion.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTDISTORTION_H -#define AUDIOEFFECTDISTORTION_H +#ifndef AUDIO_EFFECT_DISTORTION_H +#define AUDIO_EFFECT_DISTORTION_H #include "servers/audio/audio_effect.h" @@ -90,4 +90,4 @@ public: VARIANT_ENUM_CAST(AudioEffectDistortion::Mode) -#endif // AUDIOEFFECTDISTORTION_H +#endif // AUDIO_EFFECT_DISTORTION_H diff --git a/servers/audio/effects/audio_effect_eq.cpp b/servers/audio/effects/audio_effect_eq.cpp index b7c373479a..500abd3a6f 100644 --- a/servers/audio/effects/audio_effect_eq.cpp +++ b/servers/audio/effects/audio_effect_eq.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "audio_effect_eq.h" + #include "servers/audio_server.h" void AudioEffectEQInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { diff --git a/servers/audio/effects/audio_effect_eq.h b/servers/audio/effects/audio_effect_eq.h index 9b0560223f..b80fb7c73c 100644 --- a/servers/audio/effects/audio_effect_eq.h +++ b/servers/audio/effects/audio_effect_eq.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTEQ_H -#define AUDIOEFFECTEQ_H +#ifndef AUDIO_EFFECT_EQ_H +#define AUDIO_EFFECT_EQ_H #include "servers/audio/audio_effect.h" -#include "servers/audio/effects/eq.h" +#include "servers/audio/effects/eq_filter.h" class AudioEffectEQ; @@ -98,4 +98,4 @@ public: AudioEffectEQ(EQ::PRESET_21_BANDS) {} }; -#endif // AUDIOEFFECTEQ_H +#endif // AUDIO_EFFECT_EQ_H diff --git a/servers/audio/effects/audio_effect_filter.h b/servers/audio/effects/audio_effect_filter.h index d5d58ddaa3..a40af2f13c 100644 --- a/servers/audio/effects/audio_effect_filter.h +++ b/servers/audio/effects/audio_effect_filter.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTFILTER_H -#define AUDIOEFFECTFILTER_H +#ifndef AUDIO_EFFECT_FILTER_H +#define AUDIO_EFFECT_FILTER_H #include "servers/audio/audio_effect.h" #include "servers/audio/audio_filter_sw.h" @@ -167,4 +167,4 @@ public: AudioEffectFilter(AudioFilterSW::HIGHSHELF) {} }; -#endif // AUDIOEFFECTFILTER_H +#endif // AUDIO_EFFECT_FILTER_H diff --git a/servers/audio/effects/audio_effect_panner.h b/servers/audio/effects/audio_effect_panner.h index d05c9902af..3eca71a926 100644 --- a/servers/audio/effects/audio_effect_panner.h +++ b/servers/audio/effects/audio_effect_panner.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTPANNER_H -#define AUDIOEFFECTPANNER_H +#ifndef AUDIO_EFFECT_PANNER_H +#define AUDIO_EFFECT_PANNER_H #include "servers/audio/audio_effect.h" @@ -61,4 +61,4 @@ public: AudioEffectPanner(); }; -#endif // AUDIOEFFECTPANNER_H +#endif // AUDIO_EFFECT_PANNER_H diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp index a6553e1431..fff6dbc32a 100644 --- a/servers/audio/effects/audio_effect_record.cpp +++ b/servers/audio/effects/audio_effect_record.cpp @@ -199,16 +199,16 @@ bool AudioEffectRecord::is_recording_active() const { return recording_active; } -void AudioEffectRecord::set_format(AudioStreamSample::Format p_format) { +void AudioEffectRecord::set_format(AudioStreamWAV::Format p_format) { format = p_format; } -AudioStreamSample::Format AudioEffectRecord::get_format() const { +AudioStreamWAV::Format AudioEffectRecord::get_format() const { return format; } -Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { - AudioStreamSample::Format dst_format = format; +Ref<AudioStreamWAV> AudioEffectRecord::get_recording() const { + AudioStreamWAV::Format dst_format = format; bool stereo = true; //forcing mono is not implemented Vector<uint8_t> dst_data; @@ -216,7 +216,7 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { ERR_FAIL_COND_V(current_instance.is_null(), nullptr); ERR_FAIL_COND_V(current_instance->recording_data.size() == 0, nullptr); - if (dst_format == AudioStreamSample::FORMAT_8_BITS) { + if (dst_format == AudioStreamWAV::FORMAT_8_BITS) { int data_size = current_instance->recording_data.size(); dst_data.resize(data_size); uint8_t *w = dst_data.ptrw(); @@ -225,7 +225,7 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { int8_t v = CLAMP(current_instance->recording_data[i] * 128, -128, 127); w[i] = v; } - } else if (dst_format == AudioStreamSample::FORMAT_16_BITS) { + } else if (dst_format == AudioStreamWAV::FORMAT_16_BITS) { int data_size = current_instance->recording_data.size(); dst_data.resize(data_size * 2); uint8_t *w = dst_data.ptrw(); @@ -234,7 +234,7 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { int16_t v = CLAMP(current_instance->recording_data[i] * 32768, -32768, 32767); encode_uint16(v, &w[i * 2]); } - } else if (dst_format == AudioStreamSample::FORMAT_IMA_ADPCM) { + } else if (dst_format == AudioStreamWAV::FORMAT_IMA_ADPCM) { //byte interleave Vector<float> left; Vector<float> right; @@ -273,12 +273,12 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const { ERR_PRINT("Format not implemented."); } - Ref<AudioStreamSample> sample; + Ref<AudioStreamWAV> sample; sample.instantiate(); sample->set_data(dst_data); sample->set_format(dst_format); sample->set_mix_rate(AudioServer::get_singleton()->get_mix_rate()); - sample->set_loop_mode(AudioStreamSample::LOOP_DISABLED); + sample->set_loop_mode(AudioStreamWAV::LOOP_DISABLED); sample->set_loop_begin(0); sample->set_loop_end(0); sample->set_stereo(stereo); @@ -297,6 +297,6 @@ void AudioEffectRecord::_bind_methods() { } AudioEffectRecord::AudioEffectRecord() { - format = AudioStreamSample::FORMAT_16_BITS; + format = AudioStreamWAV::FORMAT_16_BITS; recording_active = false; } diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h index 8a6247e27a..e89d8adbde 100644 --- a/servers/audio/effects/audio_effect_record.h +++ b/servers/audio/effects/audio_effect_record.h @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTRECORD_H -#define AUDIOEFFECTRECORD_H +#ifndef AUDIO_EFFECT_RECORD_H +#define AUDIO_EFFECT_RECORD_H #include "core/io/file_access.h" #include "core/io/marshalls.h" #include "core/os/os.h" #include "core/os/thread.h" -#include "scene/resources/audio_stream_sample.h" +#include "scene/resources/audio_stream_wav.h" #include "servers/audio/audio_effect.h" #include "servers/audio_server.h" @@ -85,7 +85,7 @@ class AudioEffectRecord : public AudioEffect { bool recording_active; Ref<AudioEffectRecordInstance> current_instance; - AudioStreamSample::Format format; + AudioStreamWAV::Format format; void ensure_thread_stopped(); @@ -96,11 +96,11 @@ public: Ref<AudioEffectInstance> instantiate() override; void set_recording_active(bool p_record); bool is_recording_active() const; - void set_format(AudioStreamSample::Format p_format); - AudioStreamSample::Format get_format() const; - Ref<AudioStreamSample> get_recording() const; + void set_format(AudioStreamWAV::Format p_format); + AudioStreamWAV::Format get_format() const; + Ref<AudioStreamWAV> get_recording() const; AudioEffectRecord(); }; -#endif // AUDIOEFFECTRECORD_H +#endif // AUDIO_EFFECT_RECORD_H diff --git a/servers/audio/effects/audio_effect_reverb.h b/servers/audio/effects/audio_effect_reverb.h index 90694c5492..a2c1fc5ea5 100644 --- a/servers/audio/effects/audio_effect_reverb.h +++ b/servers/audio/effects/audio_effect_reverb.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef AUDIOEFFECTREVERB_H -#define AUDIOEFFECTREVERB_H +#ifndef AUDIO_EFFECT_REVERB_H +#define AUDIO_EFFECT_REVERB_H #include "servers/audio/audio_effect.h" -#include "servers/audio/effects/reverb.h" +#include "servers/audio/effects/reverb_filter.h" class AudioEffectReverb; @@ -94,4 +94,4 @@ public: AudioEffectReverb(); }; -#endif // AUDIOEFFECTREVERB_H +#endif // AUDIO_EFFECT_REVERB_H diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp index 46de1692e4..6365dacc80 100644 --- a/servers/audio/effects/audio_stream_generator.cpp +++ b/servers/audio/effects/audio_stream_generator.cpp @@ -46,7 +46,7 @@ float AudioStreamGenerator::get_buffer_length() const { return buffer_len; } -Ref<AudioStreamPlayback> AudioStreamGenerator::instance_playback() { +Ref<AudioStreamPlayback> AudioStreamGenerator::instantiate_playback() { Ref<AudioStreamGeneratorPlayback> playback; playback.instantiate(); playback->generator = this; @@ -196,6 +196,10 @@ void AudioStreamGeneratorPlayback::seek(float p_time) { //no seek possible } +void AudioStreamGeneratorPlayback::tag_used_streams() { + generator->tag_used(0); +} + void AudioStreamGeneratorPlayback::_bind_methods() { ClassDB::bind_method(D_METHOD("push_frame", "frame"), &AudioStreamGeneratorPlayback::push_frame); ClassDB::bind_method(D_METHOD("can_push_buffer", "amount"), &AudioStreamGeneratorPlayback::can_push_buffer); diff --git a/servers/audio/effects/audio_stream_generator.h b/servers/audio/effects/audio_stream_generator.h index 2ce4b95fcf..a0bed0fda5 100644 --- a/servers/audio/effects/audio_stream_generator.h +++ b/servers/audio/effects/audio_stream_generator.h @@ -50,7 +50,7 @@ public: void set_buffer_length(float p_seconds); float get_buffer_length() const; - virtual Ref<AudioStreamPlayback> instance_playback() override; + virtual Ref<AudioStreamPlayback> instantiate_playback() override; virtual String get_stream_name() const override; virtual float get_length() const override; @@ -89,8 +89,11 @@ public: int get_frames_available() const; int get_skips() const; + virtual void tag_used_streams() override; + void clear_buffer(); AudioStreamGeneratorPlayback(); }; + #endif // AUDIO_STREAM_GENERATOR_H diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq_filter.cpp index 2123284b3b..6807e81cc4 100644 --- a/servers/audio/effects/eq.cpp +++ b/servers/audio/effects/eq_filter.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* eq.cpp */ +/* eq_filter.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Author: reduzio@gmail.com (C) 2006 +#include "eq_filter.h" -#include "eq.h" #include "core/error/error_macros.h" #include "core/math/math_funcs.h" + #include <math.h> #define POW2(v) ((v) * (v)) diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq_filter.h index d6293bf875..9dcad4dcea 100644 --- a/servers/audio/effects/eq.h +++ b/servers/audio/effects/eq_filter.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* eq.h */ +/* eq_filter.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb_filter.cpp index adfd648514..0363706714 100644 --- a/servers/audio/effects/reverb.cpp +++ b/servers/audio/effects/reverb_filter.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* reverb.cpp */ +/* reverb_filter.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "reverb.h" +#include "reverb_filter.h" #include "core/math/math_funcs.h" diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb_filter.h index c9602c5b5a..fe846fe2e7 100644 --- a/servers/audio/effects/reverb.h +++ b/servers/audio/effects/reverb_filter.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* reverb.h */ +/* reverb_filter.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef REVERB_H -#define REVERB_H +#ifndef REVERB_FILTER_H +#define REVERB_FILTER_H #include "core/math/audio_frame.h" #include "core/os/memory.h" @@ -119,4 +119,4 @@ public: ~Reverb(); }; -#endif // REVERB_H +#endif // REVERB_FILTER_H diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 8ec3e469d3..9052f8e05e 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -39,7 +39,7 @@ #include "core/os/os.h" #include "core/string/string_name.h" #include "core/templates/pair.h" -#include "scene/resources/audio_stream_sample.h" +#include "scene/resources/audio_stream_wav.h" #include "servers/audio/audio_driver_dummy.h" #include "servers/audio/effects/audio_effect_compressor.h" @@ -350,6 +350,10 @@ void AudioServer::_mix_step() { // Mix the audio stream unsigned int mixed_frames = playback->stream_playback->mix(&buf[LOOKAHEAD_BUFFER_SIZE], playback->pitch_scale.get(), buffer_size); + if (tag_used_audio_streams && playback->stream_playback->is_playing()) { + playback->stream_playback->tag_used_streams(); + } + if (mixed_frames != buffer_size) { // We know we have at least the size of our lookahead buffer for fade-out purposes. @@ -1312,6 +1316,10 @@ uint64_t AudioServer::get_mix_count() const { return mix_count; } +uint64_t AudioServer::get_mixed_frames() const { + return mix_frames; +} + void AudioServer::notify_listener_changed() { for (CallbackItem *ci : listener_changed_callback_list) { ci->callback(ci->userdata); @@ -1653,6 +1661,10 @@ void AudioServer::capture_set_device(const String &p_name) { AudioDriver::get_singleton()->capture_set_device(p_name); } +void AudioServer::set_enable_tagging_used_audio_streams(bool p_enable) { + tag_used_audio_streams = p_enable; +} + void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count); ClassDB::bind_method(D_METHOD("get_bus_count"), &AudioServer::get_bus_count); @@ -1719,6 +1731,8 @@ void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout"), &AudioServer::set_bus_layout); ClassDB::bind_method(D_METHOD("generate_bus_layout"), &AudioServer::generate_bus_layout); + ClassDB::bind_method(D_METHOD("set_enable_tagging_used_audio_streams", "enable"), &AudioServer::set_enable_tagging_used_audio_streams); + ADD_PROPERTY(PropertyInfo(Variant::INT, "bus_count"), "set_bus_count", "get_bus_count"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "device"), "set_device", "get_device"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "capture_device"), "capture_set_device", "capture_get_device"); diff --git a/servers/audio_server.h b/servers/audio_server.h index 18e173ff0b..5613267909 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -43,7 +43,7 @@ class AudioDriverDummy; class AudioStream; -class AudioStreamSample; +class AudioStreamWAV; class AudioStreamPlayback; class AudioDriver { @@ -187,6 +187,8 @@ private: float playback_speed_scale = 1.0f; + bool tag_used_audio_streams = false; + struct Bus { StringName name; bool solo = false; @@ -380,6 +382,7 @@ public: bool is_playback_paused(Ref<AudioStreamPlayback> p_playback); uint64_t get_mix_count() const; + uint64_t get_mixed_frames() const; void notify_listener_changed(); @@ -424,6 +427,8 @@ public: String capture_get_device(); void capture_set_device(const String &p_name); + void set_enable_tagging_used_audio_streams(bool p_enable); + AudioServer(); virtual ~AudioServer(); }; diff --git a/servers/debugger/servers_debugger.h b/servers/debugger/servers_debugger.h index f949c436e7..be0e64fbc0 100644 --- a/servers/debugger/servers_debugger.h +++ b/servers/debugger/servers_debugger.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SERVER_DEBUGGER_H -#define SERVER_DEBUGGER_H +#ifndef SERVERS_DEBUGGER_H +#define SERVERS_DEBUGGER_H #include "core/debugger/debugger_marshalls.h" diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h index 663af1ae6c..c4b4a00eaf 100644 --- a/servers/extensions/physics_server_3d_extension.h +++ b/servers/extensions/physics_server_3d_extension.h @@ -545,4 +545,4 @@ public: ~PhysicsServer3DExtension(); }; -#endif // PHYSICSSERVER3DEXTENSION_H +#endif // PHYSICS_SERVER_3D_EXTENSION_H diff --git a/servers/movie_writer/movie_writer.cpp b/servers/movie_writer/movie_writer.cpp index 9f96b8cfda..40b2b2539e 100644 --- a/servers/movie_writer/movie_writer.cpp +++ b/servers/movie_writer/movie_writer.cpp @@ -30,6 +30,9 @@ #include "movie_writer.h" #include "core/config/project_settings.h" +#include "core/io/dir_access.h" +#include "core/os/time.h" +#include "servers/display_server.h" MovieWriter *MovieWriter::writers[MovieWriter::MAX_WRITERS]; uint32_t MovieWriter::writer_count = 0; @@ -101,6 +104,7 @@ void MovieWriter::get_supported_extensions(List<String> *r_extensions) const { } void MovieWriter::begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) { + project_name = GLOBAL_GET("application/config/name"); mix_rate = get_audio_mix_rate(); AudioDriverDummy::get_dummy_singleton()->set_mix_rate(mix_rate); AudioDriverDummy::get_dummy_singleton()->set_speaker_mode(AudioDriver::SpeakerMode(get_audio_speaker_mode())); @@ -162,10 +166,47 @@ void MovieWriter::set_extensions_hint() { } void MovieWriter::add_frame(const Ref<Image> &p_image) { + const int movie_time_seconds = Engine::get_singleton()->get_frames_drawn() / fps; + const String movie_time = vformat("%s:%s:%s", + String::num(movie_time_seconds / 3600).pad_zeros(2), + String::num((movie_time_seconds % 3600) / 60).pad_zeros(2), + String::num(movie_time_seconds % 60).pad_zeros(2)); + +#ifdef DEBUG_ENABLED + DisplayServer::get_singleton()->window_set_title(vformat("MovieWriter: Frame %d (time: %s) - %s (DEBUG)", Engine::get_singleton()->get_frames_drawn(), movie_time, project_name)); +#else + DisplayServer::get_singleton()->window_set_title(vformat("MovieWriter: Frame %d (time: %s) - %s", Engine::get_singleton()->get_frames_drawn(), movie_time, project_name)); +#endif + AudioDriverDummy::get_dummy_singleton()->mix_audio(mix_rate / fps, audio_mix_buffer.ptr()); write_frame(p_image, audio_mix_buffer.ptr()); } void MovieWriter::end() { write_end(); + + // Print a report with various statistics. + print_line("----------------"); + String movie_path = Engine::get_singleton()->get_write_movie_path(); + if (movie_path.is_relative_path()) { + // Print absolute path to make finding the file easier, + // and to make it clickable in terminal emulators that support this. + movie_path = ProjectSettings::get_singleton()->globalize_path("res://").plus_file(movie_path); + } + print_line(vformat("Done recording movie at path: %s", movie_path)); + + const int movie_time_seconds = Engine::get_singleton()->get_frames_drawn() / fps; + const String movie_time = vformat("%s:%s:%s", + String::num(movie_time_seconds / 3600).pad_zeros(2), + String::num((movie_time_seconds % 3600) / 60).pad_zeros(2), + String::num(movie_time_seconds % 60).pad_zeros(2)); + + const int real_time_seconds = Time::get_singleton()->get_ticks_msec() / 1000; + const String real_time = vformat("%s:%s:%s", + String::num(real_time_seconds / 3600).pad_zeros(2), + String::num((real_time_seconds % 3600) / 60).pad_zeros(2), + String::num(real_time_seconds % 60).pad_zeros(2)); + + print_line(vformat("%d frames at %d FPS (movie length: %s), recorded in %s (%d%% of real-time speed).", Engine::get_singleton()->get_frames_drawn(), fps, movie_time, real_time, (float(movie_time_seconds) / real_time_seconds) * 100)); + print_line("----------------"); } diff --git a/servers/movie_writer/movie_writer.h b/servers/movie_writer/movie_writer.h index 1ec6e93052..7877a60715 100644 --- a/servers/movie_writer/movie_writer.h +++ b/servers/movie_writer/movie_writer.h @@ -42,6 +42,8 @@ class MovieWriter : public Object { uint64_t mix_rate = 0; uint32_t audio_channels = 0; + String project_name; + LocalVector<int32_t> audio_mix_buffer; enum { diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp index 551fd9329f..0603458acd 100644 --- a/servers/physics_2d/godot_step_2d.cpp +++ b/servers/physics_2d/godot_step_2d.cpp @@ -239,7 +239,8 @@ void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta) { /* SETUP CONSTRAINTS / PROCESS COLLISIONS */ uint32_t total_contraint_count = all_constraints.size(); - work_pool.do_work(total_contraint_count, this, &GodotStep2D::_setup_contraint, nullptr); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GodotStep2D::_setup_contraint, nullptr, total_contraint_count, -1, true, SNAME("Physics2DConstraintSetup")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); @@ -258,7 +259,8 @@ void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta) { // Warning: _solve_island modifies the constraint islands for optimization purpose, // their content is not reliable after these calls and shouldn't be used anymore. - work_pool.do_work(island_count, this, &GodotStep2D::_solve_island, nullptr); + group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GodotStep2D::_solve_island, nullptr, island_count, -1, true, SNAME("Physics2DConstraintSolveIslands")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); @@ -297,10 +299,7 @@ GodotStep2D::GodotStep2D() { body_islands.reserve(BODY_ISLAND_COUNT_RESERVE); constraint_islands.reserve(ISLAND_COUNT_RESERVE); all_constraints.reserve(CONSTRAINT_COUNT_RESERVE); - - work_pool.init(); } GodotStep2D::~GodotStep2D() { - work_pool.finish(); } diff --git a/servers/physics_2d/godot_step_2d.h b/servers/physics_2d/godot_step_2d.h index 9a6d8caf9b..9f8fdd6ce3 100644 --- a/servers/physics_2d/godot_step_2d.h +++ b/servers/physics_2d/godot_step_2d.h @@ -33,8 +33,8 @@ #include "godot_space_2d.h" +#include "core/object/worker_thread_pool.h" #include "core/templates/local_vector.h" -#include "core/templates/thread_work_pool.h" class GodotStep2D { uint64_t _step = 1; @@ -42,8 +42,6 @@ class GodotStep2D { int iterations = 0; real_t delta = 0.0; - ThreadWorkPool work_pool; - LocalVector<LocalVector<GodotBody2D *>> body_islands; LocalVector<LocalVector<GodotConstraint2D *>> constraint_islands; LocalVector<GodotConstraint2D *> all_constraints; diff --git a/servers/physics_3d/gjk_epa.h b/servers/physics_3d/gjk_epa.h index 01a47f222e..309af76561 100644 --- a/servers/physics_3d/gjk_epa.h +++ b/servers/physics_3d/gjk_epa.h @@ -37,4 +37,4 @@ bool gjk_epa_calculate_penetration(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, GodotCollisionSolver3D::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, real_t p_margin_A = 0.0, real_t p_margin_B = 0.0); bool gjk_epa_calculate_distance(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B); -#endif +#endif // GJK_EPA_H diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.h b/servers/physics_3d/godot_collision_solver_3d_sat.h index 3eb7aa4c9e..46c5ec3254 100644 --- a/servers/physics_3d/godot_collision_solver_3d_sat.h +++ b/servers/physics_3d/godot_collision_solver_3d_sat.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GODOT_COLLISION_SOLVER_SAT_H -#define GODOT_COLLISION_SOLVER_SAT_H +#ifndef GODOT_COLLISION_SOLVER_3D_SAT_H +#define GODOT_COLLISION_SOLVER_3D_SAT_H #include "godot_collision_solver_3d.h" bool sat_calculate_penetration(const GodotShape3D *p_shape_A, const Transform3D &p_transform_A, const GodotShape3D *p_shape_B, const Transform3D &p_transform_B, GodotCollisionSolver3D::CallbackResult p_result_callback, void *p_userdata, bool p_swap = false, Vector3 *r_prev_axis = nullptr, real_t p_margin_a = 0, real_t p_margin_b = 0); -#endif // GODOT_COLLISION_SOLVER_SAT_H +#endif // GODOT_COLLISION_SOLVER_3D_SAT_H diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp index 99656d01a0..f384c829a4 100644 --- a/servers/physics_3d/godot_step_3d.cpp +++ b/servers/physics_3d/godot_step_3d.cpp @@ -343,7 +343,8 @@ void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta) { /* SETUP CONSTRAINTS / PROCESS COLLISIONS */ uint32_t total_contraint_count = all_constraints.size(); - work_pool.do_work(total_contraint_count, this, &GodotStep3D::_setup_contraint, nullptr); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GodotStep3D::_setup_contraint, nullptr, total_contraint_count, -1, true, SNAME("Physics3DConstraintSetup")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); @@ -362,7 +363,8 @@ void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta) { // Warning: _solve_island modifies the constraint islands for optimization purpose, // their content is not reliable after these calls and shouldn't be used anymore. - work_pool.do_work(island_count, this, &GodotStep3D::_solve_island, nullptr); + group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &GodotStep3D::_solve_island, nullptr, island_count, -1, true, SNAME("Physics3DConstraintSolveIslands")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); { //profile profile_endtime = OS::get_singleton()->get_ticks_usec(); @@ -409,10 +411,7 @@ GodotStep3D::GodotStep3D() { body_islands.reserve(BODY_ISLAND_COUNT_RESERVE); constraint_islands.reserve(ISLAND_COUNT_RESERVE); all_constraints.reserve(CONSTRAINT_COUNT_RESERVE); - - work_pool.init(); } GodotStep3D::~GodotStep3D() { - work_pool.finish(); } diff --git a/servers/physics_3d/godot_step_3d.h b/servers/physics_3d/godot_step_3d.h index 6d975b0dd3..189487757f 100644 --- a/servers/physics_3d/godot_step_3d.h +++ b/servers/physics_3d/godot_step_3d.h @@ -33,8 +33,8 @@ #include "godot_space_3d.h" +#include "core/object/worker_thread_pool.h" #include "core/templates/local_vector.h" -#include "core/templates/thread_work_pool.h" class GodotStep3D { uint64_t _step = 1; @@ -42,8 +42,6 @@ class GodotStep3D { int iterations = 0; real_t delta = 0.0; - ThreadWorkPool work_pool; - LocalVector<LocalVector<GodotBody3D *>> body_islands; LocalVector<LocalVector<GodotConstraint3D *>> constraint_islands; LocalVector<GodotConstraint3D *> all_constraints; diff --git a/servers/rendering/dummy/environment/fog.h b/servers/rendering/dummy/environment/fog.h index 8a2be90507..623f94b95f 100644 --- a/servers/rendering/dummy/environment/fog.h +++ b/servers/rendering/dummy/environment/fog.h @@ -52,4 +52,4 @@ public: } // namespace RendererDummy -#endif // !FOG_DUMMY_H +#endif // FOG_DUMMY_H diff --git a/servers/rendering/dummy/environment/gi.h b/servers/rendering/dummy/environment/gi.h index 9c7647c2de..76d34cd14e 100644 --- a/servers/rendering/dummy/environment/gi.h +++ b/servers/rendering/dummy/environment/gi.h @@ -79,4 +79,4 @@ public: } // namespace RendererDummy -#endif // !GI_DUMMY_H +#endif // GI_DUMMY_H diff --git a/servers/rendering/dummy/rasterizer_canvas_dummy.h b/servers/rendering/dummy/rasterizer_canvas_dummy.h index 194b5b5cfe..64c4cf5024 100644 --- a/servers/rendering/dummy/rasterizer_canvas_dummy.h +++ b/servers/rendering/dummy/rasterizer_canvas_dummy.h @@ -60,4 +60,4 @@ public: ~RasterizerCanvasDummy() {} }; -#endif // !RASTERIZER_CANVAS_DUMMY_H +#endif // RASTERIZER_CANVAS_DUMMY_H diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h index b49d6cff69..be98770b90 100644 --- a/servers/rendering/dummy/rasterizer_scene_dummy.h +++ b/servers/rendering/dummy/rasterizer_scene_dummy.h @@ -35,33 +35,10 @@ class RasterizerSceneDummy : public RendererSceneRender { public: - GeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; } - void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override {} - void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override {} - void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override {} - void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) override {} - void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override {} - void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override {} - void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override {} - void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override {} - void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {} - void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override {} - void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override {} - void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override {} - void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {} - void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override {} - void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override {} + RenderGeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; } + void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override {} uint32_t geometry_instance_get_pair_mask() override { return 0; } - void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override {} - void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} - void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} - void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} - void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override {} - - void geometry_instance_free(GeometryInstance *p_geometry_instance) override {} /* SHADOW ATLAS API */ @@ -92,49 +69,24 @@ public: /* ENVIRONMENT API */ - 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 {} - void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override {} - void environment_set_bg_color(RID p_env, const Color &p_color) override {} - void environment_set_bg_energy(RID p_env, float p_energy) override {} - void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override {} - void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override {} - - void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override {} void environment_glow_set_use_bicubic_upscale(bool p_enable) override {} void environment_glow_set_use_high_quality(bool p_enable) override {} - 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) override {} void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {} - 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_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override {} - void environment_set_ssil_quality(RS::EnvironmentSSILQuality 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, int 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_ssil_quality(RS::EnvironmentSSILQuality 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_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override {} void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override {} void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override {} - void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override {} - - 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_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) 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 {} Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); } - bool is_environment(RID p_env) const override { return false; } - 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_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 {} @@ -149,7 +101,7 @@ public: RID light_instance_create(RID p_light) override { return RID(); } void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override {} void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override {} - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {} + void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {} void light_instance_mark_visible(RID p_light_instance) override {} RID fog_volume_instance_create(RID p_fog_volume) override { return RID(); } @@ -179,20 +131,20 @@ public: RID voxel_gi_instance_create(RID p_voxel_gi) override { return RID(); } void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override {} bool voxel_gi_needs_update(RID p_probe) const override { return false; } - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override {} + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) override {} void voxel_gi_set_quality(RS::VoxelGIQuality) override {} - void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_info = nullptr) override {} - void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} - void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {} + void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_info = nullptr) override {} + void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} + void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override {} void set_scene_pass(uint64_t p_pass) override {} void set_time(double p_time, double p_step) override {} void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override {} RID render_buffers_create() override { return RID(); } - void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override {} + void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override {} void gi_set_use_half_resolution(bool p_enable) override {} void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {} @@ -203,7 +155,14 @@ public: TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override { return TypedArray<Image>(); } - bool free(RID p_rid) override { return false; } + bool free(RID p_rid) override { + if (is_environment(p_rid)) { + environment_free(p_rid); + return true; + } else { + return false; + } + } void update() override {} void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override {} @@ -214,4 +173,4 @@ public: ~RasterizerSceneDummy() {} }; -#endif // !RASTERIZER_SCENE_DUMMY_H +#endif // RASTERIZER_SCENE_DUMMY_H diff --git a/servers/rendering/dummy/storage/light_storage.h b/servers/rendering/dummy/storage/light_storage.h index b0100a5fe7..0c0ea61df5 100644 --- a/servers/rendering/dummy/storage/light_storage.h +++ b/servers/rendering/dummy/storage/light_storage.h @@ -132,4 +132,4 @@ public: } // namespace RendererDummy -#endif // !LIGHT_STORAGE_DUMMY_H +#endif // LIGHT_STORAGE_DUMMY_H diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h index d4809f81e3..55c42330cf 100644 --- a/servers/rendering/dummy/storage/material_storage.h +++ b/servers/rendering/dummy/storage/material_storage.h @@ -38,23 +38,23 @@ namespace RendererDummy { class MaterialStorage : public RendererMaterialStorage { public: - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override {} - virtual void global_variable_remove(const StringName &p_name) override {} - virtual Vector<StringName> global_variable_get_list() const override { return Vector<StringName>(); } + virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override {} + virtual void global_shader_uniform_remove(const StringName &p_name) override {} + virtual Vector<StringName> global_shader_uniform_get_list() const override { return Vector<StringName>(); } - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override {} - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override {} - virtual Variant global_variable_get(const StringName &p_name) const override { return Variant(); } - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; } + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override {} + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override {} + virtual Variant global_shader_uniform_get(const StringName &p_name) const override { return Variant(); } + virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override { return RS::GLOBAL_VAR_TYPE_MAX; } - virtual void global_variables_load_settings(bool p_load_textures = true) override {} - virtual void global_variables_clear() override {} + virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override {} + virtual void global_shader_uniforms_clear() override {} - virtual int32_t global_variables_instance_allocate(RID p_instance) override { return 0; } - virtual void global_variables_instance_free(RID p_instance) override {} - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override {} + virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override { return 0; } + virtual void global_shader_uniforms_instance_free(RID p_instance) override {} + virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override {} /* SHADER API */ @@ -63,6 +63,8 @@ public: virtual void shader_free(RID p_rid) override{}; virtual void shader_set_code(RID p_shader, const String &p_code) override {} + virtual void shader_set_path_hint(RID p_shader, const String &p_code) override {} + virtual String shader_get_code(RID p_shader) const override { return ""; } virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override {} @@ -93,4 +95,4 @@ public: } // namespace RendererDummy -#endif // !MATERIAL_STORAGE_DUMMY_H +#endif // MATERIAL_STORAGE_DUMMY_H diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index 78b19d721d..8dfcd978ac 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -131,4 +131,4 @@ public: } // namespace RendererDummy -#endif // !MESH_STORAGE_DUMMY_H +#endif // MESH_STORAGE_DUMMY_H diff --git a/servers/rendering/dummy/storage/particles_storage.h b/servers/rendering/dummy/storage/particles_storage.h index f614b41c4c..7cee55922d 100644 --- a/servers/rendering/dummy/storage/particles_storage.h +++ b/servers/rendering/dummy/storage/particles_storage.h @@ -123,4 +123,4 @@ public: } // namespace RendererDummy -#endif // !PARTICLES_STORAGE_DUMMY_H +#endif // PARTICLES_STORAGE_DUMMY_H diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h index 195d378a41..73b1284558 100644 --- a/servers/rendering/dummy/storage/texture_storage.h +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -176,4 +176,4 @@ public: } // namespace RendererDummy -#endif // !TEXTURE_STORAGE_DUMMY_H +#endif // TEXTURE_STORAGE_DUMMY_H diff --git a/servers/rendering/dummy/storage/utilities.h b/servers/rendering/dummy/storage/utilities.h index f090309e88..b94f678c75 100644 --- a/servers/rendering/dummy/storage/utilities.h +++ b/servers/rendering/dummy/storage/utilities.h @@ -95,4 +95,4 @@ public: } // namespace RendererDummy -#endif // !UTILITIES_DUMMY_H +#endif // UTILITIES_DUMMY_H diff --git a/servers/rendering/environment/renderer_fog.h b/servers/rendering/environment/renderer_fog.h index ac50da0fc0..c55021e1a1 100644 --- a/servers/rendering/environment/renderer_fog.h +++ b/servers/rendering/environment/renderer_fog.h @@ -50,4 +50,4 @@ public: virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const = 0; }; -#endif // !RENDERER_FOG_H +#endif // RENDERER_FOG_H diff --git a/servers/rendering/environment/renderer_gi.h b/servers/rendering/environment/renderer_gi.h index 4f93bb8675..70d2bb3a9c 100644 --- a/servers/rendering/environment/renderer_gi.h +++ b/servers/rendering/environment/renderer_gi.h @@ -78,4 +78,4 @@ public: virtual uint32_t voxel_gi_get_version(RID p_probe) const = 0; }; -#endif // !RENDERER_GI_H +#endif // RENDERER_GI_H diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index 48d0598c9f..e8c54310c9 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_CANVAS_CULL_H -#define RENDERING_SERVER_CANVAS_CULL_H +#ifndef RENDERER_CANVAS_CULL_H +#define RENDERER_CANVAS_CULL_H #include "core/templates/paged_allocator.h" #include "renderer_compositor.h" @@ -317,4 +317,4 @@ public: ~RendererCanvasCull(); }; -#endif // RENDERING_SERVER_CANVAS_CULL_H +#endif // RENDERER_CANVAS_CULL_H diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h index 52b2f82089..11a7d34291 100644 --- a/servers/rendering/renderer_canvas_render.h +++ b/servers/rendering/renderer_canvas_render.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERINGSERVERCANVASRENDER_H -#define RENDERINGSERVERCANVASRENDER_H +#ifndef RENDERER_CANVAS_RENDER_H +#define RENDERER_CANVAS_RENDER_H #include "servers/rendering_server.h" @@ -77,7 +77,7 @@ public: Rect2 rect_cache; Transform2D xform_cache; float radius_cache; //used for shadow far plane - //CameraMatrix shadow_matrix_cache; + //Projection shadow_matrix_cache; Transform2D light_shader_xform; //Vector2 light_shader_pos; @@ -520,4 +520,4 @@ public: virtual ~RendererCanvasRender() {} }; -#endif // RENDERINGSERVERCANVASRENDER_H +#endif // RENDERER_CANVAS_RENDER_H diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp index b331ec2c1d..80e71a0df3 100644 --- a/servers/rendering/renderer_compositor.cpp +++ b/servers/rendering/renderer_compositor.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "core/os/os.h" #include "core/string/print_string.h" +#include "servers/xr_server.h" RendererCompositor *(*RendererCompositor::_create_func)() = nullptr; bool RendererCompositor::low_end = false; @@ -46,7 +47,11 @@ bool RendererCompositor::is_xr_enabled() const { } RendererCompositor::RendererCompositor() { - xr_enabled = GLOBAL_GET("xr/shaders/enabled"); + if (XRServer::get_xr_mode() == XRServer::XRMODE_DEFAULT) { + xr_enabled = GLOBAL_GET("xr/shaders/enabled"); + } else { + xr_enabled = XRServer::get_xr_mode() == XRServer::XRMODE_ON; + } } RendererCanvasRender *RendererCanvasRender::singleton = nullptr; diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index a67eb25736..4cfded8460 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_COMPOSITOR_H -#define RENDERING_SERVER_COMPOSITOR_H +#ifndef RENDERER_COMPOSITOR_H +#define RENDERER_COMPOSITOR_H #include "servers/rendering/environment/renderer_fog.h" #include "servers/rendering/environment/renderer_gi.h" @@ -109,4 +109,4 @@ public: virtual ~RendererCompositor() {} }; -#endif // RASTERIZER_H +#endif // RENDERER_COMPOSITOR_H diff --git a/servers/rendering/renderer_geometry_instance.cpp b/servers/rendering/renderer_geometry_instance.cpp new file mode 100644 index 0000000000..3a9bab022c --- /dev/null +++ b/servers/rendering/renderer_geometry_instance.cpp @@ -0,0 +1,138 @@ +/*************************************************************************/ +/* renderer_geometry_instance.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "servers/rendering/renderer_geometry_instance.h" + +void RenderGeometryInstanceBase::set_skeleton(RID p_skeleton) { + data->skeleton = p_skeleton; + + _mark_dirty(); + data->dirty_dependencies = true; +} + +void RenderGeometryInstanceBase::set_material_override(RID p_override) { + data->material_override = p_override; + + _mark_dirty(); + data->dirty_dependencies = true; +} + +void RenderGeometryInstanceBase::set_material_overlay(RID p_overlay) { + data->material_overlay = p_overlay; + + _mark_dirty(); + data->dirty_dependencies = true; +} + +void RenderGeometryInstanceBase::set_surface_materials(const Vector<RID> &p_materials) { + data->surface_materials = p_materials; + + _mark_dirty(); + data->dirty_dependencies = true; +} + +void RenderGeometryInstanceBase::set_mesh_instance(RID p_mesh_instance) { + mesh_instance = p_mesh_instance; + + _mark_dirty(); +} + +void RenderGeometryInstanceBase::set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { + transform = p_transform; + mirror = p_transform.basis.determinant() < 0; + data->aabb = p_aabb; + transformed_aabb = p_transformed_aabb; + + Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); + // handle non uniform scale here + + float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); + float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); + non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; + + lod_model_scale = max_scale; +} + +void RenderGeometryInstanceBase::set_lod_bias(float p_lod_bias) { + lod_bias = p_lod_bias; +} + +void RenderGeometryInstanceBase::set_layer_mask(uint32_t p_layer_mask) { + layer_mask = p_layer_mask; +} + +void RenderGeometryInstanceBase::set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { + fade_near = p_enable_near; + fade_near_begin = p_near_begin; + fade_near_end = p_near_end; + fade_far = p_enable_far; + fade_far_begin = p_far_begin; + fade_far_end = p_far_end; +} + +void RenderGeometryInstanceBase::set_parent_fade_alpha(float p_alpha) { + parent_fade_alpha = p_alpha; +} + +void RenderGeometryInstanceBase::set_transparency(float p_transparency) { + force_alpha = CLAMP(1.0 - p_transparency, 0, 1); +} + +void RenderGeometryInstanceBase::set_use_baked_light(bool p_enable) { + data->use_baked_light = p_enable; + + _mark_dirty(); +} + +void RenderGeometryInstanceBase::set_use_dynamic_gi(bool p_enable) { + data->use_dynamic_gi = p_enable; + + _mark_dirty(); +} + +void RenderGeometryInstanceBase::set_instance_shader_parameters_offset(int32_t p_offset) { + shader_parameters_offset = p_offset; + + _mark_dirty(); +} + +void RenderGeometryInstanceBase::set_cast_double_sided_shadows(bool p_enable) { + data->cast_double_sided_shadows = p_enable; + + _mark_dirty(); +} + +Transform3D RenderGeometryInstanceBase::get_transform() { + return transform; +} + +AABB RenderGeometryInstanceBase::get_aabb() { + return data->aabb; +} diff --git a/servers/rendering/renderer_geometry_instance.h b/servers/rendering/renderer_geometry_instance.h new file mode 100644 index 0000000000..279566d5c9 --- /dev/null +++ b/servers/rendering/renderer_geometry_instance.h @@ -0,0 +1,150 @@ +/*************************************************************************/ +/* renderer_geometry_instance.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 RENDERER_GEOMETRY_INSTANCE_H +#define RENDERER_GEOMETRY_INSTANCE_H + +#include "core/math/rect2.h" +#include "core/math/transform_3d.h" +#include "core/math/vector3.h" +#include "core/templates/rid.h" +#include "storage/utilities.h" + +// API definition for our RenderGeometryInstance class so we can expose this through GDExternal in the near future +class RenderGeometryInstance { +public: + virtual ~RenderGeometryInstance() {} + + virtual void _mark_dirty() = 0; + + virtual void set_skeleton(RID p_skeleton) = 0; + virtual void set_material_override(RID p_override) = 0; + virtual void set_material_overlay(RID p_overlay) = 0; + virtual void set_surface_materials(const Vector<RID> &p_materials) = 0; + virtual void set_mesh_instance(RID p_mesh_instance) = 0; + virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) = 0; + virtual void set_lod_bias(float p_lod_bias) = 0; + virtual void set_layer_mask(uint32_t p_layer_mask) = 0; + virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) = 0; + virtual void set_parent_fade_alpha(float p_alpha) = 0; + virtual void set_transparency(float p_transparency) = 0; + virtual void set_use_baked_light(bool p_enable) = 0; + virtual void set_use_dynamic_gi(bool p_enable) = 0; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0; + virtual void set_lightmap_capture(const Color *p_sh9) = 0; + virtual void set_instance_shader_parameters_offset(int32_t p_offset) = 0; + virtual void set_cast_double_sided_shadows(bool p_enable) = 0; + + virtual Transform3D get_transform() = 0; + virtual AABB get_aabb() = 0; + + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) = 0; + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0; + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0; + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) = 0; + + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) = 0; +}; + +// Base implementation of RenderGeometryInstance shared by internal renderers. +class RenderGeometryInstanceBase : public RenderGeometryInstance { +public: + // setup + uint32_t base_flags = 0; + uint32_t flags_cache = 0; + + // used during rendering + float depth = 0; + + RID mesh_instance; + + Transform3D transform; + bool mirror = false; // move into data? + AABB transformed_aabb; //needed for LOD + bool non_uniform_scale = false; + float lod_model_scale = 1.0; + float lod_bias = 0.0; + + uint32_t layer_mask = 1; + + bool fade_near = false; + float fade_near_begin = 0; + float fade_near_end = 0; + bool fade_far = false; + float fade_far_begin = 0; + float fade_far_end = 0; + + float parent_fade_alpha = 1.0; + float force_alpha = 1.0; + + int32_t shader_parameters_offset = -1; + + struct Data { + //data used less often goes into regular heap + RID base; + RS::InstanceType base_type; + + RID skeleton; + Vector<RID> surface_materials; + RID material_override; + RID material_overlay; + AABB aabb; + + bool use_baked_light = false; + bool use_dynamic_gi = false; + bool cast_double_sided_shadows = false; + bool dirty_dependencies = false; + + DependencyTracker dependency_tracker; + }; + + Data *data = nullptr; + + virtual void set_skeleton(RID p_skeleton) override; + virtual void set_material_override(RID p_override) override; + virtual void set_material_overlay(RID p_overlay) override; + virtual void set_surface_materials(const Vector<RID> &p_materials) override; + virtual void set_mesh_instance(RID p_mesh_instance) override; + virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override; + virtual void set_lod_bias(float p_lod_bias) override; + virtual void set_layer_mask(uint32_t p_layer_mask) override; + virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; + virtual void set_parent_fade_alpha(float p_alpha) override; + virtual void set_transparency(float p_transparency) override; + virtual void set_use_baked_light(bool p_enable) override; + virtual void set_use_dynamic_gi(bool p_enable) override; + virtual void set_instance_shader_parameters_offset(int32_t p_offset) override; + virtual void set_cast_double_sided_shadows(bool p_enable) override; + + virtual Transform3D get_transform() override; + virtual AABB get_aabb() override; +}; + +#endif // RENDERER_GEOMETRY_INSTANCE_H diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index 228933d618..1bb45cbcc1 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -374,7 +374,7 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID } } -void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y) { +void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const Projection &p_cam_projection, bool p_flip_y) { view_xform = p_view_transform.affine_inverse(); projection = p_cam_projection; z_near = projection.get_z_near(); @@ -385,7 +385,7 @@ void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const CameraMa adjusted_projection.adjust_perspective_znear(0.0001); } - CameraMatrix correction; + Projection correction; correction.set_depth_correction(p_flip_y); projection = correction * projection; adjusted_projection = correction * adjusted_projection; diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h index 74ca530ff6..17ca1986c6 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.h +++ b/servers/rendering/renderer_rd/cluster_builder_rd.h @@ -168,8 +168,8 @@ private: uint32_t render_element_max = 0; Transform3D view_xform; - CameraMatrix adjusted_projection; - CameraMatrix projection; + Projection adjusted_projection; + Projection projection; float z_far = 0; float z_near = 0; bool orthogonal = false; @@ -220,7 +220,7 @@ private: public: void setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer); - void begin(const Transform3D &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y); + void begin(const Transform3D &p_view_transform, const Projection &p_cam_projection, bool p_flip_y); _FORCE_INLINE_ void add_light(LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) { if (p_type == LIGHT_TYPE_OMNI && cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT] == max_elements_by_type) { @@ -375,4 +375,4 @@ public: ~ClusterBuilderRD(); }; -#endif // CLUSTER_BUILDER_H +#endif // CLUSTER_BUILDER_RD_H diff --git a/servers/rendering/renderer_rd/effects/bokeh_dof.h b/servers/rendering/renderer_rd/effects/bokeh_dof.h index d7b736119c..30b33be168 100644 --- a/servers/rendering/renderer_rd/effects/bokeh_dof.h +++ b/servers/rendering/renderer_rd/effects/bokeh_dof.h @@ -117,4 +117,4 @@ public: } // namespace RendererRD -#endif // !BOKEH_DOF_RD_H +#endif // BOKEH_DOF_RD_H diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index cbf7046887..5507483cee 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -249,6 +249,56 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) { roughness.raster_pipeline.clear(); } } + + { + Vector<String> specular_modes; + specular_modes.push_back("\n#define MODE_MERGE\n"); // SPECULAR_MERGE_ADD + specular_modes.push_back("\n#define MODE_MERGE\n#define MODE_SSR\n"); // SPECULAR_MERGE_SSR + specular_modes.push_back("\n"); // SPECULAR_MERGE_ADDITIVE_ADD + specular_modes.push_back("\n#define MODE_SSR\n"); // SPECULAR_MERGE_ADDITIVE_SSR + + specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_MERGE\n"); // SPECULAR_MERGE_ADD_MULTIVIEW + specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_MERGE\n#define MODE_SSR\n"); // SPECULAR_MERGE_SSR_MULTIVIEW + specular_modes.push_back("\n#define USE_MULTIVIEW\n"); // SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW + specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_SSR\n"); // SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW + + specular_merge.shader.initialize(specular_modes); + + if (!RendererCompositorRD::singleton->is_xr_enabled()) { + specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADD_MULTIVIEW, false); + specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_SSR_MULTIVIEW, false); + specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW, false); + specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW, false); + } + + specular_merge.shader_version = specular_merge.shader.version_create(); + + //use additive + + RD::PipelineColorBlendState::Attachment ba; + ba.enable_blend = true; + ba.src_color_blend_factor = RD::BLEND_FACTOR_ONE; + ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE; + ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE; + ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE; + ba.color_blend_op = RD::BLEND_OP_ADD; + ba.alpha_blend_op = RD::BLEND_OP_ADD; + + RD::PipelineColorBlendState blend_additive; + blend_additive.attachments.push_back(ba); + + for (int i = 0; i < SPECULAR_MERGE_MAX; i++) { + if (specular_merge.shader.is_variant_enabled(i)) { + RD::PipelineColorBlendState blend_state; + if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR || i == SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW || i == SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW) { + blend_state = blend_additive; + } else { + blend_state = RD::PipelineColorBlendState::create_disabled(); + } + specular_merge.pipelines[i].setup(specular_merge.shader.version_get_shader(specular_merge.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0); + } + } + } } CopyEffects::~CopyEffects() { @@ -264,6 +314,8 @@ CopyEffects::~CopyEffects() { roughness.compute_shader.version_free(roughness.shader_version); } + specular_merge.shader.version_free(specular_merge.shader_version); + RD::get_singleton()->free(filter.coefficient_buffer); if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) { @@ -1083,3 +1135,57 @@ void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_f RD::get_singleton()->draw_list_draw(draw_list, true); RD::get_singleton()->draw_list_end(); } + +void CopyEffects::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection, uint32_t p_view_count) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::get_singleton()->draw_command_begin_label("Merge specular"); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, Vector<Color>()); + + int mode; + if (p_reflection.is_valid()) { + if (p_base.is_valid()) { + mode = SPECULAR_MERGE_SSR; + } else { + mode = SPECULAR_MERGE_ADDITIVE_SSR; + } + } else { + if (p_base.is_valid()) { + mode = SPECULAR_MERGE_ADD; + } else { + mode = SPECULAR_MERGE_ADDITIVE_ADD; + } + } + + if (p_view_count > 1) { + mode += SPECULAR_MERGE_ADD_MULTIVIEW; + } + + RID shader = specular_merge.shader.version_get_shader(specular_merge.shader_version, mode); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + + if (p_base.is_valid()) { + RD::Uniform u_base(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_base })); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_base), 2); + } + + RD::Uniform u_specular(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_specular })); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_specular), 0); + + if (p_reflection.is_valid()) { + RD::Uniform u_reflection(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_reflection })); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_reflection), 1); + } + + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + + RD::get_singleton()->draw_command_end_label(); +} diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h index 882b446964..d25555eee5 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.h +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef COPY_RD_H -#define COPY_RD_H +#ifndef COPY_EFFECTS_RD_H +#define COPY_EFFECTS_RD_H #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl.gen.h" @@ -42,6 +42,7 @@ #include "servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl.gen.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering_server.h" @@ -274,6 +275,33 @@ private: PipelineCacheRD raster_pipeline; } roughness; + // Merge specular + + enum SpecularMergeMode { + SPECULAR_MERGE_ADD, + SPECULAR_MERGE_SSR, + SPECULAR_MERGE_ADDITIVE_ADD, + SPECULAR_MERGE_ADDITIVE_SSR, + + SPECULAR_MERGE_ADD_MULTIVIEW, + SPECULAR_MERGE_SSR_MULTIVIEW, + SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW, + SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW, + + SPECULAR_MERGE_MAX + }; + + /* Specular merge must be done using raster, rather than compute + * because it must continue the existing color buffer + */ + + struct SpecularMerge { + SpecularMergeShaderRD shader; + RID shader_version; + PipelineCacheRD pipelines[SPECULAR_MERGE_MAX]; + + } specular_merge; + static CopyEffects *singleton; public: @@ -309,8 +337,10 @@ public: void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); + + void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection, uint32_t p_view_count); }; } // namespace RendererRD -#endif // !COPY_RD_H +#endif // COPY_EFFECTS_RD_H diff --git a/servers/rendering/renderer_rd/effects/resolve.h b/servers/rendering/renderer_rd/effects/resolve.h index d4b24a610f..2a4cd06827 100644 --- a/servers/rendering/renderer_rd/effects/resolve.h +++ b/servers/rendering/renderer_rd/effects/resolve.h @@ -71,4 +71,4 @@ public: } // namespace RendererRD -#endif // !RESOLVE_RD_H +#endif // RESOLVE_RD_H diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp new file mode 100644 index 0000000000..0f896a8aa7 --- /dev/null +++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp @@ -0,0 +1,1715 @@ +/*************************************************************************/ +/* ss_effects.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "ss_effects.h" + +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" + +using namespace RendererRD; + +SSEffects *SSEffects::singleton = nullptr; + +static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + p_array[i * 4 + j] = p_mtx.matrix[i][j]; + } + } +} + +SSEffects::SSEffects() { + singleton = this; + + { + // Initialize depth buffer for screen space effects + Vector<String> downsampler_modes; + downsampler_modes.push_back("\n"); + downsampler_modes.push_back("\n#define USE_HALF_SIZE\n"); + downsampler_modes.push_back("\n#define GENERATE_MIPS\n"); + downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define USE_HALF_SIZE\n"); + downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n"); + downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n#define USE_HALF_SIZE\n"); + downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define GENERATE_FULL_MIPS"); + + ss_effects.downsample_shader.initialize(downsampler_modes); + + ss_effects.downsample_shader_version = ss_effects.downsample_shader.version_create(); + + for (int i = 0; i < SS_EFFECTS_MAX; i++) { + ss_effects.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, i)); + } + + ss_effects.gather_constants_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSEffectsGatherConstants)); + SSEffectsGatherConstants gather_constants; + + const int sub_pass_count = 5; + for (int pass = 0; pass < 4; pass++) { + for (int subPass = 0; subPass < sub_pass_count; subPass++) { + int a = pass; + int b = subPass; + + int spmap[5]{ 0, 1, 4, 3, 2 }; + b = spmap[subPass]; + + float ca, sa; + float angle0 = (float(a) + float(b) / float(sub_pass_count)) * Math_PI * 0.5f; + + ca = Math::cos(angle0); + sa = Math::sin(angle0); + + float scale = 1.0f + (a - 1.5f + (b - (sub_pass_count - 1.0f) * 0.5f) / float(sub_pass_count)) * 0.07f; + + gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 0] = scale * ca; + gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 1] = scale * -sa; + gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 2] = -scale * sa; + gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 3] = -scale * ca; + } + } + + RD::get_singleton()->buffer_update(ss_effects.gather_constants_buffer, 0, sizeof(SSEffectsGatherConstants), &gather_constants); + } + + // Initialize Screen Space Indirect Lighting (SSIL) + + { + Vector<String> ssil_modes; + ssil_modes.push_back("\n"); + ssil_modes.push_back("\n#define SSIL_BASE\n"); + ssil_modes.push_back("\n#define ADAPTIVE\n"); + + ssil.gather_shader.initialize(ssil_modes); + + ssil.gather_shader_version = ssil.gather_shader.version_create(); + + for (int i = SSIL_GATHER; i <= SSIL_GATHER_ADAPTIVE; i++) { + ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.gather_shader.version_get_shader(ssil.gather_shader_version, i)); + } + ssil.projection_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSILProjectionUniforms)); + } + + { + Vector<String> ssil_modes; + ssil_modes.push_back("\n#define GENERATE_MAP\n"); + ssil_modes.push_back("\n#define PROCESS_MAPA\n"); + ssil_modes.push_back("\n#define PROCESS_MAPB\n"); + + ssil.importance_map_shader.initialize(ssil_modes); + + ssil.importance_map_shader_version = ssil.importance_map_shader.version_create(); + + for (int i = SSIL_GENERATE_IMPORTANCE_MAP; i <= SSIL_PROCESS_IMPORTANCE_MAPB; i++) { + ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, i - SSIL_GENERATE_IMPORTANCE_MAP)); + } + ssil.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t)); + int zero[1] = { 0 }; + RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero); + RD::get_singleton()->set_resource_name(ssil.importance_map_load_counter, "Importance Map Load Counter"); + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 0; + u.append_id(ssil.importance_map_load_counter); + uniforms.push_back(u); + } + ssil.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 2), 2); + RD::get_singleton()->set_resource_name(ssil.counter_uniform_set, "Load Counter Uniform Set"); + } + + { + Vector<String> ssil_modes; + ssil_modes.push_back("\n#define MODE_NON_SMART\n"); + ssil_modes.push_back("\n#define MODE_SMART\n"); + ssil_modes.push_back("\n#define MODE_WIDE\n"); + + ssil.blur_shader.initialize(ssil_modes); + + ssil.blur_shader_version = ssil.blur_shader.version_create(); + for (int i = SSIL_BLUR_PASS; i <= SSIL_BLUR_PASS_WIDE; i++) { + ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.blur_shader.version_get_shader(ssil.blur_shader_version, i - SSIL_BLUR_PASS)); + } + } + + { + Vector<String> ssil_modes; + ssil_modes.push_back("\n#define MODE_NON_SMART\n"); + ssil_modes.push_back("\n#define MODE_SMART\n"); + ssil_modes.push_back("\n#define MODE_HALF\n"); + + ssil.interleave_shader.initialize(ssil_modes); + + ssil.interleave_shader_version = ssil.interleave_shader.version_create(); + for (int i = SSIL_INTERLEAVE; i <= SSIL_INTERLEAVE_HALF; i++) { + ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, i - SSIL_INTERLEAVE)); + } + } + + { + // Initialize Screen Space Ambient Occlusion (SSAO) + + RD::SamplerState sampler; + sampler.mag_filter = RD::SAMPLER_FILTER_NEAREST; + sampler.min_filter = RD::SAMPLER_FILTER_NEAREST; + sampler.mip_filter = RD::SAMPLER_FILTER_NEAREST; + sampler.repeat_u = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; + sampler.repeat_v = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; + sampler.repeat_w = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; + sampler.max_lod = 4; + + uint32_t pipeline = 0; + { + Vector<String> ssao_modes; + + ssao_modes.push_back("\n"); + ssao_modes.push_back("\n#define SSAO_BASE\n"); + ssao_modes.push_back("\n#define ADAPTIVE\n"); + + ssao.gather_shader.initialize(ssao_modes); + + ssao.gather_shader_version = ssao.gather_shader.version_create(); + + for (int i = 0; i <= SSAO_GATHER_ADAPTIVE; i++) { + ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.gather_shader.version_get_shader(ssao.gather_shader_version, i)); + pipeline++; + } + } + + { + Vector<String> ssao_modes; + ssao_modes.push_back("\n#define GENERATE_MAP\n"); + ssao_modes.push_back("\n#define PROCESS_MAPA\n"); + ssao_modes.push_back("\n#define PROCESS_MAPB\n"); + + ssao.importance_map_shader.initialize(ssao_modes); + + ssao.importance_map_shader_version = ssao.importance_map_shader.version_create(); + + for (int i = SSAO_GENERATE_IMPORTANCE_MAP; i <= SSAO_PROCESS_IMPORTANCE_MAPB; i++) { + ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, i - SSAO_GENERATE_IMPORTANCE_MAP)); + + pipeline++; + } + + ssao.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t)); + int zero[1] = { 0 }; + RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero); + RD::get_singleton()->set_resource_name(ssao.importance_map_load_counter, "Importance Map Load Counter"); + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 0; + u.append_id(ssao.importance_map_load_counter); + uniforms.push_back(u); + } + ssao.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2), 2); + RD::get_singleton()->set_resource_name(ssao.counter_uniform_set, "Load Counter Uniform Set"); + } + + { + Vector<String> ssao_modes; + ssao_modes.push_back("\n#define MODE_NON_SMART\n"); + ssao_modes.push_back("\n#define MODE_SMART\n"); + ssao_modes.push_back("\n#define MODE_WIDE\n"); + + ssao.blur_shader.initialize(ssao_modes); + + ssao.blur_shader_version = ssao.blur_shader.version_create(); + + for (int i = SSAO_BLUR_PASS; i <= SSAO_BLUR_PASS_WIDE; i++) { + ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.blur_shader.version_get_shader(ssao.blur_shader_version, i - SSAO_BLUR_PASS)); + + pipeline++; + } + } + + { + Vector<String> ssao_modes; + ssao_modes.push_back("\n#define MODE_NON_SMART\n"); + ssao_modes.push_back("\n#define MODE_SMART\n"); + ssao_modes.push_back("\n#define MODE_HALF\n"); + + ssao.interleave_shader.initialize(ssao_modes); + + ssao.interleave_shader_version = ssao.interleave_shader.version_create(); + for (int i = SSAO_INTERLEAVE; i <= SSAO_INTERLEAVE_HALF; i++) { + ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, i - SSAO_INTERLEAVE)); + RD::get_singleton()->set_resource_name(ssao.pipelines[pipeline], "Interleave Pipeline " + itos(i)); + pipeline++; + } + } + + ERR_FAIL_COND(pipeline != SSAO_MAX); + + ss_effects.mirror_sampler = RD::get_singleton()->sampler_create(sampler); + } + + { + // Screen Space Reflections + + Vector<RD::PipelineSpecializationConstant> specialization_constants; + + { + RD::PipelineSpecializationConstant sc; + sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL; + sc.constant_id = 0; // SSR_USE_FULL_PROJECTION_MATRIX + sc.bool_value = false; + specialization_constants.push_back(sc); + } + + { + Vector<String> ssr_scale_modes; + ssr_scale_modes.push_back("\n"); + + ssr_scale.shader.initialize(ssr_scale_modes); + ssr_scale.shader_version = ssr_scale.shader.version_create(); + + for (int v = 0; v < SSR_VARIATIONS; v++) { + specialization_constants.ptrw()[0].bool_value = (v & SSR_MULTIVIEW) ? true : false; + ssr_scale.pipelines[v] = RD::get_singleton()->compute_pipeline_create(ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), specialization_constants); + } + } + + { + Vector<String> ssr_modes; + ssr_modes.push_back("\n"); // SCREEN_SPACE_REFLECTION_NORMAL + ssr_modes.push_back("\n#define MODE_ROUGH\n"); // SCREEN_SPACE_REFLECTION_ROUGH + + ssr.shader.initialize(ssr_modes); + ssr.shader_version = ssr.shader.version_create(); + + for (int v = 0; v < SSR_VARIATIONS; v++) { + specialization_constants.ptrw()[0].bool_value = (v & SSR_MULTIVIEW) ? true : false; + for (int i = 0; i < SCREEN_SPACE_REFLECTION_MAX; i++) { + ssr.pipelines[v][i] = RD::get_singleton()->compute_pipeline_create(ssr.shader.version_get_shader(ssr.shader_version, i), specialization_constants); + } + } + } + + { + Vector<String> ssr_filter_modes; + ssr_filter_modes.push_back("\n"); // SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL + ssr_filter_modes.push_back("\n#define VERTICAL_PASS\n"); // SCREEN_SPACE_REFLECTION_FILTER_VERTICAL + + ssr_filter.shader.initialize(ssr_filter_modes); + ssr_filter.shader_version = ssr_filter.shader.version_create(); + + for (int v = 0; v < SSR_VARIATIONS; v++) { + specialization_constants.ptrw()[0].bool_value = (v & SSR_MULTIVIEW) ? true : false; + for (int i = 0; i < SCREEN_SPACE_REFLECTION_FILTER_MAX; i++) { + ssr_filter.pipelines[v][i] = RD::get_singleton()->compute_pipeline_create(ssr_filter.shader.version_get_shader(ssr_filter.shader_version, i), specialization_constants); + } + } + } + } +} + +SSEffects::~SSEffects() { + { + // Cleanup SS Reflections + ssr.shader.version_free(ssr.shader_version); + ssr_filter.shader.version_free(ssr_filter.shader_version); + ssr_scale.shader.version_free(ssr_scale.shader_version); + + if (ssr.ubo.is_valid()) { + RD::get_singleton()->free(ssr.ubo); + } + } + + { + // Cleanup SS downsampler + ss_effects.downsample_shader.version_free(ss_effects.downsample_shader_version); + + RD::get_singleton()->free(ss_effects.mirror_sampler); + RD::get_singleton()->free(ss_effects.gather_constants_buffer); + } + + { + // Cleanup SSIL + ssil.blur_shader.version_free(ssil.blur_shader_version); + ssil.gather_shader.version_free(ssil.gather_shader_version); + ssil.interleave_shader.version_free(ssil.interleave_shader_version); + ssil.importance_map_shader.version_free(ssil.importance_map_shader_version); + + RD::get_singleton()->free(ssil.importance_map_load_counter); + RD::get_singleton()->free(ssil.projection_uniform_buffer); + } + + { + // Cleanup SSAO + ssao.blur_shader.version_free(ssao.blur_shader_version); + ssao.gather_shader.version_free(ssao.gather_shader_version); + ssao.interleave_shader.version_free(ssao.interleave_shader_version); + ssao.importance_map_shader.version_free(ssao.importance_map_shader_version); + + RD::get_singleton()->free(ssao.importance_map_load_counter); + } + + singleton = nullptr; +} + +/* SS Downsampler */ + +void SSEffects::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const Projection &p_projection) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + // Downsample and deinterleave the depth buffer for SSAO and SSIL + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + + int downsample_mode = SS_EFFECTS_DOWNSAMPLE; + bool use_mips = p_ssao_quality > RS::ENV_SSAO_QUALITY_MEDIUM || p_ssil_quality > RS::ENV_SSIL_QUALITY_MEDIUM; + + if (p_ssao_quality == RS::ENV_SSAO_QUALITY_VERY_LOW && p_ssil_quality == RS::ENV_SSIL_QUALITY_VERY_LOW) { + downsample_mode = SS_EFFECTS_DOWNSAMPLE_HALF; + } else if (use_mips) { + downsample_mode = SS_EFFECTS_DOWNSAMPLE_MIPMAP; + } + + bool use_half_size = false; + bool use_full_mips = false; + + if (p_ssao_half_size && p_ssil_half_size) { + downsample_mode++; + use_half_size = true; + } else if (p_ssao_half_size != p_ssil_half_size) { + if (use_mips) { + downsample_mode = SS_EFFECTS_DOWNSAMPLE_FULL_MIPS; + use_full_mips = true; + } else { + // Only need the first two mipmaps, but the cost to generate the next two is trivial + // TODO investigate the benefit of a shader version to generate only 2 mips + downsample_mode = SS_EFFECTS_DOWNSAMPLE_MIPMAP; + use_mips = true; + } + } + + int depth_index = use_half_size ? 1 : 0; + + RD::get_singleton()->draw_command_begin_label("Downsample Depth"); + if (p_invalidate_uniform_set || use_full_mips != ss_effects.used_full_mips_last_frame || use_half_size != ss_effects.used_half_size_last_frame || use_mips != ss_effects.used_mips_last_frame) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 0; + u.append_id(p_depth_mipmaps[depth_index + 1]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 1; + u.append_id(p_depth_mipmaps[depth_index + 2]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 2; + u.append_id(p_depth_mipmaps[depth_index + 3]); + uniforms.push_back(u); + } + if (use_full_mips) { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 3; + u.append_id(p_depth_mipmaps[4]); + uniforms.push_back(u); + } + ss_effects.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, use_full_mips ? 6 : 2), 2); + } + + float depth_linearize_mul = -p_projection.matrix[3][2]; + float depth_linearize_add = p_projection.matrix[2][2]; + if (depth_linearize_mul * depth_linearize_add < 0) { + depth_linearize_add = -depth_linearize_add; + } + + ss_effects.downsample_push_constant.orthogonal = p_projection.is_orthogonal(); + ss_effects.downsample_push_constant.z_near = depth_linearize_mul; + ss_effects.downsample_push_constant.z_far = depth_linearize_add; + if (ss_effects.downsample_push_constant.orthogonal) { + ss_effects.downsample_push_constant.z_near = p_projection.get_z_near(); + ss_effects.downsample_push_constant.z_far = p_projection.get_z_far(); + } + ss_effects.downsample_push_constant.pixel_size[0] = 1.0 / p_full_screen_size.x; + ss_effects.downsample_push_constant.pixel_size[1] = 1.0 / p_full_screen_size.y; + ss_effects.downsample_push_constant.radius_sq = 1.0; + + RID shader = ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, downsample_mode); + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_depth_buffer(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_depth_buffer })); + RD::Uniform u_depth_mipmaps(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_depth_mipmaps[depth_index + 0] })); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ss_effects.pipelines[downsample_mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_depth_buffer), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_depth_mipmaps), 1); + if (use_mips) { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ss_effects.downsample_uniform_set, 2); + } + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ss_effects.downsample_push_constant, sizeof(SSEffectsDownsamplePushConstant)); + + Size2i size(MAX(1, p_full_screen_size.x >> (use_half_size ? 2 : 1)), MAX(1, p_full_screen_size.y >> (use_half_size ? 2 : 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(); + + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); + + ss_effects.used_full_mips_last_frame = use_full_mips; + ss_effects.used_half_size_last_frame = use_half_size; +} + +/* SSIL */ + +void SSEffects::gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + + RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0); + if ((p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) && !p_adaptive_base_pass) { + RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1); + } + RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_projection_uniform_set, 3); + + RID shader = ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0); + + for (int i = 0; i < 4; i++) { + if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) { + continue; + } + + RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_slices[i] })); + RD::Uniform u_edges_slice(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_edges_slices[i] })); + + ssil.gather_push_constant.pass_coord_offset[0] = i % 2; + ssil.gather_push_constant.pass_coord_offset[1] = i / 2; + ssil.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x; + ssil.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y; + ssil.gather_push_constant.pass = i; + RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, uniform_set_cache->get_cache(shader, 2, u_ssil_slice, u_edges_slice), 2); + RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssil.gather_push_constant, sizeof(SSILGatherPushConstant)); + + 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_threads(p_compute_list, size.x, size.y, 1); + } + RD::get_singleton()->compute_list_add_barrier(p_compute_list); +} + +void SSEffects::ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth) { + if (p_ssil_buffers.half_size != p_settings.half_size) { + ssil_free(p_ssil_buffers); + } + + if (p_settings.half_size) { + p_ssil_buffers.buffer_width = (p_settings.full_screen_size.x + 3) / 4; + p_ssil_buffers.buffer_height = (p_settings.full_screen_size.y + 3) / 4; + p_ssil_buffers.half_buffer_width = (p_settings.full_screen_size.x + 7) / 8; + p_ssil_buffers.half_buffer_height = (p_settings.full_screen_size.y + 7) / 8; + } else { + p_ssil_buffers.buffer_width = (p_settings.full_screen_size.x + 1) / 2; + p_ssil_buffers.buffer_height = (p_settings.full_screen_size.y + 1) / 2; + p_ssil_buffers.half_buffer_width = (p_settings.full_screen_size.x + 3) / 4; + p_ssil_buffers.half_buffer_height = (p_settings.full_screen_size.y + 3) / 4; + } + + if (p_ssil_buffers.ssil_final.is_null()) { + { + p_ssil_buffers.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_linear_depth, 0, p_settings.half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY); + } + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.width = p_settings.full_screen_size.x; + tf.height = p_settings.full_screen_size.y; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + p_ssil_buffers.ssil_final = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssil_buffers.ssil_final, "SSIL texture"); + RD::get_singleton()->texture_clear(p_ssil_buffers.ssil_final, Color(0, 0, 0, 0), 0, 1, 0, 1); + if (p_ssil_buffers.last_frame.is_null()) { + tf.mipmaps = 6; + p_ssil_buffers.last_frame = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssil_buffers.last_frame, "Last Frame Radiance"); + RD::get_singleton()->texture_clear(p_ssil_buffers.last_frame, Color(0, 0, 0, 0), 0, tf.mipmaps, 0, 1); + for (uint32_t i = 0; i < 6; i++) { + RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.last_frame, 0, i); + p_ssil_buffers.last_frame_slices.push_back(slice); + RD::get_singleton()->set_resource_name(slice, "Last Frame Radiance Mip " + itos(i) + " "); + } + } + } + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.width = p_ssil_buffers.buffer_width; + tf.height = p_ssil_buffers.buffer_height; + tf.array_layers = 4; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + p_ssil_buffers.deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssil_buffers.deinterleaved, "SSIL deinterleaved buffer"); + for (uint32_t i = 0; i < 4; i++) { + RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.deinterleaved, i, 0); + p_ssil_buffers.deinterleaved_slices.push_back(slice); + RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer array " + itos(i) + " "); + } + } + + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.width = p_ssil_buffers.buffer_width; + tf.height = p_ssil_buffers.buffer_height; + tf.array_layers = 4; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + p_ssil_buffers.pong = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssil_buffers.pong, "SSIL deinterleaved pong buffer"); + for (uint32_t i = 0; i < 4; i++) { + RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.pong, i, 0); + p_ssil_buffers.pong_slices.push_back(slice); + RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer pong array " + itos(i) + " "); + } + } + + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.width = p_ssil_buffers.buffer_width; + tf.height = p_ssil_buffers.buffer_height; + tf.array_layers = 4; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + p_ssil_buffers.edges = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssil_buffers.edges, "SSIL edges buffer"); + for (uint32_t i = 0; i < 4; i++) { + RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssil_buffers.edges, i, 0); + p_ssil_buffers.edges_slices.push_back(slice); + RD::get_singleton()->set_resource_name(slice, "SSIL edges buffer slice " + itos(i) + " "); + } + } + + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.width = p_ssil_buffers.half_buffer_width; + tf.height = p_ssil_buffers.half_buffer_height; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + p_ssil_buffers.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssil_buffers.importance_map[0], "SSIL Importance Map"); + p_ssil_buffers.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssil_buffers.importance_map[1], "SSIL Importance Map Pong"); + } + p_ssil_buffers.half_size = p_settings.half_size; + } +} + +void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + RD::get_singleton()->draw_command_begin_label("Process Screen Space Indirect Lighting"); + //Store projection info before starting the compute list + SSILProjectionUniforms projection_uniforms; + store_camera(p_last_projection, projection_uniforms.inv_last_frame_projection_matrix); + + RD::get_singleton()->buffer_update(ssil.projection_uniform_buffer, 0, sizeof(SSILProjectionUniforms), &projection_uniforms); + + memset(&ssil.gather_push_constant, 0, sizeof(SSILGatherPushConstant)); + + RID shader = ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0); + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + { + RD::get_singleton()->draw_command_begin_label("Gather Samples"); + ssil.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x; + ssil.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y; + + ssil.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width; + ssil.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height; + float tan_half_fov_x = 1.0 / p_projection.matrix[0][0]; + float tan_half_fov_y = 1.0 / p_projection.matrix[1][1]; + ssil.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0; + ssil.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0; + ssil.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0; + ssil.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y; + ssil.gather_push_constant.z_near = p_projection.get_z_near(); + ssil.gather_push_constant.z_far = p_projection.get_z_far(); + ssil.gather_push_constant.is_orthogonal = p_projection.is_orthogonal(); + + ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.25; + ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.25; + + ssil.gather_push_constant.radius = p_settings.radius; + float radius_near_limit = (p_settings.radius * 1.2f); + if (p_settings.quality <= RS::ENV_SSIL_QUALITY_LOW) { + radius_near_limit *= 1.50f; + + if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) { + ssil.gather_push_constant.radius *= 0.8f; + } + } + radius_near_limit /= tan_half_fov_y; + ssil.gather_push_constant.intensity = p_settings.intensity * Math_PI; + ssil.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from); + ssil.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0; + ssil.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit; + ssil.gather_push_constant.neg_inv_radius = -1.0 / ssil.gather_push_constant.radius; + ssil.gather_push_constant.normal_rejection_amount = p_settings.normal_rejection; + + ssil.gather_push_constant.load_counter_avg_div = 9.0 / float((p_ssil_buffers.half_buffer_width) * (p_ssil_buffers.half_buffer_height) * 255); + ssil.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target; + + ssil.gather_push_constant.quality = MAX(0, p_settings.quality - 1); + ssil.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1; + + if (p_ssil_buffers.projection_uniform_set.is_null()) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.binding = 0; + u.append_id(default_mipmap_sampler); + u.append_id(p_ssil_buffers.last_frame); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 1; + u.append_id(ssil.projection_uniform_buffer); + uniforms.push_back(u); + } + p_ssil_buffers.projection_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 3); + } + + if (p_ssil_buffers.gather_uniform_set.is_null()) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.binding = 0; + u.append_id(default_sampler); + u.append_id(p_ssil_buffers.depth_texture_view); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 1; + u.append_id(p_normal_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 2; + u.append_id(ss_effects.gather_constants_buffer); + uniforms.push_back(u); + } + p_ssil_buffers.gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 0); + } + + if (p_ssil_buffers.importance_map_uniform_set.is_null()) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 0; + u.append_id(p_ssil_buffers.pong); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.binding = 1; + u.append_id(default_sampler); + u.append_id(p_ssil_buffers.importance_map[0]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 2; + u.append_id(ssil.importance_map_load_counter); + uniforms.push_back(u); + } + p_ssil_buffers.importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 2), 1); + } + + if (p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) { + RD::get_singleton()->draw_command_begin_label("Generate Importance Map"); + ssil.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width; + ssil.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height; + ssil.importance_map_push_constant.intensity = p_settings.intensity * Math_PI; + //base pass + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_BASE]); + gather_ssil(compute_list, p_ssil_buffers.pong_slices, p_ssil_buffers.edges_slices, p_settings, true, p_ssil_buffers.gather_uniform_set, p_ssil_buffers.importance_map_uniform_set, p_ssil_buffers.projection_uniform_set); + + //generate importance map + RD::Uniform u_ssil_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong })); + RD::Uniform u_importance_map(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.importance_map[0] })); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GENERATE_IMPORTANCE_MAP]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_with_sampler), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + // process Importance Map A + RD::Uniform u_importance_map_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.importance_map[0] })); + RD::Uniform u_importance_map_pong(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.importance_map[1] })); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPA]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_with_sampler), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map_pong), 1); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + // process Importance Map B + RD::Uniform u_importance_map_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.importance_map[1] })); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPB]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_pong_with_sampler), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_importance_map), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssil.counter_uniform_set, 2); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_ssil_buffers.half_buffer_width, p_ssil_buffers.half_buffer_height, 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + RD::get_singleton()->draw_command_end_label(); // Importance Map + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_ADAPTIVE]); + } else { + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER]); + } + + gather_ssil(compute_list, p_ssil_buffers.deinterleaved_slices, p_ssil_buffers.edges_slices, p_settings, false, p_ssil_buffers.gather_uniform_set, p_ssil_buffers.importance_map_uniform_set, p_ssil_buffers.projection_uniform_set); + RD::get_singleton()->draw_command_end_label(); //Gather + } + + { + RD::get_singleton()->draw_command_begin_label("Edge Aware Blur"); + ssil.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness; + ssil.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width; + ssil.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height; + + int blur_passes = p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW ? p_settings.blur_passes : 1; + + shader = ssil.blur_shader.version_get_shader(ssil.blur_shader_version, 0); + + for (int pass = 0; pass < blur_passes; pass++) { + int blur_pipeline = SSIL_BLUR_PASS; + if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) { + blur_pipeline = SSIL_BLUR_PASS_SMART; + if (pass < blur_passes - 2) { + blur_pipeline = SSIL_BLUR_PASS_WIDE; + } + } + + for (int i = 0; i < 4; i++) { + if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) { + continue; + } + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[blur_pipeline]); + if (pass % 2 == 0) { + if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) { + RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.deinterleaved_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_slice), 0); + } else { + RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssil_buffers.deinterleaved_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_slice), 0); + } + + RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.pong_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_pong_slice), 1); + } else { + if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) { + RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_slice), 0); + } else { + RD::Uniform u_ssil_pong_slice(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssil_buffers.pong_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ssil_pong_slice), 0); + } + + RD::Uniform u_ssil_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.deinterleaved_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_slice), 1); + } + + RD::Uniform u_edges_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.edges_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_edges_slice), 2); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.blur_push_constant, sizeof(SSILBlurPushConstant)); + + int x_groups = (p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)); + int y_groups = (p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, x_groups, y_groups, 1); + if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) { + RD::get_singleton()->compute_list_add_barrier(compute_list); + } + } + } + + RD::get_singleton()->draw_command_end_label(); // Blur + } + + { + RD::get_singleton()->draw_command_begin_label("Interleave Buffers"); + ssil.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness; + ssil.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x; + ssil.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y; + ssil.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2); + + int interleave_pipeline = SSIL_INTERLEAVE_HALF; + if (p_settings.quality == RS::ENV_SSIL_QUALITY_LOW) { + interleave_pipeline = SSIL_INTERLEAVE; + } else if (p_settings.quality >= RS::ENV_SSIL_QUALITY_MEDIUM) { + interleave_pipeline = SSIL_INTERLEAVE_SMART; + } + + shader = ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, 0); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[interleave_pipeline]); + + RD::Uniform u_destination(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.ssil_final })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_destination), 0); + + if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) { + RD::Uniform u_ssil(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.deinterleaved })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil), 1); + } else { + RD::Uniform u_ssil_pong(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssil_buffers.pong })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ssil_pong), 1); + } + + RD::Uniform u_edges(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssil_buffers.edges })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_edges), 2); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.interleave_push_constant, sizeof(SSILInterleavePushConstant)); + + 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(); // SSIL + + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); + + int zero[1] = { 0 }; + RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier +} + +void SSEffects::ssil_free(SSILRenderBuffers &p_ssil_buffers) { + if (p_ssil_buffers.ssil_final.is_valid()) { + RD::get_singleton()->free(p_ssil_buffers.ssil_final); + RD::get_singleton()->free(p_ssil_buffers.deinterleaved); + RD::get_singleton()->free(p_ssil_buffers.pong); + RD::get_singleton()->free(p_ssil_buffers.edges); + RD::get_singleton()->free(p_ssil_buffers.importance_map[0]); + RD::get_singleton()->free(p_ssil_buffers.importance_map[1]); + RD::get_singleton()->free(p_ssil_buffers.last_frame); + + p_ssil_buffers.ssil_final = RID(); + p_ssil_buffers.deinterleaved = RID(); + p_ssil_buffers.pong = RID(); + p_ssil_buffers.edges = RID(); + p_ssil_buffers.deinterleaved_slices.clear(); + p_ssil_buffers.pong_slices.clear(); + p_ssil_buffers.edges_slices.clear(); + p_ssil_buffers.importance_map[0] = RID(); + p_ssil_buffers.importance_map[1] = RID(); + p_ssil_buffers.last_frame = RID(); + p_ssil_buffers.last_frame_slices.clear(); + + p_ssil_buffers.gather_uniform_set = RID(); + p_ssil_buffers.importance_map_uniform_set = RID(); + p_ssil_buffers.projection_uniform_set = RID(); + } +} + +/* SSAO */ + +void SSEffects::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + + RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0); + if ((p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) { + RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 0); + } + + RID shader = ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 1); // + + for (int i = 0; i < 4; i++) { + if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) { + continue; + } + + RD::Uniform u_ao_slice(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ao_slices[i] })); + + ssao.gather_push_constant.pass_coord_offset[0] = i % 2; + ssao.gather_push_constant.pass_coord_offset[1] = i / 2; + ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x; + ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y; + ssao.gather_push_constant.pass = i; + RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, uniform_set_cache->get_cache(shader, 2, u_ao_slice), 2); + RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssao.gather_push_constant, sizeof(SSAOGatherPushConstant)); + + 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_threads(p_compute_list, size.x, size.y, 1); + } + RD::get_singleton()->compute_list_add_barrier(p_compute_list); +} + +void SSEffects::ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth) { + if (p_ssao_buffers.half_size != p_settings.half_size) { + ssao_free(p_ssao_buffers); + } + + if (p_settings.half_size) { + p_ssao_buffers.buffer_width = (p_settings.full_screen_size.x + 3) / 4; + p_ssao_buffers.buffer_height = (p_settings.full_screen_size.y + 3) / 4; + p_ssao_buffers.half_buffer_width = (p_settings.full_screen_size.x + 7) / 8; + p_ssao_buffers.half_buffer_height = (p_settings.full_screen_size.y + 7) / 8; + } else { + p_ssao_buffers.buffer_width = (p_settings.full_screen_size.x + 1) / 2; + p_ssao_buffers.buffer_height = (p_settings.full_screen_size.y + 1) / 2; + p_ssao_buffers.half_buffer_width = (p_settings.full_screen_size.x + 3) / 4; + p_ssao_buffers.half_buffer_height = (p_settings.full_screen_size.y + 3) / 4; + } + + if (p_ssao_buffers.ao_deinterleaved.is_null()) { + { + p_ssao_buffers.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_linear_depth, 0, p_settings.half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY); + } + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8G8_UNORM; + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.width = p_ssao_buffers.buffer_width; + tf.height = p_ssao_buffers.buffer_height; + tf.array_layers = 4; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + p_ssao_buffers.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_deinterleaved, "SSAO De-interleaved Array"); + for (uint32_t i = 0; i < 4; i++) { + RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssao_buffers.ao_deinterleaved, i, 0); + p_ssao_buffers.ao_deinterleaved_slices.push_back(slice); + RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " "); + } + } + + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8G8_UNORM; + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.width = p_ssao_buffers.buffer_width; + tf.height = p_ssao_buffers.buffer_height; + tf.array_layers = 4; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + p_ssao_buffers.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_pong, "SSAO De-interleaved Array Pong"); + for (uint32_t i = 0; i < 4; i++) { + RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssao_buffers.ao_pong, i, 0); + p_ssao_buffers.ao_pong_slices.push_back(slice); + RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " Pong"); + } + } + + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.width = p_ssao_buffers.buffer_width; + tf.height = p_ssao_buffers.buffer_height; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + p_ssao_buffers.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map[0], "SSAO Importance Map"); + p_ssao_buffers.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map[1], "SSAO Importance Map Pong"); + } + { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.width = p_settings.full_screen_size.x; + tf.height = p_settings.full_screen_size.y; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + p_ssao_buffers.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssao_buffers.ao_final, "SSAO Final"); + } + p_ssao_buffers.half_size = p_settings.half_size; + } +} + +void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + memset(&ssao.gather_push_constant, 0, sizeof(SSAOGatherPushConstant)); + /* FIRST PASS */ + + RID shader = ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0); + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::get_singleton()->draw_command_begin_label("Process Screen Space Ambient Occlusion"); + /* SECOND PASS */ + // Sample SSAO + { + RD::get_singleton()->draw_command_begin_label("Gather Samples"); + ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x; + ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y; + + ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width; + ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height; + float tan_half_fov_x = 1.0 / p_projection.matrix[0][0]; + float tan_half_fov_y = 1.0 / p_projection.matrix[1][1]; + ssao.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0; + ssao.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0; + ssao.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0; + ssao.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y; + ssao.gather_push_constant.is_orthogonal = p_projection.is_orthogonal(); + + ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.25; + ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.25; + + ssao.gather_push_constant.radius = p_settings.radius; + float radius_near_limit = (p_settings.radius * 1.2f); + if (p_settings.quality <= RS::ENV_SSAO_QUALITY_LOW) { + radius_near_limit *= 1.50f; + + if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) { + ssao.gather_push_constant.radius *= 0.8f; + } + } + radius_near_limit /= tan_half_fov_y; + ssao.gather_push_constant.intensity = p_settings.intensity; + ssao.gather_push_constant.shadow_power = p_settings.power; + ssao.gather_push_constant.shadow_clamp = 0.98; + ssao.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from); + ssao.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0; + ssao.gather_push_constant.horizon_angle_threshold = p_settings.horizon; + ssao.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit; + ssao.gather_push_constant.neg_inv_radius = -1.0 / ssao.gather_push_constant.radius; + + ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_ssao_buffers.half_buffer_width) * (p_ssao_buffers.half_buffer_height) * 255); + ssao.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target; + + ssao.gather_push_constant.detail_intensity = p_settings.detail; + ssao.gather_push_constant.quality = MAX(0, p_settings.quality - 1); + ssao.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1; + + if (p_ssao_buffers.gather_uniform_set.is_null()) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.binding = 0; + u.append_id(default_sampler); + u.append_id(p_ssao_buffers.depth_texture_view); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 1; + u.append_id(p_normal_buffer); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 2; + u.append_id(ss_effects.gather_constants_buffer); + uniforms.push_back(u); + } + p_ssao_buffers.gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader, 0); + RD::get_singleton()->set_resource_name(p_ssao_buffers.gather_uniform_set, "SSAO Gather Uniform Set"); + } + + if (p_ssao_buffers.importance_map_uniform_set.is_null()) { + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 0; + u.append_id(p_ssao_buffers.ao_pong); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; + u.binding = 1; + u.append_id(default_sampler); + u.append_id(p_ssao_buffers.importance_map[0]); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 2; + u.append_id(ssao.importance_map_load_counter); + uniforms.push_back(u); + } + p_ssao_buffers.importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1); + RD::get_singleton()->set_resource_name(p_ssao_buffers.importance_map_uniform_set, "SSAO Importance Map Uniform Set"); + } + + if (p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) { + RD::get_singleton()->draw_command_begin_label("Generate Importance Map"); + ssao.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width; + ssao.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height; + ssao.importance_map_push_constant.intensity = p_settings.intensity; + ssao.importance_map_push_constant.power = p_settings.power; + + //base pass + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]); + gather_ssao(compute_list, p_ssao_buffers.ao_pong_slices, p_settings, true, p_ssao_buffers.gather_uniform_set, RID()); + + //generate importance map + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]); + + RD::Uniform u_ao_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_with_sampler), 0); + + RD::Uniform u_importance_map(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.importance_map[0] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_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_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 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::Uniform u_importance_map_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.importance_map[0] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_with_sampler), 0); + + RD::Uniform u_importance_map_pong(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.importance_map[1] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_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_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 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]); + + RD::Uniform u_importance_map_pong_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.importance_map[1] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_importance_map_pong_with_sampler), 0); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_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_threads(compute_list, p_ssao_buffers.half_buffer_width, p_ssao_buffers.half_buffer_height, 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]); + RD::get_singleton()->draw_command_end_label(); // Importance Map + } else { + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]); + } + + gather_ssao(compute_list, p_ssao_buffers.ao_deinterleaved_slices, p_settings, false, p_ssao_buffers.gather_uniform_set, p_ssao_buffers.importance_map_uniform_set); + RD::get_singleton()->draw_command_end_label(); // Gather SSAO + } + + // /* THIRD PASS */ + // // Blur + // + { + RD::get_singleton()->draw_command_begin_label("Edge Aware Blur"); + ssao.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness; + ssao.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width; + ssao.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height; + + int blur_passes = p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW ? p_settings.blur_passes : 1; + + shader = ssao.blur_shader.version_get_shader(ssao.blur_shader_version, 0); + + for (int pass = 0; pass < blur_passes; pass++) { + int blur_pipeline = SSAO_BLUR_PASS; + if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) { + blur_pipeline = SSAO_BLUR_PASS_SMART; + if (pass < blur_passes - 2) { + blur_pipeline = SSAO_BLUR_PASS_WIDE; + } else { + blur_pipeline = SSAO_BLUR_PASS_SMART; + } + } + + for (int i = 0; i < 4; i++) { + if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) { + continue; + } + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[blur_pipeline]); + if (pass % 2 == 0) { + if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) { + RD::Uniform u_ao_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_deinterleaved_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_slices_with_sampler), 0); + } else { + RD::Uniform u_ao_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssao_buffers.ao_deinterleaved_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_slices_with_sampler), 0); + } + + RD::Uniform u_ao_pong_slices(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_pong_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao_pong_slices), 1); + } else { + if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) { + RD::Uniform u_ao_pong_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_slices_with_sampler), 0); + } else { + RD::Uniform u_ao_pong_slices_with_sampler(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ ss_effects.mirror_sampler, p_ssao_buffers.ao_pong_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_ao_pong_slices_with_sampler), 0); + } + + RD::Uniform u_ao_slices(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_deinterleaved_slices[i] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao_slices), 1); + } + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant)); + + 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) { + RD::get_singleton()->compute_list_add_barrier(compute_list); + } + } + RD::get_singleton()->draw_command_end_label(); // Blur + } + + /* FOURTH PASS */ + // Interleave buffers + // back to full size + { + RD::get_singleton()->draw_command_begin_label("Interleave Buffers"); + ssao.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness; + ssao.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x; + ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y; + ssao.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2); + + shader = ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, 0); + + int interleave_pipeline = SSAO_INTERLEAVE_HALF; + if (p_settings.quality == RS::ENV_SSAO_QUALITY_LOW) { + interleave_pipeline = SSAO_INTERLEAVE; + } else if (p_settings.quality >= RS::ENV_SSAO_QUALITY_MEDIUM) { + interleave_pipeline = SSAO_INTERLEAVE_SMART; + } + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[interleave_pipeline]); + + RD::Uniform u_upscale_buffer(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssao_buffers.ao_final })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_upscale_buffer), 0); + + if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) { + RD::Uniform u_ao(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_deinterleaved })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao), 1); + } else { + RD::Uniform u_ao(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_ssao_buffers.ao_pong })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_ao), 1); + } + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant)); + + 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::BARRIER_MASK_NO_BARRIER); //wait for upcoming transfer + + int zero[1] = { 0 }; + RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier +} + +void SSEffects::ssao_free(SSAORenderBuffers &p_ssao_buffers) { + if (p_ssao_buffers.ao_final.is_valid()) { + RD::get_singleton()->free(p_ssao_buffers.ao_deinterleaved); + RD::get_singleton()->free(p_ssao_buffers.ao_pong); + RD::get_singleton()->free(p_ssao_buffers.ao_final); + + RD::get_singleton()->free(p_ssao_buffers.importance_map[0]); + RD::get_singleton()->free(p_ssao_buffers.importance_map[1]); + + p_ssao_buffers.ao_deinterleaved = RID(); + p_ssao_buffers.ao_pong = RID(); + p_ssao_buffers.ao_final = RID(); + p_ssao_buffers.importance_map[0] = RID(); + p_ssao_buffers.importance_map[1] = RID(); + p_ssao_buffers.ao_deinterleaved_slices.clear(); + p_ssao_buffers.ao_pong_slices.clear(); + + p_ssao_buffers.gather_uniform_set = RID(); + p_ssao_buffers.importance_map_uniform_set = RID(); + } +} + +/* Screen Space Reflection */ + +void SSEffects::ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const Size2i &p_screen_size, const uint32_t p_view_count) { + // As we are processing one view at a time, we can reuse buffers, only our output needs to have layers for each view. + + if (p_ssr_buffers.depth_scaled.is_null()) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R32_SFLOAT; + tf.width = p_screen_size.x; + tf.height = p_screen_size.y; + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; + + p_ssr_buffers.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssr_buffers.depth_scaled, "SSR Depth Scaled"); + + tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; + + p_ssr_buffers.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssr_buffers.normal_scaled, "SSR Normal Scaled"); + } + + if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED && !p_ssr_buffers.blur_radius[0].is_valid()) { + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.width = p_screen_size.x; + tf.height = p_screen_size.y; + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + + p_ssr_buffers.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssr_buffers.blur_radius[0], "SSR Blur Radius 0"); + p_ssr_buffers.blur_radius[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssr_buffers.blur_radius[1], "SSR Blur Radius 1"); + } + + if (p_ssr_buffers.intermediate.is_null()) { + RD::TextureFormat tf; + tf.format = p_color_format; + tf.width = p_screen_size.x; + tf.height = p_screen_size.y; + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + + p_ssr_buffers.intermediate = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssr_buffers.intermediate, "SSR Intermediate"); + + if (p_view_count > 1) { + tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tf.array_layers = p_view_count; + } else { + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + } + + p_ssr_buffers.output = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(p_ssr_buffers.output, "SSR Output"); + + for (uint32_t v = 0; v < p_view_count; v++) { + p_ssr_buffers.output_slices[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_ssr_buffers.output, v, 0); + } + } +} + +void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const RID *p_metallic_slices, const Color &p_metallic_mask, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + { + // Store some scene data in a UBO, in the near future we will use a UBO shared with other shaders + ScreenSpaceReflectionSceneData scene_data; + + if (ssr.ubo.is_null()) { + ssr.ubo = RD::get_singleton()->uniform_buffer_create(sizeof(ScreenSpaceReflectionSceneData)); + } + + for (uint32_t v = 0; v < p_view_count; v++) { + store_camera(p_projections[v], scene_data.projection[v]); + store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]); + scene_data.eye_offset[v][0] = p_eye_offsets[v].x; + scene_data.eye_offset[v][1] = p_eye_offsets[v].y; + scene_data.eye_offset[v][2] = p_eye_offsets[v].z; + scene_data.eye_offset[v][3] = 0.0; + } + + RD::get_singleton()->buffer_update(ssr.ubo, 0, sizeof(ScreenSpaceReflectionSceneData), &scene_data, RD::BARRIER_MASK_COMPUTE); + } + + uint32_t pipeline_specialization = 0; + if (p_view_count > 1) { + pipeline_specialization |= SSR_MULTIVIEW; + } + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + + for (uint32_t v = 0; v < p_view_count; v++) { + RD::get_singleton()->draw_command_begin_label(String("SSR View ") + itos(v)); + + { //scale color and depth to half + RD::get_singleton()->draw_command_begin_label("SSR Scale"); + + ScreenSpaceReflectionScalePushConstant push_constant; + push_constant.view_index = v; + push_constant.camera_z_far = p_projections[v].get_z_far(); + push_constant.camera_z_near = p_projections[v].get_z_near(); + push_constant.orthogonal = p_projections[v].is_orthogonal(); + push_constant.filter = false; //enabling causes arctifacts + push_constant.screen_size[0] = p_screen_size.x; + push_constant.screen_size[1] = p_screen_size.y; + + RID shader = ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_scale.pipelines[pipeline_specialization]); + + RD::Uniform u_diffuse(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_diffuse_slices[v] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_diffuse), 0); + + RD::Uniform u_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_depth_slices[v] })); + RD::Uniform u_normal_roughness(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, Vector<RID>({ default_sampler, p_normal_roughness_slices[v] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_depth, u_normal_roughness), 1); + + RD::Uniform u_output_blur(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_output_blur), 2); + + RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.depth_scaled })); + RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.normal_scaled })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth, u_scale_normal), 3); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionScalePushConstant)); + 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); + + RD::get_singleton()->draw_command_end_label(); + } + + { + RD::get_singleton()->draw_command_begin_label("SSR main"); + + ScreenSpaceReflectionPushConstant push_constant; + push_constant.view_index = v; + push_constant.camera_z_far = p_projections[v].get_z_far(); + push_constant.camera_z_near = p_projections[v].get_z_near(); + push_constant.orthogonal = p_projections[v].is_orthogonal(); + push_constant.screen_size[0] = p_screen_size.x; + push_constant.screen_size[1] = p_screen_size.y; + push_constant.curve_fade_in = p_fade_in; + push_constant.distance_fade = p_fade_out; + push_constant.num_steps = p_max_steps; + push_constant.depth_tolerance = p_tolerance; + push_constant.use_half_res = true; + push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].matrix[0][0]); + push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].matrix[1][1]); + push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0]; + push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1]; + push_constant.metallic_mask[0] = CLAMP(p_metallic_mask.r * 255.0, 0, 255); + push_constant.metallic_mask[1] = CLAMP(p_metallic_mask.g * 255.0, 0, 255); + push_constant.metallic_mask[2] = CLAMP(p_metallic_mask.b * 255.0, 0, 255); + push_constant.metallic_mask[3] = CLAMP(p_metallic_mask.a * 255.0, 0, 255); + + ScreenSpaceReflectionMode mode = (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL; + RID shader = ssr.shader.version_get_shader(ssr.shader_version, mode); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[pipeline_specialization][mode]); + + RD::Uniform u_scene_data(RD::UNIFORM_TYPE_UNIFORM_BUFFER, 0, ssr.ubo); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4); + + RD::Uniform u_output_blur(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] })); + RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.depth_scaled })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_output_blur, u_scale_depth), 0); + + if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) { + RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate })); + RD::Uniform u_blur_radius(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[0] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_intermediate, u_blur_radius), 1); + } else { + RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_intermediate), 1); + } + + RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.normal_scaled })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_scale_normal), 2); + + RD::Uniform u_metallic(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_metallic_slices[v] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_metallic), 3); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); + + RD::get_singleton()->draw_command_end_label(); + } + + if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) { + RD::get_singleton()->draw_command_begin_label("SSR filter"); + //blur + + RD::get_singleton()->compute_list_add_barrier(compute_list); + + ScreenSpaceReflectionFilterPushConstant push_constant; + push_constant.view_index = v; + push_constant.orthogonal = p_projections[v].is_orthogonal(); + push_constant.edge_tolerance = Math::sin(Math::deg2rad(15.0)); + push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_projections[v].matrix[0][0]); + push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_projections[v].matrix[1][1]); + push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0]; + push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1]; + push_constant.vertical = 0; + if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_LOW) { + push_constant.steps = p_max_steps / 3; + push_constant.increment = 3; + } else if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_MEDIUM) { + push_constant.steps = p_max_steps / 2; + push_constant.increment = 2; + } else { + push_constant.steps = p_max_steps; + push_constant.increment = 1; + } + + push_constant.screen_size[0] = p_screen_size.width; + push_constant.screen_size[1] = p_screen_size.height; + + // Horizontal pass + + SSRReflectionMode mode = SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL; + + RID shader = ssr_filter.shader.version_get_shader(ssr_filter.shader_version, mode); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[pipeline_specialization][mode]); + + RD::Uniform u_scene_data(RD::UNIFORM_TYPE_UNIFORM_BUFFER, 0, ssr.ubo); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4); + + RD::Uniform u_intermediate(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.intermediate })); + RD::Uniform u_blur_radius(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[0] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_intermediate, u_blur_radius), 0); + + RD::Uniform u_scale_normal(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.normal_scaled })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_scale_normal), 1); + + RD::Uniform u_output_blur(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.output_slices[v] })); + RD::Uniform u_blur_radius2(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_ssr_buffers.blur_radius[1] })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_output_blur, u_blur_radius2), 2); + + RD::Uniform u_scale_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_ssr_buffers.depth_scaled })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth), 3); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); + 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); + + // Vertical pass + + mode = SCREEN_SPACE_REFLECTION_FILTER_VERTICAL; + shader = ssr_filter.shader.version_get_shader(ssr_filter.shader_version, mode); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[pipeline_specialization][mode]); + + push_constant.vertical = 1; + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_output_blur, u_blur_radius2), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_scale_normal), 1); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_intermediate), 2); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_scale_depth), 3); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 4, u_scene_data), 4); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); + + if (v != p_view_count - 1) { + RD::get_singleton()->compute_list_add_barrier(compute_list); + } + + RD::get_singleton()->draw_command_end_label(); + } + + RD::get_singleton()->draw_command_end_label(); + } + + RD::get_singleton()->compute_list_end(); +} + +void SSEffects::ssr_free(SSRRenderBuffers &p_ssr_buffers) { + for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) { + p_ssr_buffers.output_slices[v] = RID(); + } + + if (p_ssr_buffers.output.is_valid()) { + RD::get_singleton()->free(p_ssr_buffers.output); + p_ssr_buffers.output = RID(); + } + + if (p_ssr_buffers.intermediate.is_valid()) { + RD::get_singleton()->free(p_ssr_buffers.intermediate); + p_ssr_buffers.intermediate = RID(); + } + + if (p_ssr_buffers.blur_radius[0].is_valid()) { + RD::get_singleton()->free(p_ssr_buffers.blur_radius[0]); + RD::get_singleton()->free(p_ssr_buffers.blur_radius[1]); + p_ssr_buffers.blur_radius[0] = RID(); + p_ssr_buffers.blur_radius[1] = RID(); + } + + if (p_ssr_buffers.depth_scaled.is_valid()) { + RD::get_singleton()->free(p_ssr_buffers.depth_scaled); + p_ssr_buffers.depth_scaled = RID(); + RD::get_singleton()->free(p_ssr_buffers.normal_scaled); + p_ssr_buffers.normal_scaled = RID(); + } +} diff --git a/servers/rendering/renderer_rd/effects/ss_effects.h b/servers/rendering/renderer_rd/effects/ss_effects.h new file mode 100644 index 0000000000..c31271ffd2 --- /dev/null +++ b/servers/rendering/renderer_rd/effects/ss_effects.h @@ -0,0 +1,508 @@ +/*************************************************************************/ +/* ss_effects.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 SS_EFFECTS_RD_H +#define SS_EFFECTS_RD_H + +#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ssao.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ssil.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl.gen.h" +#include "servers/rendering/renderer_scene_render.h" +#include "servers/rendering_server.h" + +namespace RendererRD { + +class SSEffects { +private: + static SSEffects *singleton; + +public: + static SSEffects *get_singleton() { return singleton; } + + SSEffects(); + ~SSEffects(); + + /* SS Downsampler */ + + void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const Projection &p_projection); + + /* SSIL */ + + struct SSILRenderBuffers { + bool half_size = false; + int buffer_width; + int buffer_height; + int half_buffer_width; + int half_buffer_height; + + RID ssil_final; + RID deinterleaved; + Vector<RID> deinterleaved_slices; + RID pong; + Vector<RID> pong_slices; + RID edges; + Vector<RID> edges_slices; + RID importance_map[2]; + RID depth_texture_view; + + RID last_frame; + Vector<RID> last_frame_slices; + + RID gather_uniform_set; + RID importance_map_uniform_set; + RID projection_uniform_set; + }; + + struct SSILSettings { + float radius = 1.0; + float intensity = 2.0; + float sharpness = 0.98; + float normal_rejection = 1.0; + + RS::EnvironmentSSILQuality quality = RS::ENV_SSIL_QUALITY_MEDIUM; + bool half_size = true; + float adaptive_target = 0.5; + int blur_passes = 4; + float fadeout_from = 50.0; + float fadeout_to = 300.0; + + Size2i full_screen_size = Size2i(); + }; + + void ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth); + void screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings); + void ssil_free(SSILRenderBuffers &p_ssil_buffers); + + /* SSAO */ + + struct SSAORenderBuffers { + bool half_size = false; + int buffer_width; + int buffer_height; + int half_buffer_width; + int half_buffer_height; + + RID ao_deinterleaved; + Vector<RID> ao_deinterleaved_slices; + RID ao_pong; + Vector<RID> ao_pong_slices; + RID ao_final; + RID importance_map[2]; + RID depth_texture_view; + + RID gather_uniform_set; + RID importance_map_uniform_set; + }; + + struct SSAOSettings { + float radius = 1.0; + float intensity = 2.0; + float power = 1.5; + float detail = 0.5; + float horizon = 0.06; + float sharpness = 0.98; + + RS::EnvironmentSSAOQuality quality = RS::ENV_SSAO_QUALITY_MEDIUM; + bool half_size = false; + float adaptive_target = 0.5; + int blur_passes = 2; + float fadeout_from = 50.0; + float fadeout_to = 300.0; + + Size2i full_screen_size = Size2i(); + }; + + void ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth); + void generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings); + void ssao_free(SSAORenderBuffers &p_ssao_buffers); + + /* Screen Space Reflection */ + + struct SSRRenderBuffers { + RID normal_scaled; + RID depth_scaled; + RID blur_radius[2]; + RID intermediate; + RID output; + RID output_slices[RendererSceneRender::MAX_RENDER_VIEWS]; + }; + + void ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const Size2i &p_screen_size, const uint32_t p_view_count); + void screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, const RID *p_metallic_slices, const Color &p_metallic_mask, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets); + void ssr_free(SSRRenderBuffers &p_ssr_buffers); + +private: + /* SS Downsampler */ + + struct SSEffectsDownsamplePushConstant { + float pixel_size[2]; + float z_far; + float z_near; + uint32_t orthogonal; + float radius_sq; + uint32_t pad[2]; + }; + + enum SSEffectsMode { + SS_EFFECTS_DOWNSAMPLE, + SS_EFFECTS_DOWNSAMPLE_HALF_RES, + SS_EFFECTS_DOWNSAMPLE_MIPMAP, + SS_EFFECTS_DOWNSAMPLE_MIPMAP_HALF_RES, + SS_EFFECTS_DOWNSAMPLE_HALF, + SS_EFFECTS_DOWNSAMPLE_HALF_RES_HALF, + SS_EFFECTS_DOWNSAMPLE_FULL_MIPS, + SS_EFFECTS_MAX + }; + + struct SSEffectsGatherConstants { + float rotation_matrices[80]; //5 vec4s * 4 + }; + + struct SSEffectsShader { + SSEffectsDownsamplePushConstant downsample_push_constant; + SsEffectsDownsampleShaderRD downsample_shader; + RID downsample_shader_version; + RID downsample_uniform_set; + bool used_half_size_last_frame = false; + bool used_mips_last_frame = false; + bool used_full_mips_last_frame = false; + + RID gather_constants_buffer; + + RID mirror_sampler; + + RID pipelines[SS_EFFECTS_MAX]; + } ss_effects; + + /* SSIL */ + + enum SSILMode { + SSIL_GATHER, + SSIL_GATHER_BASE, + SSIL_GATHER_ADAPTIVE, + SSIL_GENERATE_IMPORTANCE_MAP, + SSIL_PROCESS_IMPORTANCE_MAPA, + SSIL_PROCESS_IMPORTANCE_MAPB, + SSIL_BLUR_PASS, + SSIL_BLUR_PASS_SMART, + SSIL_BLUR_PASS_WIDE, + SSIL_INTERLEAVE, + SSIL_INTERLEAVE_SMART, + SSIL_INTERLEAVE_HALF, + SSIL_MAX + }; + + struct SSILGatherPushConstant { + int32_t screen_size[2]; + int pass; + int quality; + + float half_screen_pixel_size[2]; + float half_screen_pixel_size_x025[2]; + + float NDC_to_view_mul[2]; + float NDC_to_view_add[2]; + + float pad2[2]; + float z_near; + float z_far; + + float radius; + float intensity; + int size_multiplier; + int pad; + + float fade_out_mul; + float fade_out_add; + float normal_rejection_amount; + float inv_radius_near_limit; + + uint32_t is_orthogonal; + float neg_inv_radius; + float load_counter_avg_div; + float adaptive_sample_limit; + + int32_t pass_coord_offset[2]; + float pass_uv_offset[2]; + }; + + struct SSILImportanceMapPushConstant { + float half_screen_pixel_size[2]; + float intensity; + float pad; + }; + + struct SSILBlurPushConstant { + float edge_sharpness; + float pad; + float half_screen_pixel_size[2]; + }; + + struct SSILInterleavePushConstant { + float inv_sharpness; + uint32_t size_modifier; + float pixel_size[2]; + }; + + struct SSILProjectionUniforms { + float inv_last_frame_projection_matrix[16]; + }; + + struct SSIL { + SSILGatherPushConstant gather_push_constant; + SsilShaderRD gather_shader; + RID gather_shader_version; + RID projection_uniform_buffer; + + SSILImportanceMapPushConstant importance_map_push_constant; + SsilImportanceMapShaderRD importance_map_shader; + RID importance_map_shader_version; + RID importance_map_load_counter; + RID counter_uniform_set; + + SSILBlurPushConstant blur_push_constant; + SsilBlurShaderRD blur_shader; + RID blur_shader_version; + + SSILInterleavePushConstant interleave_push_constant; + SsilInterleaveShaderRD interleave_shader; + RID interleave_shader_version; + + RID pipelines[SSIL_MAX]; + } ssil; + + void gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set); + + /* SSAO */ + + enum SSAOMode { + SSAO_GATHER, + SSAO_GATHER_BASE, + SSAO_GATHER_ADAPTIVE, + SSAO_GENERATE_IMPORTANCE_MAP, + SSAO_PROCESS_IMPORTANCE_MAPA, + SSAO_PROCESS_IMPORTANCE_MAPB, + SSAO_BLUR_PASS, + SSAO_BLUR_PASS_SMART, + SSAO_BLUR_PASS_WIDE, + SSAO_INTERLEAVE, + SSAO_INTERLEAVE_SMART, + SSAO_INTERLEAVE_HALF, + SSAO_MAX + }; + + struct SSAOGatherPushConstant { + int32_t screen_size[2]; + int pass; + int quality; + + float half_screen_pixel_size[2]; + int size_multiplier; + float detail_intensity; + + float NDC_to_view_mul[2]; + float NDC_to_view_add[2]; + + float pad[2]; + float half_screen_pixel_size_x025[2]; + + float radius; + float intensity; + float shadow_power; + float shadow_clamp; + + float fade_out_mul; + float fade_out_add; + float horizon_angle_threshold; + float inv_radius_near_limit; + + uint32_t is_orthogonal; + float neg_inv_radius; + float load_counter_avg_div; + float adaptive_sample_limit; + + int32_t pass_coord_offset[2]; + float pass_uv_offset[2]; + }; + + struct SSAOImportanceMapPushConstant { + float half_screen_pixel_size[2]; + float intensity; + float power; + }; + + struct SSAOBlurPushConstant { + float edge_sharpness; + float pad; + float half_screen_pixel_size[2]; + }; + + struct SSAOInterleavePushConstant { + float inv_sharpness; + uint32_t size_modifier; + float pixel_size[2]; + }; + + struct SSAO { + SSAOGatherPushConstant gather_push_constant; + SsaoShaderRD gather_shader; + RID gather_shader_version; + + SSAOImportanceMapPushConstant importance_map_push_constant; + SsaoImportanceMapShaderRD importance_map_shader; + RID importance_map_shader_version; + RID importance_map_load_counter; + RID counter_uniform_set; + + SSAOBlurPushConstant blur_push_constant; + SsaoBlurShaderRD blur_shader; + RID blur_shader_version; + + SSAOInterleavePushConstant interleave_push_constant; + SsaoInterleaveShaderRD interleave_shader; + RID interleave_shader_version; + + RID pipelines[SSAO_MAX]; + } ssao; + + void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set); + + /* Screen Space Reflection */ + + enum SSRShaderSpecializations { + SSR_MULTIVIEW = 1 << 0, + SSR_VARIATIONS = 2, + }; + + struct ScreenSpaceReflectionSceneData { + float projection[2][16]; + float inv_projection[2][16]; + float eye_offset[2][4]; + }; + + // SSR Scale + + struct ScreenSpaceReflectionScalePushConstant { + int32_t screen_size[2]; + float camera_z_near; + float camera_z_far; + + uint32_t orthogonal; + uint32_t filter; + uint32_t view_index; + uint32_t pad1; + }; + + struct ScreenSpaceReflectionScale { + ScreenSpaceReflectionScaleShaderRD shader; + RID shader_version; + RID pipelines[SSR_VARIATIONS]; + } ssr_scale; + + // SSR main + + enum ScreenSpaceReflectionMode { + SCREEN_SPACE_REFLECTION_NORMAL, + SCREEN_SPACE_REFLECTION_ROUGH, + SCREEN_SPACE_REFLECTION_MAX, + }; + + struct ScreenSpaceReflectionPushConstant { + float proj_info[4]; // 16 - 16 + + int32_t screen_size[2]; // 8 - 24 + float camera_z_near; // 4 - 28 + float camera_z_far; // 4 - 32 + + int32_t num_steps; // 4 - 36 + float depth_tolerance; // 4 - 40 + float distance_fade; // 4 - 44 + float curve_fade_in; // 4 - 48 + + uint32_t orthogonal; // 4 - 52 + float filter_mipmap_levels; // 4 - 56 + uint32_t use_half_res; // 4 - 60 + uint8_t metallic_mask[4]; // 4 - 64 + + uint32_t view_index; // 4 - 68 + uint32_t pad[3]; // 12 - 80 + + // float projection[16]; // this is in our ScreenSpaceReflectionSceneData now + }; + + struct ScreenSpaceReflection { + ScreenSpaceReflectionShaderRD shader; + RID shader_version; + RID pipelines[SSR_VARIATIONS][SCREEN_SPACE_REFLECTION_MAX]; + + RID ubo; + } ssr; + + // SSR Filter + + struct ScreenSpaceReflectionFilterPushConstant { + float proj_info[4]; // 16 - 16 + + uint32_t orthogonal; // 4 - 20 + float edge_tolerance; // 4 - 24 + int32_t increment; // 4 - 28 + uint32_t view_index; // 4 - 32 + + int32_t screen_size[2]; // 8 - 40 + uint32_t vertical; // 4 - 44 + uint32_t steps; // 4 - 48 + }; + + enum SSRReflectionMode { + SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL, + SCREEN_SPACE_REFLECTION_FILTER_VERTICAL, + SCREEN_SPACE_REFLECTION_FILTER_MAX, + }; + + struct ScreenSpaceReflectionFilter { + ScreenSpaceReflectionFilterShaderRD shader; + RID shader_version; + RID pipelines[SSR_VARIATIONS][SCREEN_SPACE_REFLECTION_FILTER_MAX]; + } ssr_filter; +}; + +} // namespace RendererRD + +#endif // SS_EFFECTS_RD_H diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.h b/servers/rendering/renderer_rd/effects/tone_mapper.h index a90849dbeb..05db4a0cbe 100644 --- a/servers/rendering/renderer_rd/effects/tone_mapper.h +++ b/servers/rendering/renderer_rd/effects/tone_mapper.h @@ -149,4 +149,4 @@ public: } // namespace RendererRD -#endif // !TONE_MAPPER_RD_H +#endif // TONE_MAPPER_RD_H diff --git a/servers/rendering/renderer_rd/effects/vrs.cpp b/servers/rendering/renderer_rd/effects/vrs.cpp index 505a35a269..fa0b99fef9 100644 --- a/servers/rendering/renderer_rd/effects/vrs.cpp +++ b/servers/rendering/renderer_rd/effects/vrs.cpp @@ -95,7 +95,7 @@ void VRS::create_vrs_texture(const int p_base_width, const int p_base_height, co // TODO find a way to skip this if VRS is not supported, but we don't have access to VulkanContext here, even though we're in vulkan.. hmmm // TODO we should find some way to store this properly, we're assuming 16x16 as this seems to be the standard but in our vrs_capacities we - // obtain a minimum and maximum size, and we should choose something within this range and then make sure that is consistantly set when creating + // obtain a minimum and maximum size, and we should choose something within this range and then make sure that is consistently set when creating // our frame buffer. Also it is important that we make the resulting size we calculate down below available to the end user so they know the size // of the VRS buffer to supply. Size2i texel_size = Size2i(16, 16); diff --git a/servers/rendering/renderer_rd/effects/vrs.h b/servers/rendering/renderer_rd/effects/vrs.h index 0f2bdd31b6..dd15df615e 100644 --- a/servers/rendering/renderer_rd/effects/vrs.h +++ b/servers/rendering/renderer_rd/effects/vrs.h @@ -72,4 +72,4 @@ public: } // namespace RendererRD -#endif // !VRS_RD_H +#endif // VRS_RD_H diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index f731a0007a..8d59b24f3f 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -41,14 +41,6 @@ bool EffectsRD::get_prefer_raster_effects() { return prefer_raster_effects; } -static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - p_array[i * 4 + j] = p_mtx.matrix[i][j]; - } - } -} - RID EffectsRD::_get_uniform_set_from_image(RID p_image) { if (image_to_uniform_set_cache.has(p_image)) { RID uniform_set = image_to_uniform_set_cache[p_image]; @@ -86,7 +78,7 @@ RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) u.append_id(p_texture); uniforms.push_back(u); // anything with the same configuration (one texture in binding 0 for set 0), is good - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, specular_merge.shader.version_get_shader(specular_merge.shader_version, 0), 0); + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce_raster.shader.version_get_shader(luminance_reduce_raster.shader_version, 0), 0); texture_to_uniform_set_cache[p_texture] = uniform_set; @@ -116,105 +108,6 @@ RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_m return uniform_set; } -RID EffectsRD::_get_compute_uniform_set_from_texture_and_sampler(RID p_texture, RID p_sampler) { - TextureSamplerPair tsp; - tsp.texture = p_texture; - tsp.sampler = p_sampler; - - if (texture_sampler_to_compute_uniform_set_cache.has(tsp)) { - RID uniform_set = texture_sampler_to_compute_uniform_set_cache[tsp]; - if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { - return uniform_set; - } - } - - Vector<RD::Uniform> uniforms; - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 0; - u.append_id(p_sampler); - u.append_id(p_texture); - uniforms.push_back(u); - //any thing with the same configuration (one texture in binding 0 for set 0), is good - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.blur_shader.version_get_shader(ssao.blur_shader_version, 0), 0); - - texture_sampler_to_compute_uniform_set_cache[tsp] = uniform_set; - - return uniform_set; -} - -RID EffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) { - TexturePair tp; - tp.texture1 = p_texture1; - tp.texture2 = p_texture2; - - if (texture_pair_to_compute_uniform_set_cache.has(tp)) { - RID uniform_set = texture_pair_to_compute_uniform_set_cache[tp]; - if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { - return uniform_set; - } - } - - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 0; - u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.append_id(p_texture1); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 1; - u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.append_id(p_texture2); - uniforms.push_back(u); - } - //any thing with the same configuration (one texture in binding 0 for set 0), is good - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), 1); - - texture_pair_to_compute_uniform_set_cache[tp] = uniform_set; - - return uniform_set; -} - -RID EffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) { - TexturePair tp; - tp.texture1 = p_texture1; - tp.texture2 = p_texture2; - - if (image_pair_to_compute_uniform_set_cache.has(tp)) { - RID uniform_set = image_pair_to_compute_uniform_set_cache[tp]; - if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) { - return uniform_set; - } - } - - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 0; - u.append_id(p_texture1); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 1; - u.append_id(p_texture2); - uniforms.push_back(u); - } - //any thing with the same configuration (one texture in binding 0 for set 0), is good - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0), 3); - - image_pair_to_compute_uniform_set_cache[tp] = uniform_set; - - return uniform_set; -} - void EffectsRD::fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness) { memset(&FSR_upscale.push_constant, 0, sizeof(FSRUpscalePushConstant)); @@ -281,126 +174,7 @@ void EffectsRD::taa_resolve(RID p_frame, RID p_temp, RID p_depth, RID p_velocity 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(); - - { //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(); - ssr_scale.push_constant.orthogonal = p_camera.is_orthogonal(); - ssr_scale.push_constant.filter = false; //enabling causes arctifacts - ssr_scale.push_constant.screen_size[0] = p_screen_size.x; - ssr_scale.push_constant.screen_size[1] = p_screen_size.y; - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_scale.pipeline); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_diffuse), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_depth, p_normal_roughness), 1); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output_blur), 2); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_scale_depth, p_scale_normal), 3); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_scale.push_constant, sizeof(ScreenSpaceReflectionScalePushConstant)); - - 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); - } - - { - ssr.push_constant.camera_z_far = p_camera.get_z_far(); - ssr.push_constant.camera_z_near = p_camera.get_z_near(); - ssr.push_constant.orthogonal = p_camera.is_orthogonal(); - ssr.push_constant.screen_size[0] = p_screen_size.x; - ssr.push_constant.screen_size[1] = p_screen_size.y; - ssr.push_constant.curve_fade_in = p_fade_in; - ssr.push_constant.distance_fade = p_fade_out; - ssr.push_constant.num_steps = p_max_steps; - ssr.push_constant.depth_tolerance = p_tolerance; - ssr.push_constant.use_half_res = true; - ssr.push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_camera.matrix[0][0]); - ssr.push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_camera.matrix[1][1]); - ssr.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0]; - ssr.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1]; - ssr.push_constant.metallic_mask[0] = CLAMP(p_metallic_mask.r * 255.0, 0, 255); - ssr.push_constant.metallic_mask[1] = CLAMP(p_metallic_mask.g * 255.0, 0, 255); - ssr.push_constant.metallic_mask[2] = CLAMP(p_metallic_mask.b * 255.0, 0, 255); - ssr.push_constant.metallic_mask[3] = CLAMP(p_metallic_mask.a * 255.0, 0, 255); - store_camera(p_camera, ssr.push_constant.projection); - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[(p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL]); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr.push_constant, sizeof(ScreenSpaceReflectionPushConstant)); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_scale_depth), 0); - - if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 1); - } else { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 1); - } - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_metallic), 3); - 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_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); - } - - if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) { - //blur - - RD::get_singleton()->compute_list_add_barrier(compute_list); - - ssr_filter.push_constant.orthogonal = p_camera.is_orthogonal(); - ssr_filter.push_constant.edge_tolerance = Math::sin(Math::deg2rad(15.0)); - ssr_filter.push_constant.proj_info[0] = -2.0f / (p_screen_size.width * p_camera.matrix[0][0]); - ssr_filter.push_constant.proj_info[1] = -2.0f / (p_screen_size.height * p_camera.matrix[1][1]); - ssr_filter.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0]; - ssr_filter.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1]; - ssr_filter.push_constant.vertical = 0; - if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_LOW) { - ssr_filter.push_constant.steps = p_max_steps / 3; - ssr_filter.push_constant.increment = 3; - } else if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_MEDIUM) { - ssr_filter.push_constant.steps = p_max_steps / 2; - ssr_filter.push_constant.increment = 2; - } else { - ssr_filter.push_constant.steps = p_max_steps; - ssr_filter.push_constant.increment = 1; - } - - ssr_filter.push_constant.screen_size[0] = p_screen_size.width; - ssr_filter.push_constant.screen_size[1] = p_screen_size.height; - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 1); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_blur_radius2), 2); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_depth), 3); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); - - 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); - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr_filter.pipelines[SCREEN_SPACE_REFLECTION_FILTER_VERTICAL]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_blur_radius2), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 1); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 2); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_depth), 3); - - ssr_filter.push_constant.vertical = 1; - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr_filter.push_constant, sizeof(ScreenSpaceReflectionFilterPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); - } - - RD::get_singleton()->compute_list_end(); -} - -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) { +void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const Projection &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(); Plane p = p_camera.xform4(Plane(1, 0, -1, 1)); @@ -443,36 +217,6 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept } } -void EffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) { - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, Vector<Color>()); - - if (p_reflection.is_valid()) { - if (p_base.is_valid()) { - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2); - } else { - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADDITIVE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - } - - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_specular), 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_reflection), 1); - - } else { - if (p_base.is_valid()) { - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2); - } else { - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADDITIVE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - } - - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_specular), 0); - } - - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); -} - void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) { ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of luminance reduction with the mobile renderer."); @@ -546,674 +290,6 @@ void EffectsRD::luminance_reduction_raster(RID p_source_texture, const Size2i p_ } } -void EffectsRD::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection) { - // Downsample and deinterleave the depth buffer for SSAO and SSIL - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - - int downsample_pipeline = SS_EFFECTS_DOWNSAMPLE; - bool use_mips = p_ssao_quality > RS::ENV_SSAO_QUALITY_MEDIUM || p_ssil_quality > RS::ENV_SSIL_QUALITY_MEDIUM; - - if (p_ssao_quality == RS::ENV_SSAO_QUALITY_VERY_LOW && p_ssil_quality == RS::ENV_SSIL_QUALITY_VERY_LOW) { - downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_HALF; - } else if (use_mips) { - downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_MIPMAP; - } - - bool use_half_size = false; - bool use_full_mips = false; - - if (p_ssao_half_size && p_ssil_half_size) { - downsample_pipeline++; - use_half_size = true; - } else if (p_ssao_half_size != p_ssil_half_size) { - if (use_mips) { - downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_FULL_MIPS; - use_full_mips = true; - } else { - // Only need the first two mipmaps, but the cost to generate the next two is trivial - // TODO investigate the benefit of a shader version to generate only 2 mips - downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_MIPMAP; - use_mips = true; - } - } - - int depth_index = use_half_size ? 1 : 0; - - RD::get_singleton()->draw_command_begin_label("Downsample Depth"); - if (p_invalidate_uniform_set || use_full_mips != ss_effects.used_full_mips_last_frame || use_half_size != ss_effects.used_half_size_last_frame || use_mips != ss_effects.used_mips_last_frame) { - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 0; - u.append_id(p_depth_mipmaps[depth_index + 1]); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 1; - u.append_id(p_depth_mipmaps[depth_index + 2]); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 2; - u.append_id(p_depth_mipmaps[depth_index + 3]); - uniforms.push_back(u); - } - if (use_full_mips) { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 3; - u.append_id(p_depth_mipmaps[4]); - uniforms.push_back(u); - } - ss_effects.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, use_full_mips ? 6 : 2), 2); - } - - float depth_linearize_mul = -p_projection.matrix[3][2]; - float depth_linearize_add = p_projection.matrix[2][2]; - if (depth_linearize_mul * depth_linearize_add < 0) { - depth_linearize_add = -depth_linearize_add; - } - - ss_effects.downsample_push_constant.orthogonal = p_projection.is_orthogonal(); - ss_effects.downsample_push_constant.z_near = depth_linearize_mul; - ss_effects.downsample_push_constant.z_far = depth_linearize_add; - if (ss_effects.downsample_push_constant.orthogonal) { - ss_effects.downsample_push_constant.z_near = p_projection.get_z_near(); - ss_effects.downsample_push_constant.z_far = p_projection.get_z_far(); - } - ss_effects.downsample_push_constant.pixel_size[0] = 1.0 / p_full_screen_size.x; - ss_effects.downsample_push_constant.pixel_size[1] = 1.0 / p_full_screen_size.y; - ss_effects.downsample_push_constant.radius_sq = 1.0; - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ss_effects.pipelines[downsample_pipeline]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_depth_mipmaps[depth_index + 0]), 1); - if (use_mips) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ss_effects.downsample_uniform_set, 2); - } - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ss_effects.downsample_push_constant, sizeof(SSEffectsDownsamplePushConstant)); - - Size2i size(MAX(1, p_full_screen_size.x >> (use_half_size ? 2 : 1)), MAX(1, p_full_screen_size.y >> (use_half_size ? 2 : 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(); - - RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE); - - ss_effects.used_full_mips_last_frame = use_full_mips; - ss_effects.used_half_size_last_frame = use_half_size; -} - -void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) { - RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0); - if ((p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) { - RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1); - } - - for (int i = 0; i < 4; i++) { - if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) { - continue; - } - - ssao.gather_push_constant.pass_coord_offset[0] = i % 2; - ssao.gather_push_constant.pass_coord_offset[1] = i / 2; - ssao.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x; - ssao.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y; - ssao.gather_push_constant.pass = i; - 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)); - - 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_threads(p_compute_list, size.x, size.y, 1); - } - RD::get_singleton()->compute_list_add_barrier(p_compute_list); -} - -void EffectsRD::generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set) { - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - memset(&ssao.gather_push_constant, 0, sizeof(SSAOGatherPushConstant)); - /* FIRST PASS */ - - RD::get_singleton()->draw_command_begin_label("Process Screen Space Ambient Occlusion"); - /* SECOND PASS */ - // Sample SSAO - { - RD::get_singleton()->draw_command_begin_label("Gather Samples"); - ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x; - ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y; - - ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; - ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; - float tan_half_fov_x = 1.0 / p_projection.matrix[0][0]; - float tan_half_fov_y = 1.0 / p_projection.matrix[1][1]; - ssao.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0; - ssao.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0; - ssao.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0; - ssao.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y; - ssao.gather_push_constant.is_orthogonal = p_projection.is_orthogonal(); - - ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.25; - ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.25; - - ssao.gather_push_constant.radius = p_settings.radius; - float radius_near_limit = (p_settings.radius * 1.2f); - if (p_settings.quality <= RS::ENV_SSAO_QUALITY_LOW) { - radius_near_limit *= 1.50f; - - if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) { - ssao.gather_push_constant.radius *= 0.8f; - } - } - radius_near_limit /= tan_half_fov_y; - ssao.gather_push_constant.intensity = p_settings.intensity; - ssao.gather_push_constant.shadow_power = p_settings.power; - ssao.gather_push_constant.shadow_clamp = 0.98; - ssao.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from); - ssao.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0; - ssao.gather_push_constant.horizon_angle_threshold = p_settings.horizon; - ssao.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit; - ssao.gather_push_constant.neg_inv_radius = -1.0 / ssao.gather_push_constant.radius; - - ssao.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_screen_size.x) * (p_settings.quarter_screen_size.y) * 255); - ssao.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target; - - ssao.gather_push_constant.detail_intensity = p_settings.detail; - ssao.gather_push_constant.quality = MAX(0, p_settings.quality - 1); - ssao.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1; - - if (p_invalidate_uniform_sets) { - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 0; - u.append_id(default_sampler); - u.append_id(p_depth_mipmaps_texture); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 1; - u.append_id(p_normal_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 2; - u.append_id(ss_effects.gather_constants_buffer); - uniforms.push_back(u); - } - r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0), 0); - } - - if (p_invalidate_uniform_sets) { - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 0; - u.append_id(p_ao_pong); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 1; - u.append_id(default_sampler); - u.append_id(p_importance_map); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 2; - u.append_id(ssao.importance_map_load_counter); - uniforms.push_back(u); - } - r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1); - } - - if (p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) { - RD::get_singleton()->draw_command_begin_label("Generate Importance Map"); - ssao.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; - ssao.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; - ssao.importance_map_push_constant.intensity = p_settings.intensity; - ssao.importance_map_push_constant.power = p_settings.power; - //base pass - 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, r_gather_uniform_set, RID()); - //generate importance map - - 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_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_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]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map_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_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_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]); - RD::get_singleton()->draw_command_end_label(); // Importance Map - } else { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]); - } - - gather_ssao(compute_list, p_ao_slices, p_settings, false, r_gather_uniform_set, r_importance_map_uniform_set); - RD::get_singleton()->draw_command_end_label(); // Gather SSAO - } - - // /* THIRD PASS */ - // // Blur - // - { - RD::get_singleton()->draw_command_begin_label("Edge Aware Blur"); - ssao.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness; - ssao.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; - ssao.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; - - int blur_passes = p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW ? p_settings.blur_passes : 1; - - for (int pass = 0; pass < blur_passes; pass++) { - int blur_pipeline = SSAO_BLUR_PASS; - if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) { - blur_pipeline = SSAO_BLUR_PASS_SMART; - if (pass < blur_passes - 2) { - blur_pipeline = SSAO_BLUR_PASS_WIDE; - } else { - blur_pipeline = SSAO_BLUR_PASS_SMART; - } - } - - for (int i = 0; i < 4; i++) { - if ((p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) { - continue; - } - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[blur_pipeline]); - if (pass % 2 == 0) { - if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_slices[i]), 0); - } else { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ao_slices[i], ss_effects.mirror_sampler), 0); - } - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao_pong_slices[i]), 1); - } else { - if (p_settings.quality == RS::ENV_SSAO_QUALITY_VERY_LOW) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong_slices[i]), 0); - } else { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ao_pong_slices[i], ss_effects.mirror_sampler), 0); - } - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 1); - } - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.blur_push_constant, sizeof(SSAOBlurPushConstant)); - - 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) { - RD::get_singleton()->compute_list_add_barrier(compute_list); - } - } - RD::get_singleton()->draw_command_end_label(); // Blur - } - - /* FOURTH PASS */ - // Interleave buffers - // back to full size - { - RD::get_singleton()->draw_command_begin_label("Interleave Buffers"); - ssao.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness; - ssao.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x; - ssao.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y; - ssao.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2); - - int interleave_pipeline = SSAO_INTERLEAVE_HALF; - if (p_settings.quality == RS::ENV_SSAO_QUALITY_LOW) { - interleave_pipeline = SSAO_INTERLEAVE; - } else if (p_settings.quality >= RS::ENV_SSAO_QUALITY_MEDIUM) { - interleave_pipeline = SSAO_INTERLEAVE_SMART; - } - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[interleave_pipeline]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_upscale_buffer), 0); - if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao), 1); - } else { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao_pong), 1); - } - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.interleave_push_constant, sizeof(SSAOInterleavePushConstant)); - - 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::BARRIER_MASK_NO_BARRIER); //wait for upcoming transfer - - int zero[1] = { 0 }; - RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier -} - -void EffectsRD::gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set) { - RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0); - if ((p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) && !p_adaptive_base_pass) { - RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1); - } - RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_projection_uniform_set, 3); - - for (int i = 0; i < 4; i++) { - if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) { - continue; - } - - ssil.gather_push_constant.pass_coord_offset[0] = i % 2; - ssil.gather_push_constant.pass_coord_offset[1] = i / 2; - ssil.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x; - ssil.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y; - ssil.gather_push_constant.pass = i; - RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, _get_compute_uniform_set_from_image_pair(p_ssil_slices[i], p_edges_slices[i]), 2); - RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssil.gather_push_constant, sizeof(SSILGatherPushConstant)); - - 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_threads(p_compute_list, size.x, size.y, 1); - } - RD::get_singleton()->compute_list_add_barrier(p_compute_list); -} - -void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ssil, const Vector<RID> p_ssil_slices, RID p_ssil_pong, const Vector<RID> p_ssil_pong_slices, RID p_importance_map, RID p_importance_map_pong, RID p_edges, const Vector<RID> p_edges_slices, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set, RID &r_projection_uniform_set) { - RD::get_singleton()->draw_command_begin_label("Process Screen Space Indirect Lighting"); - //Store projection info before starting the compute list - SSILProjectionUniforms projection_uniforms; - store_camera(p_last_projection, projection_uniforms.inv_last_frame_projection_matrix); - - RD::get_singleton()->buffer_update(ssil.projection_uniform_buffer, 0, sizeof(SSILProjectionUniforms), &projection_uniforms); - - memset(&ssil.gather_push_constant, 0, sizeof(SSILGatherPushConstant)); - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - { - RD::get_singleton()->draw_command_begin_label("Gather Samples"); - ssil.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x; - ssil.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y; - - ssil.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; - ssil.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; - float tan_half_fov_x = 1.0 / p_projection.matrix[0][0]; - float tan_half_fov_y = 1.0 / p_projection.matrix[1][1]; - ssil.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0; - ssil.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0; - ssil.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0; - ssil.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y; - ssil.gather_push_constant.z_near = p_projection.get_z_near(); - ssil.gather_push_constant.z_far = p_projection.get_z_far(); - ssil.gather_push_constant.is_orthogonal = p_projection.is_orthogonal(); - - ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.25; - ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.25; - - ssil.gather_push_constant.radius = p_settings.radius; - float radius_near_limit = (p_settings.radius * 1.2f); - if (p_settings.quality <= RS::ENV_SSIL_QUALITY_LOW) { - radius_near_limit *= 1.50f; - - if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) { - ssil.gather_push_constant.radius *= 0.8f; - } - } - radius_near_limit /= tan_half_fov_y; - ssil.gather_push_constant.intensity = p_settings.intensity * Math_PI; - ssil.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from); - ssil.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0; - ssil.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit; - ssil.gather_push_constant.neg_inv_radius = -1.0 / ssil.gather_push_constant.radius; - ssil.gather_push_constant.normal_rejection_amount = p_settings.normal_rejection; - - ssil.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_screen_size.x) * (p_settings.quarter_screen_size.y) * 255); - ssil.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target; - - ssil.gather_push_constant.quality = MAX(0, p_settings.quality - 1); - ssil.gather_push_constant.size_multiplier = p_settings.half_size ? 2 : 1; - - if (p_invalidate_uniform_sets) { - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 0; - u.append_id(default_mipmap_sampler); - u.append_id(p_diffuse); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 1; - u.append_id(ssil.projection_uniform_buffer); - uniforms.push_back(u); - } - r_projection_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 3); - } - - if (p_invalidate_uniform_sets) { - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 0; - u.append_id(default_sampler); - u.append_id(p_depth_mipmaps_texture); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 1; - u.append_id(p_normal_buffer); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 2; - u.append_id(ss_effects.gather_constants_buffer); - uniforms.push_back(u); - } - r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 0); - } - - if (p_invalidate_uniform_sets) { - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 0; - u.append_id(p_ssil_pong); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u.binding = 1; - u.append_id(default_sampler); - u.append_id(p_importance_map); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 2; - u.append_id(ssil.importance_map_load_counter); - uniforms.push_back(u); - } - r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 2), 1); - } - - if (p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) { - RD::get_singleton()->draw_command_begin_label("Generate Importance Map"); - ssil.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; - ssil.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; - ssil.importance_map_push_constant.intensity = p_settings.intensity * Math_PI; - //base pass - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_BASE]); - gather_ssil(compute_list, p_ssil_pong_slices, p_edges_slices, p_settings, true, r_gather_uniform_set, r_importance_map_uniform_set, r_projection_uniform_set); - //generate importance map - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GENERATE_IMPORTANCE_MAP]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_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, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant)); - 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, ssil.pipelines[SSIL_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, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant)); - 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, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPB]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_importance_map_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_bind_uniform_set(compute_list, ssil.counter_uniform_set, 2); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant)); - 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()->draw_command_end_label(); // Importance Map - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_ADAPTIVE]); - } else { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER]); - } - - gather_ssil(compute_list, p_ssil_slices, p_edges_slices, p_settings, false, r_gather_uniform_set, r_importance_map_uniform_set, r_projection_uniform_set); - RD::get_singleton()->draw_command_end_label(); //Gather - } - - { - RD::get_singleton()->draw_command_begin_label("Edge Aware Blur"); - ssil.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness; - ssil.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x; - ssil.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y; - - int blur_passes = p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW ? p_settings.blur_passes : 1; - - for (int pass = 0; pass < blur_passes; pass++) { - int blur_pipeline = SSIL_BLUR_PASS; - if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) { - blur_pipeline = SSIL_BLUR_PASS_SMART; - if (pass < blur_passes - 2) { - blur_pipeline = SSIL_BLUR_PASS_WIDE; - } - } - - for (int i = 0; i < 4; i++) { - if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) { - continue; - } - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[blur_pipeline]); - if (pass % 2 == 0) { - if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_slices[i]), 0); - } else { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ssil_slices[i], ss_effects.mirror_sampler), 0); - } - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ssil_pong_slices[i]), 1); - } else { - if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_pong_slices[i]), 0); - } else { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ssil_pong_slices[i], ss_effects.mirror_sampler), 0); - } - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ssil_slices[i]), 1); - } - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_edges_slices[i]), 2); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.blur_push_constant, sizeof(SSILBlurPushConstant)); - - int x_groups = (p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)); - int y_groups = (p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, x_groups, y_groups, 1); - if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) { - RD::get_singleton()->compute_list_add_barrier(compute_list); - } - } - } - - RD::get_singleton()->draw_command_end_label(); // Blur - } - - { - RD::get_singleton()->draw_command_begin_label("Interleave Buffers"); - ssil.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness; - ssil.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x; - ssil.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y; - ssil.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2); - - int interleave_pipeline = SSIL_INTERLEAVE_HALF; - if (p_settings.quality == RS::ENV_SSIL_QUALITY_LOW) { - interleave_pipeline = SSIL_INTERLEAVE; - } else if (p_settings.quality >= RS::ENV_SSIL_QUALITY_MEDIUM) { - interleave_pipeline = SSIL_INTERLEAVE_SMART; - } - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[interleave_pipeline]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_destination), 0); - - if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW && p_settings.blur_passes % 2 == 0) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil), 1); - } else { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_pong), 1); - } - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_edges), 2); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.interleave_push_constant, sizeof(SSILInterleavePushConstant)); - - 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(); // SSIL - - RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); - - int zero[1] = { 0 }; - RD::get_singleton()->buffer_update(ssil.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) { roughness_limiter.push_constant.screen_size[0] = p_size.x; roughness_limiter.push_constant.screen_size[1] = p_size.y; @@ -1304,7 +380,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { { Vector<String> FSR_upscale_modes; -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) +#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) // MoltenVK does not support some of the operations used by the normal mode of FSR. Fallback works just fine though. FSR_upscale_modes.push_back("\n#define MODE_FSR_UPSCALE_FALLBACK\n"); #else @@ -1358,154 +434,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { } if (!prefer_raster_effects) { - { - // Initialize depth buffer for screen space effects - Vector<String> downsampler_modes; - downsampler_modes.push_back("\n"); - downsampler_modes.push_back("\n#define USE_HALF_SIZE\n"); - downsampler_modes.push_back("\n#define GENERATE_MIPS\n"); - downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define USE_HALF_SIZE\n"); - downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n"); - downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n#define USE_HALF_SIZE\n"); - downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define GENERATE_FULL_MIPS"); - - ss_effects.downsample_shader.initialize(downsampler_modes); - - ss_effects.downsample_shader_version = ss_effects.downsample_shader.version_create(); - - for (int i = 0; i < SS_EFFECTS_MAX; i++) { - ss_effects.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, i)); - } - - ss_effects.gather_constants_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSEffectsGatherConstants)); - SSEffectsGatherConstants gather_constants; - - const int sub_pass_count = 5; - for (int pass = 0; pass < 4; pass++) { - for (int subPass = 0; subPass < sub_pass_count; subPass++) { - int a = pass; - int b = subPass; - - int spmap[5]{ 0, 1, 4, 3, 2 }; - b = spmap[subPass]; - - float ca, sa; - float angle0 = (float(a) + float(b) / float(sub_pass_count)) * Math_PI * 0.5f; - - ca = Math::cos(angle0); - sa = Math::sin(angle0); - - float scale = 1.0f + (a - 1.5f + (b - (sub_pass_count - 1.0f) * 0.5f) / float(sub_pass_count)) * 0.07f; - - gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 0] = scale * ca; - gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 1] = scale * -sa; - gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 2] = -scale * sa; - gather_constants.rotation_matrices[pass * 20 + subPass * 4 + 3] = -scale * ca; - } - } - - RD::get_singleton()->buffer_update(ss_effects.gather_constants_buffer, 0, sizeof(SSEffectsGatherConstants), &gather_constants); - } - - { - // Initialize ssao - - RD::SamplerState sampler; - sampler.mag_filter = RD::SAMPLER_FILTER_NEAREST; - sampler.min_filter = RD::SAMPLER_FILTER_NEAREST; - sampler.mip_filter = RD::SAMPLER_FILTER_NEAREST; - sampler.repeat_u = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; - sampler.repeat_v = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; - sampler.repeat_w = RD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT; - sampler.max_lod = 4; - - ss_effects.mirror_sampler = RD::get_singleton()->sampler_create(sampler); - - uint32_t pipeline = 0; - { - Vector<String> ssao_modes; - - ssao_modes.push_back("\n"); - ssao_modes.push_back("\n#define SSAO_BASE\n"); - ssao_modes.push_back("\n#define ADAPTIVE\n"); - - ssao.gather_shader.initialize(ssao_modes); - - ssao.gather_shader_version = ssao.gather_shader.version_create(); - - for (int i = 0; i <= SSAO_GATHER_ADAPTIVE; i++) { - ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.gather_shader.version_get_shader(ssao.gather_shader_version, i)); - pipeline++; - } - } - { - Vector<String> ssao_modes; - ssao_modes.push_back("\n#define GENERATE_MAP\n"); - ssao_modes.push_back("\n#define PROCESS_MAPA\n"); - ssao_modes.push_back("\n#define PROCESS_MAPB\n"); - - ssao.importance_map_shader.initialize(ssao_modes); - - ssao.importance_map_shader_version = ssao.importance_map_shader.version_create(); - - for (int i = SSAO_GENERATE_IMPORTANCE_MAP; i <= SSAO_PROCESS_IMPORTANCE_MAPB; i++) { - ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, i - SSAO_GENERATE_IMPORTANCE_MAP)); - - pipeline++; - } - ssao.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t)); - int zero[1] = { 0 }; - RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero); - RD::get_singleton()->set_resource_name(ssao.importance_map_load_counter, "Importance Map Load Counter"); - - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 0; - u.append_id(ssao.importance_map_load_counter); - uniforms.push_back(u); - } - ssao.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.importance_map_shader.version_get_shader(ssao.importance_map_shader_version, 2), 2); - RD::get_singleton()->set_resource_name(ssao.counter_uniform_set, "Load Counter Uniform Set"); - } - { - Vector<String> ssao_modes; - ssao_modes.push_back("\n#define MODE_NON_SMART\n"); - ssao_modes.push_back("\n#define MODE_SMART\n"); - ssao_modes.push_back("\n#define MODE_WIDE\n"); - - ssao.blur_shader.initialize(ssao_modes); - - ssao.blur_shader_version = ssao.blur_shader.version_create(); - - for (int i = SSAO_BLUR_PASS; i <= SSAO_BLUR_PASS_WIDE; i++) { - ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.blur_shader.version_get_shader(ssao.blur_shader_version, i - SSAO_BLUR_PASS)); - - pipeline++; - } - } - { - Vector<String> ssao_modes; - ssao_modes.push_back("\n#define MODE_NON_SMART\n"); - ssao_modes.push_back("\n#define MODE_SMART\n"); - ssao_modes.push_back("\n#define MODE_HALF\n"); - - ssao.interleave_shader.initialize(ssao_modes); - - ssao.interleave_shader_version = ssao.interleave_shader.version_create(); - for (int i = SSAO_INTERLEAVE; i <= SSAO_INTERLEAVE_HALF; i++) { - ssao.pipelines[pipeline] = RD::get_singleton()->compute_pipeline_create(ssao.interleave_shader.version_get_shader(ssao.interleave_shader_version, i - SSAO_INTERLEAVE)); - RD::get_singleton()->set_resource_name(ssao.pipelines[pipeline], "Interleave Pipeline " + itos(i)); - pipeline++; - } - } - - ERR_FAIL_COND(pipeline != SSAO_MAX); - } - } - - if (!prefer_raster_effects) { // Initialize roughness limiter Vector<String> shader_modes; shader_modes.push_back(""); @@ -1518,81 +446,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { } if (!prefer_raster_effects) { - Vector<String> specular_modes; - specular_modes.push_back("\n#define MODE_MERGE\n"); - specular_modes.push_back("\n#define MODE_MERGE\n#define MODE_SSR\n"); - specular_modes.push_back("\n"); - specular_modes.push_back("\n#define MODE_SSR\n"); - - specular_merge.shader.initialize(specular_modes); - - specular_merge.shader_version = specular_merge.shader.version_create(); - - //use additive - - RD::PipelineColorBlendState::Attachment ba; - ba.enable_blend = true; - ba.src_color_blend_factor = RD::BLEND_FACTOR_ONE; - ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE; - ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE; - ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE; - ba.color_blend_op = RD::BLEND_OP_ADD; - ba.alpha_blend_op = RD::BLEND_OP_ADD; - - RD::PipelineColorBlendState blend_additive; - blend_additive.attachments.push_back(ba); - - for (int i = 0; i < SPECULAR_MERGE_MAX; i++) { - RD::PipelineColorBlendState blend_state; - if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR) { - blend_state = blend_additive; - } else { - blend_state = RD::PipelineColorBlendState::create_disabled(); - } - specular_merge.pipelines[i].setup(specular_merge.shader.version_get_shader(specular_merge.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0); - } - } - - if (!prefer_raster_effects) { - { - Vector<String> ssr_modes; - ssr_modes.push_back("\n"); - ssr_modes.push_back("\n#define MODE_ROUGH\n"); - - ssr.shader.initialize(ssr_modes); - - ssr.shader_version = ssr.shader.version_create(); - - for (int i = 0; i < SCREEN_SPACE_REFLECTION_MAX; i++) { - ssr.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssr.shader.version_get_shader(ssr.shader_version, i)); - } - } - - { - Vector<String> ssr_filter_modes; - ssr_filter_modes.push_back("\n"); - ssr_filter_modes.push_back("\n#define VERTICAL_PASS\n"); - - ssr_filter.shader.initialize(ssr_filter_modes); - - ssr_filter.shader_version = ssr_filter.shader.version_create(); - - for (int i = 0; i < SCREEN_SPACE_REFLECTION_FILTER_MAX; i++) { - ssr_filter.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssr_filter.shader.version_get_shader(ssr_filter.shader_version, i)); - } - } - - { - Vector<String> ssr_scale_modes; - ssr_scale_modes.push_back("\n"); - - ssr_scale.shader.initialize(ssr_scale_modes); - - ssr_scale.shader_version = ssr_scale.shader.version_create(); - - ssr_scale.pipeline = RD::get_singleton()->compute_pipeline_create(ssr_scale.shader.version_get_shader(ssr_scale.shader_version, 0)); - } - { Vector<String> sss_modes; sss_modes.push_back("\n#define USE_11_SAMPLES\n"); @@ -1607,79 +460,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { sss.pipelines[i] = RD::get_singleton()->compute_pipeline_create(sss.shader.version_get_shader(sss.shader_version, i)); } } - - { - Vector<String> ssil_modes; - ssil_modes.push_back("\n"); - ssil_modes.push_back("\n#define SSIL_BASE\n"); - ssil_modes.push_back("\n#define ADAPTIVE\n"); - - ssil.gather_shader.initialize(ssil_modes); - - ssil.gather_shader_version = ssil.gather_shader.version_create(); - - for (int i = SSIL_GATHER; i <= SSIL_GATHER_ADAPTIVE; i++) { - ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.gather_shader.version_get_shader(ssil.gather_shader_version, i)); - } - ssil.projection_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSILProjectionUniforms)); - } - - { - Vector<String> ssil_modes; - ssil_modes.push_back("\n#define GENERATE_MAP\n"); - ssil_modes.push_back("\n#define PROCESS_MAPA\n"); - ssil_modes.push_back("\n#define PROCESS_MAPB\n"); - - ssil.importance_map_shader.initialize(ssil_modes); - - ssil.importance_map_shader_version = ssil.importance_map_shader.version_create(); - - for (int i = SSIL_GENERATE_IMPORTANCE_MAP; i <= SSIL_PROCESS_IMPORTANCE_MAPB; i++) { - ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, i - SSIL_GENERATE_IMPORTANCE_MAP)); - } - ssil.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t)); - int zero[1] = { 0 }; - RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero); - RD::get_singleton()->set_resource_name(ssil.importance_map_load_counter, "Importance Map Load Counter"); - - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 0; - u.append_id(ssil.importance_map_load_counter); - uniforms.push_back(u); - } - ssil.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 2), 2); - RD::get_singleton()->set_resource_name(ssil.counter_uniform_set, "Load Counter Uniform Set"); - } - { - Vector<String> ssil_modes; - ssil_modes.push_back("\n#define MODE_NON_SMART\n"); - ssil_modes.push_back("\n#define MODE_SMART\n"); - ssil_modes.push_back("\n#define MODE_WIDE\n"); - - ssil.blur_shader.initialize(ssil_modes); - - ssil.blur_shader_version = ssil.blur_shader.version_create(); - for (int i = SSIL_BLUR_PASS; i <= SSIL_BLUR_PASS_WIDE; i++) { - ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.blur_shader.version_get_shader(ssil.blur_shader_version, i - SSIL_BLUR_PASS)); - } - } - - { - Vector<String> ssil_modes; - ssil_modes.push_back("\n#define MODE_NON_SMART\n"); - ssil_modes.push_back("\n#define MODE_SMART\n"); - ssil_modes.push_back("\n#define MODE_HALF\n"); - - ssil.interleave_shader.initialize(ssil_modes); - - ssil.interleave_shader_version = ssil.interleave_shader.version_create(); - for (int i = SSIL_INTERLEAVE; i <= SSIL_INTERLEAVE_HALF; i++) { - ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, i - SSIL_INTERLEAVE)); - } - } } { @@ -1751,27 +531,8 @@ EffectsRD::~EffectsRD() { luminance_reduce.shader.version_free(luminance_reduce.shader_version); } if (!prefer_raster_effects) { - specular_merge.shader.version_free(specular_merge.shader_version); - ss_effects.downsample_shader.version_free(ss_effects.downsample_shader_version); - ssao.blur_shader.version_free(ssao.blur_shader_version); - ssao.gather_shader.version_free(ssao.gather_shader_version); - ssao.interleave_shader.version_free(ssao.interleave_shader_version); - ssao.importance_map_shader.version_free(ssao.importance_map_shader_version); - ssil.blur_shader.version_free(ssil.blur_shader_version); - ssil.gather_shader.version_free(ssil.gather_shader_version); - ssil.interleave_shader.version_free(ssil.interleave_shader_version); - ssil.importance_map_shader.version_free(ssil.importance_map_shader_version); roughness_limiter.shader.version_free(roughness_limiter.shader_version); - ssr.shader.version_free(ssr.shader_version); - ssr_filter.shader.version_free(ssr_filter.shader_version); - ssr_scale.shader.version_free(ssr_scale.shader_version); sss.shader.version_free(sss.shader_version); - - RD::get_singleton()->free(ss_effects.mirror_sampler); - RD::get_singleton()->free(ss_effects.gather_constants_buffer); - RD::get_singleton()->free(ssao.importance_map_load_counter); - RD::get_singleton()->free(ssil.importance_map_load_counter); - RD::get_singleton()->free(ssil.projection_uniform_buffer); } sort.shader.version_free(sort.shader_version); } diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 76627a8d7d..94cd26fae9 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -31,26 +31,13 @@ #ifndef EFFECTS_RD_H #define EFFECTS_RD_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/shaders/fsr_upscale.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h" -#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/sort.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ssao_blur.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ssao_interleave.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ssil.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ssil_blur.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/ssil_interleave.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/taa_resolve.glsl.gen.h" #include "servers/rendering/renderer_scene_render.h" @@ -142,231 +129,6 @@ private: PipelineCacheRD pipelines[LUMINANCE_REDUCE_FRAGMENT_MAX]; } luminance_reduce_raster; - struct SSEffectsDownsamplePushConstant { - float pixel_size[2]; - float z_far; - float z_near; - uint32_t orthogonal; - float radius_sq; - uint32_t pad[2]; - }; - - enum SSEffectsMode { - SS_EFFECTS_DOWNSAMPLE, - SS_EFFECTS_DOWNSAMPLE_HALF_RES, - SS_EFFECTS_DOWNSAMPLE_MIPMAP, - SS_EFFECTS_DOWNSAMPLE_MIPMAP_HALF_RES, - SS_EFFECTS_DOWNSAMPLE_HALF, - SS_EFFECTS_DOWNSAMPLE_HALF_RES_HALF, - SS_EFFECTS_DOWNSAMPLE_FULL_MIPS, - SS_EFFECTS_MAX - }; - - struct SSEffectsGatherConstants { - float rotation_matrices[80]; //5 vec4s * 4 - }; - - struct SSEffects { - SSEffectsDownsamplePushConstant downsample_push_constant; - SsEffectsDownsampleShaderRD downsample_shader; - RID downsample_shader_version; - RID downsample_uniform_set; - bool used_half_size_last_frame = false; - bool used_mips_last_frame = false; - bool used_full_mips_last_frame = false; - - RID gather_constants_buffer; - - RID mirror_sampler; - - RID pipelines[SS_EFFECTS_MAX]; - } ss_effects; - - enum SSAOMode { - SSAO_GATHER, - SSAO_GATHER_BASE, - SSAO_GATHER_ADAPTIVE, - SSAO_GENERATE_IMPORTANCE_MAP, - SSAO_PROCESS_IMPORTANCE_MAPA, - SSAO_PROCESS_IMPORTANCE_MAPB, - SSAO_BLUR_PASS, - SSAO_BLUR_PASS_SMART, - SSAO_BLUR_PASS_WIDE, - SSAO_INTERLEAVE, - SSAO_INTERLEAVE_SMART, - SSAO_INTERLEAVE_HALF, - SSAO_MAX - }; - - struct SSAOGatherPushConstant { - int32_t screen_size[2]; - int pass; - int quality; - - float half_screen_pixel_size[2]; - int size_multiplier; - float detail_intensity; - - float NDC_to_view_mul[2]; - float NDC_to_view_add[2]; - - float pad[2]; - float half_screen_pixel_size_x025[2]; - - float radius; - float intensity; - float shadow_power; - float shadow_clamp; - - float fade_out_mul; - float fade_out_add; - float horizon_angle_threshold; - float inv_radius_near_limit; - - uint32_t is_orthogonal; - float neg_inv_radius; - float load_counter_avg_div; - float adaptive_sample_limit; - - int32_t pass_coord_offset[2]; - float pass_uv_offset[2]; - }; - - struct SSAOImportanceMapPushConstant { - float half_screen_pixel_size[2]; - float intensity; - float power; - }; - - struct SSAOBlurPushConstant { - float edge_sharpness; - float pad; - float half_screen_pixel_size[2]; - }; - - struct SSAOInterleavePushConstant { - float inv_sharpness; - uint32_t size_modifier; - float pixel_size[2]; - }; - - struct SSAO { - SSAOGatherPushConstant gather_push_constant; - SsaoShaderRD gather_shader; - RID gather_shader_version; - - SSAOImportanceMapPushConstant importance_map_push_constant; - SsaoImportanceMapShaderRD importance_map_shader; - RID importance_map_shader_version; - RID importance_map_load_counter; - RID counter_uniform_set; - - SSAOBlurPushConstant blur_push_constant; - SsaoBlurShaderRD blur_shader; - RID blur_shader_version; - - SSAOInterleavePushConstant interleave_push_constant; - SsaoInterleaveShaderRD interleave_shader; - RID interleave_shader_version; - - RID pipelines[SSAO_MAX]; - } ssao; - - enum SSILMode { - SSIL_GATHER, - SSIL_GATHER_BASE, - SSIL_GATHER_ADAPTIVE, - SSIL_GENERATE_IMPORTANCE_MAP, - SSIL_PROCESS_IMPORTANCE_MAPA, - SSIL_PROCESS_IMPORTANCE_MAPB, - SSIL_BLUR_PASS, - SSIL_BLUR_PASS_SMART, - SSIL_BLUR_PASS_WIDE, - SSIL_INTERLEAVE, - SSIL_INTERLEAVE_SMART, - SSIL_INTERLEAVE_HALF, - SSIL_MAX - }; - - struct SSILGatherPushConstant { - int32_t screen_size[2]; - int pass; - int quality; - - float half_screen_pixel_size[2]; - float half_screen_pixel_size_x025[2]; - - float NDC_to_view_mul[2]; - float NDC_to_view_add[2]; - - float pad2[2]; - float z_near; - float z_far; - - float radius; - float intensity; - int size_multiplier; - int pad; - - float fade_out_mul; - float fade_out_add; - float normal_rejection_amount; - float inv_radius_near_limit; - - uint32_t is_orthogonal; - float neg_inv_radius; - float load_counter_avg_div; - float adaptive_sample_limit; - - int32_t pass_coord_offset[2]; - float pass_uv_offset[2]; - }; - - struct SSILImportanceMapPushConstant { - float half_screen_pixel_size[2]; - float intensity; - float pad; - }; - - struct SSILBlurPushConstant { - float edge_sharpness; - float pad; - float half_screen_pixel_size[2]; - }; - - struct SSILInterleavePushConstant { - float inv_sharpness; - uint32_t size_modifier; - float pixel_size[2]; - }; - - struct SSILProjectionUniforms { - float inv_last_frame_projection_matrix[16]; - }; - - struct SSIL { - SSILGatherPushConstant gather_push_constant; - SsilShaderRD gather_shader; - RID gather_shader_version; - RID projection_uniform_buffer; - - SSILImportanceMapPushConstant importance_map_push_constant; - SsilImportanceMapShaderRD importance_map_shader; - RID importance_map_shader_version; - RID importance_map_load_counter; - RID counter_uniform_set; - - SSILBlurPushConstant blur_push_constant; - SsilBlurShaderRD blur_shader; - RID blur_shader_version; - - SSILInterleavePushConstant interleave_push_constant; - SsilInterleaveShaderRD interleave_shader; - RID interleave_shader_version; - - RID pipelines[SSIL_MAX]; - } ssil; - struct RoughnessLimiterPushConstant { int32_t screen_size[2]; float curve; @@ -381,101 +143,6 @@ private: } roughness_limiter; - enum SpecularMergeMode { - SPECULAR_MERGE_ADD, - SPECULAR_MERGE_SSR, - SPECULAR_MERGE_ADDITIVE_ADD, - SPECULAR_MERGE_ADDITIVE_SSR, - SPECULAR_MERGE_MAX - }; - - /* Specular merge must be done using raster, rather than compute - * because it must continue the existing color buffer - */ - - struct SpecularMerge { - SpecularMergeShaderRD shader; - RID shader_version; - PipelineCacheRD pipelines[SPECULAR_MERGE_MAX]; - - } specular_merge; - - enum ScreenSpaceReflectionMode { - SCREEN_SPACE_REFLECTION_NORMAL, - SCREEN_SPACE_REFLECTION_ROUGH, - SCREEN_SPACE_REFLECTION_MAX, - }; - - struct ScreenSpaceReflectionPushConstant { - float proj_info[4]; - - int32_t screen_size[2]; - float camera_z_near; - float camera_z_far; - - int32_t num_steps; - float depth_tolerance; - float distance_fade; - float curve_fade_in; - - uint32_t orthogonal; - float filter_mipmap_levels; - uint32_t use_half_res; - uint8_t metallic_mask[4]; - - float projection[16]; - }; - - struct ScreenSpaceReflection { - ScreenSpaceReflectionPushConstant push_constant; - ScreenSpaceReflectionShaderRD shader; - RID shader_version; - RID pipelines[SCREEN_SPACE_REFLECTION_MAX]; - - } ssr; - - struct ScreenSpaceReflectionFilterPushConstant { - float proj_info[4]; - - uint32_t orthogonal; - float edge_tolerance; - int32_t increment; - uint32_t pad; - - int32_t screen_size[2]; - uint32_t vertical; - uint32_t steps; - }; - enum { - SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL, - SCREEN_SPACE_REFLECTION_FILTER_VERTICAL, - SCREEN_SPACE_REFLECTION_FILTER_MAX, - }; - - struct ScreenSpaceReflectionFilter { - ScreenSpaceReflectionFilterPushConstant push_constant; - ScreenSpaceReflectionFilterShaderRD shader; - RID shader_version; - RID pipelines[SCREEN_SPACE_REFLECTION_FILTER_MAX]; - } ssr_filter; - - struct ScreenSpaceReflectionScalePushConstant { - int32_t screen_size[2]; - float camera_z_near; - float camera_z_far; - - uint32_t orthogonal; - uint32_t filter; - uint32_t pad[2]; - }; - - struct ScreenSpaceReflectionScale { - ScreenSpaceReflectionScalePushConstant push_constant; - ScreenSpaceReflectionScaleShaderRD shader; - RID shader_version; - RID pipeline; - } ssr_scale; - struct SubSurfaceScatteringPushConstant { int32_t screen_size[2]; float camera_z_far; @@ -559,9 +226,6 @@ private: RID _get_uniform_set_from_image(RID p_texture); RID _get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false); RID _get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false); - RID _get_compute_uniform_set_from_texture_and_sampler(RID p_texture, RID p_sampler); - RID _get_compute_uniform_set_from_texture_pair(RID p_texture, RID p_texture2, bool p_use_mipmaps = false); - RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2); public: bool get_prefer_raster_effects(); @@ -572,57 +236,9 @@ public: void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); - struct SSAOSettings { - float radius = 1.0; - float intensity = 2.0; - float power = 1.5; - float detail = 0.5; - float horizon = 0.06; - float sharpness = 0.98; - - RS::EnvironmentSSAOQuality quality = RS::ENV_SSAO_QUALITY_MEDIUM; - bool half_size = false; - float adaptive_target = 0.5; - int blur_passes = 2; - float fadeout_from = 50.0; - float fadeout_to = 300.0; - - Size2i full_screen_size = Size2i(); - Size2i half_screen_size = Size2i(); - Size2i quarter_screen_size = Size2i(); - }; - - struct SSILSettings { - float radius = 1.0; - float intensity = 2.0; - float sharpness = 0.98; - float normal_rejection = 1.0; - - RS::EnvironmentSSILQuality quality = RS::ENV_SSIL_QUALITY_MEDIUM; - bool half_size = true; - float adaptive_target = 0.5; - int blur_passes = 4; - float fadeout_from = 50.0; - float fadeout_to = 300.0; - - Size2i full_screen_size = Size2i(); - Size2i half_screen_size = Size2i(); - Size2i quarter_screen_size = Size2i(); - }; - - void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection); - - void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set); - void generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set); - - void gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set); - void screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_importance_map, RID p_importance_map_pong, RID p_edges, const Vector<RID> p_edges_slices, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set, RID &r_projection_uniform_set); - void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve); - void screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RS::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); - 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 sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const Projection &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); void sort_buffer(RID p_uniform_set, int p_size); @@ -630,4 +246,4 @@ public: ~EffectsRD(); }; -#endif // !RASTERIZER_EFFECTS_RD_H +#endif // EFFECTS_RD_H diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index 2a6c96480e..fba04c0db4 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -30,6 +30,11 @@ #include "fog.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" +#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" +#include "servers/rendering/rendering_server_default.h" + using namespace RendererRD; Fog *Fog::singleton = nullptr; @@ -126,3 +131,1075 @@ Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const { ERR_FAIL_COND_V(!fog_volume, Vector3()); return fog_volume->extents; } + +//////////////////////////////////////////////////////////////////////////////// +// Fog material + +bool Fog::FogMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { + uniform_set_updated = true; + + return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, Fog::get_singleton()->volumetric_fog.shader.version_get_shader(shader_data->version, 0), VolumetricFogShader::FogSet::FOG_SET_MATERIAL); +} + +Fog::FogMaterialData::~FogMaterialData() { + free_parameters_uniform_set(uniform_set); +} + +RendererRD::ShaderData *Fog::_create_fog_shader_func() { + FogShaderData *shader_data = memnew(FogShaderData); + return shader_data; +} + +RendererRD::ShaderData *Fog::_create_fog_shader_funcs() { + return Fog::get_singleton()->_create_fog_shader_func(); +}; + +RendererRD::MaterialData *Fog::_create_fog_material_func(FogShaderData *p_shader) { + FogMaterialData *material_data = memnew(FogMaterialData); + material_data->shader_data = p_shader; + //update will happen later anyway so do nothing. + return material_data; +} + +RendererRD::MaterialData *Fog::_create_fog_material_funcs(RendererRD::ShaderData *p_shader) { + return Fog::get_singleton()->_create_fog_material_func(static_cast<FogShaderData *>(p_shader)); +}; + +//////////////////////////////////////////////////////////////////////////////// +// FOG VOLUMES INSTANCE + +RID Fog::fog_volume_instance_create(RID p_fog_volume) { + FogVolumeInstance fvi; + fvi.volume = p_fog_volume; + return fog_volume_instance_owner.make_rid(fvi); +} + +void Fog::fog_instance_free(RID p_rid) { + fog_volume_instance_owner.free(p_rid); +} + +//////////////////////////////////////////////////////////////////////////////// +// Volumetric Fog Shader + +void Fog::init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_cubemap_array) { + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + + { + // Initialize local fog shader + Vector<String> volumetric_fog_modes; + volumetric_fog_modes.push_back(""); + volumetric_fog.shader.initialize(volumetric_fog_modes); + + material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_shader_funcs); + material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_material_funcs); + volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO)); + } + + { + ShaderCompiler::DefaultIdentifierActions actions; + + actions.renames["TIME"] = "scene_params.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); + actions.renames["WORLD_POSITION"] = "world.xyz"; + actions.renames["OBJECT_POSITION"] = "params.position"; + actions.renames["UVW"] = "uvw"; + actions.renames["EXTENTS"] = "params.extents"; + actions.renames["ALBEDO"] = "albedo"; + actions.renames["DENSITY"] = "density"; + actions.renames["EMISSION"] = "emission"; + actions.renames["SDF"] = "sdf"; + + actions.usage_defines["SDF"] = "#define SDF_USED\n"; + actions.usage_defines["DENSITY"] = "#define DENSITY_USED\n"; + actions.usage_defines["ALBEDO"] = "#define ALBEDO_USED\n"; + actions.usage_defines["EMISSION"] = "#define EMISSION_USED\n"; + + actions.sampler_array_name = "material_samplers"; + actions.base_texture_binding_index = 1; + actions.texture_layout_set = VolumetricFogShader::FogSet::FOG_SET_MATERIAL; + actions.base_uniform_string = "material."; + + actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; + actions.default_repeat = ShaderLanguage::REPEAT_DISABLE; + actions.global_buffer_array_variable = "global_variables.data"; + + volumetric_fog.compiler.initialize(actions); + } + + { + // default material and shader for fog shader + volumetric_fog.default_shader = material_storage->shader_allocate(); + material_storage->shader_initialize(volumetric_fog.default_shader); + material_storage->shader_set_code(volumetric_fog.default_shader, R"( +// Default fog shader. + +shader_type fog; + +void fog() { +DENSITY = 1.0; +ALBEDO = vec3(1.0); +} +)"); + volumetric_fog.default_material = material_storage->material_allocate(); + material_storage->material_initialize(volumetric_fog.default_material); + material_storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader); + + FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::SHADER_TYPE_FOG)); + volumetric_fog.default_shader_rd = volumetric_fog.shader.version_get_shader(md->shader_data->version, 0); + + Vector<RD::Uniform> uniforms; + + { + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); + ids_ptr[0] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[1] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[2] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[3] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[4] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[5] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + ids_ptr[6] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[7] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[8] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[9] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[10] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + ids_ptr[11] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 2; + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); + uniforms.push_back(u); + } + + volumetric_fog.base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_BASE); + } + { + String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(p_max_directional_lights) + "\n"; + defines += "\n#define MAX_SKY_LOD " + itos(p_roughness_layers - 1) + ".0\n"; + if (p_is_using_radiance_cubemap_array) { + defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n"; + } + Vector<String> volumetric_fog_modes; + volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n"); + volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n#define ENABLE_SDFGI\n"); + volumetric_fog_modes.push_back("\n#define MODE_FILTER\n"); + volumetric_fog_modes.push_back("\n#define MODE_FOG\n"); + volumetric_fog_modes.push_back("\n#define MODE_COPY\n"); + + volumetric_fog.process_shader.initialize(volumetric_fog_modes, defines); + volumetric_fog.process_shader_version = volumetric_fog.process_shader.version_create(); + for (int i = 0; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) { + volumetric_fog.process_pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, i)); + } + volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO)); + } +} + +void Fog::free_fog_shader() { + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + + volumetric_fog.process_shader.version_free(volumetric_fog.process_shader_version); + RD::get_singleton()->free(volumetric_fog.volume_ubo); + RD::get_singleton()->free(volumetric_fog.params_ubo); + material_storage->shader_free(volumetric_fog.default_shader); + material_storage->material_free(volumetric_fog.default_material); +} + +void Fog::FogShaderData::set_path_hint(const String &p_path) { + path = p_path; +} + +void Fog::FogShaderData::set_code(const String &p_code) { + //compile + + code = p_code; + valid = false; + ubo_size = 0; + uniforms.clear(); + + if (code.is_empty()) { + return; //just invalid, but no error + } + + ShaderCompiler::GeneratedCode gen_code; + ShaderCompiler::IdentifierActions actions; + actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE; + + uses_time = false; + + actions.usage_flag_pointers["TIME"] = &uses_time; + + actions.uniforms = &uniforms; + + Fog *fog_singleton = Fog::get_singleton(); + + Error err = fog_singleton->volumetric_fog.compiler.compile(RS::SHADER_FOG, code, &actions, path, gen_code); + ERR_FAIL_COND_MSG(err != OK, "Fog shader compilation failed."); + + if (version.is_null()) { + version = fog_singleton->volumetric_fog.shader.version_create(); + } + + fog_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines); + ERR_FAIL_COND(!fog_singleton->volumetric_fog.shader.version_is_valid(version)); + + ubo_size = gen_code.uniform_total_size; + ubo_offsets = gen_code.uniform_offsets; + texture_uniforms = gen_code.texture_uniforms; + + pipeline = RD::get_singleton()->compute_pipeline_create(fog_singleton->volumetric_fog.shader.version_get_shader(version, 0)); + + valid = true; +} + +void Fog::FogShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { + if (!p_texture.is_valid()) { + if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { + default_texture_params[p_name].erase(p_index); + + if (default_texture_params[p_name].is_empty()) { + default_texture_params.erase(p_name); + } + } + } else { + if (!default_texture_params.has(p_name)) { + default_texture_params[p_name] = HashMap<int, RID>(); + } + default_texture_params[p_name][p_index] = p_texture; + } +} + +void Fog::FogShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { + RBMap<int, StringName> order; + + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + if (E.value.texture_order >= 0) { + order[E.value.texture_order + 100000] = E.key; + } else { + order[E.value.order] = E.key; + } + } + + String last_group; + for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); + pi.name = E.value; + p_param_list->push_back(pi); + } +} + +void Fog::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + continue; + } + + RendererMaterialStorage::InstanceShaderParam p; + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); + p_param_list->push_back(p); + } +} + +bool Fog::FogShaderData::is_param_texture(const StringName &p_param) const { + if (!uniforms.has(p_param)) { + return false; + } + + return uniforms[p_param].texture_order >= 0; +} + +bool Fog::FogShaderData::is_animated() const { + return false; +} + +bool Fog::FogShaderData::casts_shadows() const { + return false; +} + +Variant Fog::FogShaderData::get_default_parameter(const StringName &p_parameter) const { + if (uniforms.has(p_parameter)) { + ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; + Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; + return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); + } + return Variant(); +} + +RS::ShaderNativeSourceCode Fog::FogShaderData::get_native_source_code() const { + Fog *fog_singleton = Fog::get_singleton(); + + return fog_singleton->volumetric_fog.shader.version_get_native_source_code(version); +} + +Fog::FogShaderData::~FogShaderData() { + Fog *fog_singleton = Fog::get_singleton(); + ERR_FAIL_COND(!fog_singleton); + //pipeline variants will clear themselves if shader is gone + if (version.is_valid()) { + fog_singleton->volumetric_fog.shader.version_free(version); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Volumetric Fog + +Fog::VolumetricFog::VolumetricFog(const Vector3i &fog_size, RID p_sky_shader) { + width = fog_size.x; + height = fog_size.y; + depth = fog_size.z; + + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.width = fog_size.x; + tf.height = fog_size.y; + tf.depth = fog_size.z; + tf.texture_type = RD::TEXTURE_TYPE_3D; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; + + light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(light_density_map, "Fog light-density map"); + + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + + prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(prev_light_density_map, "Fog previous light-density map"); + RD::get_singleton()->texture_clear(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; + + fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(fog_map, "Fog map"); + +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + Vector<uint8_t> dm; + dm.resize(fog_size.x * fog_size.y * fog_size.z * 4); + dm.fill(0); + + density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); + RD::get_singleton()->set_resource_name(density_map, "Fog density map"); + light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); + RD::get_singleton()->set_resource_name(light_map, "Fog light map"); + emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); + RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map"); +#else + tf.format = RD::DATA_FORMAT_R32_UINT; + tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; + density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(density_map, "Fog density map"); + RD::get_singleton()->texture_clear(density_map, Color(0, 0, 0, 0), 0, 1, 0, 1); + light_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(light_map, "Fog light map"); + RD::get_singleton()->texture_clear(light_map, Color(0, 0, 0, 0), 0, 1, 0, 1); + emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); + RD::get_singleton()->set_resource_name(emissive_map, "Fog emissive map"); + RD::get_singleton()->texture_clear(emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1); +#endif + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.binding = 0; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.append_id(fog_map); + uniforms.push_back(u); + } + + sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_sky_shader, RendererRD::SkyRD::SKY_SET_FOG); +} + +Fog::VolumetricFog::~VolumetricFog() { + RD::get_singleton()->free(prev_light_density_map); + RD::get_singleton()->free(light_density_map); + RD::get_singleton()->free(fog_map); + RD::get_singleton()->free(density_map); + RD::get_singleton()->free(light_map); + RD::get_singleton()->free(emissive_map); + + if (fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog_uniform_set)) { + RD::get_singleton()->free(fog_uniform_set); + } + if (process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set_density)) { + RD::get_singleton()->free(process_uniform_set_density); + } + if (process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set)) { + RD::get_singleton()->free(process_uniform_set); + } + if (process_uniform_set2.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set2)) { + RD::get_singleton()->free(process_uniform_set2); + } + if (sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_uniform_set)) { + RD::get_singleton()->free(sdfgi_uniform_set); + } + if (sky_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_uniform_set)) { + RD::get_singleton()->free(sky_uniform_set); + } +} + +Vector3i Fog::_point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform) { + Vector3 view_position = p_cam_transform.affine_inverse().xform(p_point); + view_position.z = MIN(view_position.z, -0.01); // Clamp to the front of camera + Vector3 fog_position = Vector3(0, 0, 0); + + view_position.y = -view_position.y; + fog_position.z = -view_position.z / fog_end; + fog_position.x = (view_position.x / (2 * (fog_near_size.x * (1.0 - fog_position.z) + fog_far_size.x * fog_position.z))) + 0.5; + fog_position.y = (view_position.y / (2 * (fog_near_size.y * (1.0 - fog_position.z) + fog_far_size.y * fog_position.z))) + 0.5; + fog_position.z = Math::pow(float(fog_position.z), float(1.0 / volumetric_fog_detail_spread)); + fog_position = fog_position * fog_size - Vector3(0.5, 0.5, 0.5); + + fog_position.x = CLAMP(fog_position.x, 0.0, fog_size.x); + fog_position.y = CLAMP(fog_position.y, 0.0, fog_size.y); + fog_position.z = CLAMP(fog_position.z, 0.0, fog_size.z); + + return Vector3i(fog_position); +} + +void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + + RENDER_TIMESTAMP("> Volumetric Fog"); + RD::get_singleton()->draw_command_begin_label("Volumetric Fog"); + + if (p_fog_volumes.size() > 0) { + RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes"); + + RENDER_TIMESTAMP("Render FogVolumes"); + + VolumetricFogShader::VolumeUBO params; + + Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); + Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); + float z_near = p_cam_projection.get_z_near(); + float z_far = p_cam_projection.get_z_far(); + float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); + + Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); + Vector2 fog_near_size; + if (p_cam_projection.is_orthogonal()) { + fog_near_size = fog_far_size; + } else { + fog_near_size = Vector2(); + } + + params.fog_frustum_size_begin[0] = fog_near_size.x; + params.fog_frustum_size_begin[1] = fog_near_size.y; + + params.fog_frustum_size_end[0] = fog_far_size.x; + params.fog_frustum_size_end[1] = fog_far_size.y; + + params.fog_frustum_end = fog_end; + params.z_near = z_near; + params.z_far = z_far; + params.time = p_settings.time; + + params.fog_volume_size[0] = p_settings.vfog->width; + params.fog_volume_size[1] = p_settings.vfog->height; + params.fog_volume_size[2] = p_settings.vfog->depth; + + params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env); + params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; + params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); + params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env); + + Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; + RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); + RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform); + + RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms, RD::BARRIER_MASK_COMPUTE); + + if (p_settings.vfog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->fog_uniform_set)) { + Vector<RD::Uniform> uniforms; + + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 1; + u.append_id(p_settings.vfog->emissive_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 2; + u.append_id(volumetric_fog.volume_ubo); + uniforms.push_back(u); + } + + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 3; + u.append_id(p_settings.vfog->density_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 4; + u.append_id(p_settings.vfog->light_map); + uniforms.push_back(u); + } + + p_settings.vfog->fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); + } + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + bool any_uses_time = false; + + for (int i = 0; i < (int)p_fog_volumes.size(); i++) { + FogVolumeInstance *fog_volume_instance = fog_volume_instance_owner.get_or_null(p_fog_volumes[i]); + ERR_FAIL_COND(!fog_volume_instance); + RID fog_volume = fog_volume_instance->volume; + + RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume); + + FogMaterialData *material = nullptr; + + if (fog_material.is_valid()) { + material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); + if (!material || !material->shader_data->valid) { + material = nullptr; + } + } + + if (!material) { + fog_material = volumetric_fog.default_material; + material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); + } + + ERR_FAIL_COND(!material); + + FogShaderData *shader_data = material->shader_data; + + ERR_FAIL_COND(!shader_data); + + any_uses_time |= shader_data->uses_time; + + Vector3i min = Vector3i(); + Vector3i max = Vector3i(); + Vector3i kernel_size = Vector3i(); + + Vector3 position = fog_volume_instance->transform.get_origin(); + RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume); + Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume); + + if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) { + // Local fog volume. + Vector3i points[8]; + Vector3 fog_size = Vector3(p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + float volumetric_fog_detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); + points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[2] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[3] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[4] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[5] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[6] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + points[7] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform); + + min = Vector3i(int32_t(p_settings.vfog->width) - 1, int32_t(p_settings.vfog->height) - 1, int32_t(p_settings.vfog->depth) - 1); + max = Vector3i(1, 1, 1); + + for (int j = 0; j < 8; j++) { + min = Vector3i(MIN(min.x, points[j].x), MIN(min.y, points[j].y), MIN(min.z, points[j].z)); + max = Vector3i(MAX(max.x, points[j].x), MAX(max.y, points[j].y), MAX(max.z, points[j].z)); + } + + kernel_size = max - min; + } else { + // Volume type global runs on all cells + extents = Vector3(p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + min = Vector3i(0, 0, 0); + kernel_size = Vector3i(int32_t(p_settings.vfog->width), int32_t(p_settings.vfog->height), int32_t(p_settings.vfog->depth)); + } + + if (kernel_size.x == 0 || kernel_size.y == 0 || kernel_size.z == 0) { + continue; + } + + VolumetricFogShader::FogPushConstant push_constant; + push_constant.position[0] = position.x; + push_constant.position[1] = position.y; + push_constant.position[2] = position.z; + push_constant.extents[0] = extents.x; + push_constant.extents[1] = extents.y; + push_constant.extents[2] = extents.z; + push_constant.corner[0] = min.x; + push_constant.corner[1] = min.y; + push_constant.corner[2] = min.z; + push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume)); + RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), push_constant.transform); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->fog_uniform_set, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VolumetricFogShader::FogPushConstant)); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE); + if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set. + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL); + } + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z); + } + if (any_uses_time || RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) { + RenderingServerDefault::redraw_request(); + } + + RD::get_singleton()->draw_command_end_label(); + + RD::get_singleton()->compute_list_end(); + } + + if (p_settings.vfog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->process_uniform_set_density)) { + //re create uniform set if needed + Vector<RD::Uniform> uniforms; + Vector<RD::Uniform> copy_uniforms; + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 1; + if (p_settings.shadow_atlas_depth.is_null()) { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); + } else { + u.append_id(p_settings.shadow_atlas_depth); + } + + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 2; + if (p_settings.directional_shadow_depth.is_valid()) { + u.append_id(p_settings.directional_shadow_depth); + } else { + u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); + } + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 3; + u.append_id(p_settings.omni_light_buffer); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 4; + u.append_id(p_settings.spot_light_buffer); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 5; + u.append_id(p_settings.directional_light_buffer); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 6; + u.append_id(p_settings.cluster_builder->get_cluster_buffer()); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 7; + u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 8; + u.append_id(p_settings.vfog->light_density_map); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 9; + u.append_id(p_settings.vfog->fog_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 9; + u.append_id(p_settings.vfog->prev_light_density_map); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 10; + u.append_id(p_settings.shadow_sampler); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 11; + u.append_id(p_settings.voxel_gl_buffer); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 12; + for (int i = 0; i < RendererRD::GI::MAX_VOXEL_GI_INSTANCES; i++) { + u.append_id(p_settings.rbgi->voxel_gi_textures[i]); + } + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; + u.binding = 13; + u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 14; + u.append_id(volumetric_fog.params_ubo); + uniforms.push_back(u); + copy_uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 15; + u.append_id(p_settings.vfog->prev_light_density_map); + uniforms.push_back(u); + } + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 16; + u.append_id(p_settings.vfog->density_map); + uniforms.push_back(u); + } + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 17; + u.append_id(p_settings.vfog->light_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; +#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) + u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; +#else + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; +#endif + u.binding = 18; + u.append_id(p_settings.vfog->emissive_map); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 19; + RID radiance_texture = texture_storage->texture_rd_get_default(p_settings.is_using_radiance_cubemap_array ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); + RID sky_texture = RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env).is_valid() ? p_settings.sky->sky_get_radiance_texture_rd(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_settings.env)) : RID(); + u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture); + uniforms.push_back(u); + } + + p_settings.vfog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0); + + p_settings.vfog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); + + RID aux7 = uniforms.write[7].get_id(0); + RID aux8 = uniforms.write[8].get_id(0); + + uniforms.write[7].set_id(0, aux8); + uniforms.write[8].set_id(0, aux7); + + p_settings.vfog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); + + uniforms.remove_at(8); + uniforms.write[7].set_id(0, aux7); + p_settings.vfog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); + } + + bool using_sdfgi = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.0001 && RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_enabled(p_settings.env) && (p_settings.sdfgi != nullptr); + + if (using_sdfgi) { + if (p_settings.vfog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(p_settings.vfog->sdfgi_uniform_set)) { + Vector<RD::Uniform> uniforms; + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; + u.binding = 0; + u.append_id(p_settings.gi->sdfgi_ubo); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 1; + u.append_id(p_settings.sdfgi->ambient_texture); + uniforms.push_back(u); + } + + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 2; + u.append_id(p_settings.sdfgi->occlusion_texture); + uniforms.push_back(u); + } + + p_settings.vfog->sdfgi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI), 1); + } + } + + p_settings.vfog->length = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); + p_settings.vfog->spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); + + VolumetricFogShader::ParamsUBO params; + + Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); + Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); + float z_near = p_cam_projection.get_z_near(); + float z_far = p_cam_projection.get_z_far(); + float fog_end = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_length(p_settings.env); + + Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); + Vector2 fog_near_size; + if (p_cam_projection.is_orthogonal()) { + fog_near_size = fog_far_size; + } else { + fog_near_size = Vector2(); + } + + params.fog_frustum_size_begin[0] = fog_near_size.x; + params.fog_frustum_size_begin[1] = fog_near_size.y; + + params.fog_frustum_size_end[0] = fog_far_size.x; + params.fog_frustum_size_end[1] = fog_far_size.y; + + params.ambient_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_ambient_inject(p_settings.env) * RendererSceneRenderRD::get_singleton()->environment_get_ambient_light_energy(p_settings.env); + params.z_far = z_far; + + params.fog_frustum_end = fog_end; + + Color ambient_color = RendererSceneRenderRD::get_singleton()->environment_get_ambient_light(p_settings.env).srgb_to_linear(); + params.ambient_color[0] = ambient_color.r; + params.ambient_color[1] = ambient_color.g; + params.ambient_color[2] = ambient_color.b; + params.sky_contribution = RendererSceneRenderRD::get_singleton()->environment_get_ambient_sky_contribution(p_settings.env); + + params.fog_volume_size[0] = p_settings.vfog->width; + params.fog_volume_size[1] = p_settings.vfog->height; + params.fog_volume_size[2] = p_settings.vfog->depth; + + params.directional_light_count = p_directional_light_count; + + Color emission = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission(p_settings.env).srgb_to_linear(); + params.base_emission[0] = emission.r * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); + params.base_emission[1] = emission.g * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); + params.base_emission[2] = emission.b * RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_emission_energy(p_settings.env); + params.base_density = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_density(p_settings.env); + + Color base_scattering = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_scattering(p_settings.env).srgb_to_linear(); + params.base_scattering[0] = base_scattering.r; + params.base_scattering[1] = base_scattering.g; + params.base_scattering[2] = base_scattering.b; + params.phase_g = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_anisotropy(p_settings.env); + + params.detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env); + params.gi_inject = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env); + + params.cam_rotation[0] = p_cam_transform.basis[0][0]; + params.cam_rotation[1] = p_cam_transform.basis[1][0]; + params.cam_rotation[2] = p_cam_transform.basis[2][0]; + params.cam_rotation[3] = 0; + params.cam_rotation[4] = p_cam_transform.basis[0][1]; + params.cam_rotation[5] = p_cam_transform.basis[1][1]; + params.cam_rotation[6] = p_cam_transform.basis[2][1]; + params.cam_rotation[7] = 0; + params.cam_rotation[8] = p_cam_transform.basis[0][2]; + params.cam_rotation[9] = p_cam_transform.basis[1][2]; + params.cam_rotation[10] = p_cam_transform.basis[2][2]; + params.cam_rotation[11] = 0; + params.filter_axis = 0; + params.max_voxel_gi_instances = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.001 ? p_voxel_gi_count : 0; + params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; + + Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; + RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); + + params.use_temporal_reprojection = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env); + params.temporal_blend = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection_amount(p_settings.env); + + { + uint32_t cluster_size = p_settings.cluster_builder->get_cluster_size(); + params.cluster_shift = get_shift_from_power_of_2(cluster_size); + + uint32_t cluster_screen_width = (p_settings.rb_size.x - 1) / cluster_size + 1; + uint32_t cluster_screen_height = (p_settings.rb_size.y - 1) / cluster_size + 1; + params.max_cluster_element_count_div_32 = p_settings.max_cluster_elements / 32; + params.cluster_type_size = cluster_screen_width * cluster_screen_height * (params.max_cluster_element_count_div_32 + 32); + params.cluster_width = cluster_screen_width; + + params.screen_size[0] = p_settings.rb_size.x; + params.screen_size[1] = p_settings.rb_size.y; + } + + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_settings.env); + sky_transform = sky_transform.inverse() * p_cam_transform.basis; + RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform); + + 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::BARRIER_MASK_COMPUTE); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set_density, 0); + + if (using_sdfgi) { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->sdfgi_uniform_set, 1); + } + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + // Copy fog to history buffer + if (RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) { + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->copy_uniform_set, 0); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + RD::get_singleton()->compute_list_add_barrier(compute_list); + } + RD::get_singleton()->draw_command_end_label(); + + if (p_settings.volumetric_fog_filter_active) { + 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.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set, 0); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->depth); + + RD::get_singleton()->compute_list_end(); + //need restart for buffer update + + params.filter_axis = 1; + RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms); + + compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set2, 0); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, p_settings.vfog->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.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_settings.vfog->process_uniform_set, 0); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.vfog->width, p_settings.vfog->height, 1); + + RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER); + + RENDER_TIMESTAMP("< Volumetric Fog"); + RD::get_singleton()->draw_command_end_label(); + RD::get_singleton()->draw_command_end_label(); +} diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h index 55a01c3616..e777a1d383 100644 --- a/servers/rendering/renderer_rd/environment/fog.h +++ b/servers/rendering/renderer_rd/environment/fog.h @@ -34,12 +34,18 @@ #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "servers/rendering/environment/renderer_fog.h" +#include "servers/rendering/renderer_rd/cluster_builder_rd.h" +#include "servers/rendering/renderer_rd/environment/gi.h" +#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl.gen.h" #include "servers/rendering/storage/utilities.h" namespace RendererRD { class Fog : public RendererFog { public: + /* FOG VOLUMES */ + struct FogVolume { RID material; Vector3 extents = Vector3(1, 1, 1); @@ -49,10 +55,179 @@ public: Dependency dependency; }; + struct FogVolumeInstance { + RID volume; + Transform3D transform; + bool active = false; + }; + private: static Fog *singleton; mutable RID_Owner<FogVolume, true> fog_volume_owner; + mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner; + + /* Volumetric Fog */ + struct VolumetricFogShader { + enum FogSet { + FOG_SET_BASE, + FOG_SET_UNIFORMS, + FOG_SET_MATERIAL, + FOG_SET_MAX, + }; + + struct FogPushConstant { + float position[3]; + float pad; + + float extents[3]; + float pad2; + + int32_t corner[3]; + uint32_t shape; + + float transform[16]; + }; + + struct VolumeUBO { + float fog_frustum_size_begin[2]; + float fog_frustum_size_end[2]; + + float fog_frustum_end; + float z_near; + float z_far; + float time; + + int32_t fog_volume_size[3]; + uint32_t directional_light_count; + + uint32_t use_temporal_reprojection; + uint32_t temporal_frame; + float detail_spread; + float temporal_blend; + + float to_prev_view[16]; + float transform[16]; + }; + + ShaderCompiler compiler; + VolumetricFogShaderRD shader; + RID volume_ubo; + + RID default_shader; + RID default_material; + RID default_shader_rd; + + RID base_uniform_set; + + RID params_ubo; + + enum { + VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY, + VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI, + VOLUMETRIC_FOG_PROCESS_SHADER_FILTER, + VOLUMETRIC_FOG_PROCESS_SHADER_FOG, + VOLUMETRIC_FOG_PROCESS_SHADER_COPY, + VOLUMETRIC_FOG_PROCESS_SHADER_MAX, + }; + + struct ParamsUBO { + float fog_frustum_size_begin[2]; + float fog_frustum_size_end[2]; + + float fog_frustum_end; + float ambient_inject; + float z_far; + uint32_t filter_axis; + + float ambient_color[3]; + float sky_contribution; + + int32_t fog_volume_size[3]; + uint32_t directional_light_count; + + float base_emission[3]; + float base_density; + + float base_scattering[3]; + float phase_g; + + float detail_spread; + float gi_inject; + uint32_t max_voxel_gi_instances; + uint32_t cluster_type_size; + + float screen_size[2]; + uint32_t cluster_shift; + uint32_t cluster_width; + + 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]; + float radiance_inverse_xform[12]; + }; + + VolumetricFogProcessShaderRD process_shader; + + RID process_shader_version; + RID process_pipelines[VOLUMETRIC_FOG_PROCESS_SHADER_MAX]; + + } volumetric_fog; + + Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform); + + struct FogShaderData : public RendererRD::ShaderData { + bool valid = false; + RID version; + + RID pipeline; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; + + Vector<uint32_t> ubo_offsets; + uint32_t ubo_size = 0; + + String path; + String code; + HashMap<StringName, HashMap<int, RID>> default_texture_params; + + bool uses_time = false; + + virtual void set_path_hint(const String &p_hint); + virtual void set_code(const String &p_Code); + virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); + virtual void get_param_list(List<PropertyInfo> *p_param_list) const; + virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; + virtual bool is_param_texture(const StringName &p_param) const; + virtual bool is_animated() const; + virtual bool casts_shadows() const; + virtual Variant get_default_parameter(const StringName &p_parameter) const; + virtual RS::ShaderNativeSourceCode get_native_source_code() const; + + FogShaderData() {} + virtual ~FogShaderData(); + }; + + struct FogMaterialData : public RendererRD::MaterialData { + FogShaderData *shader_data = nullptr; + RID uniform_set; + bool uniform_set_updated; + + virtual void set_render_priority(int p_priority) {} + virtual void set_next_pass(RID p_pass) {} + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); + virtual ~FogMaterialData(); + }; + + RendererRD::ShaderData *_create_fog_shader_func(); + static RendererRD::ShaderData *_create_fog_shader_funcs(); + + RendererRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader); + static RendererRD::MaterialData *_create_fog_material_funcs(RendererRD::ShaderData *p_shader); public: static Fog *get_singleton() { return singleton; } @@ -76,8 +251,78 @@ public: RID fog_volume_get_material(RID p_fog_volume) const; virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override; Vector3 fog_volume_get_extents(RID p_fog_volume) const; + + /* FOG VOLUMES INSTANCE */ + + FogVolumeInstance *get_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.get_or_null(p_rid); }; + bool owns_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.owns(p_rid); }; + + RID fog_volume_instance_create(RID p_fog_volume); + void fog_instance_free(RID p_rid); + + /* Volumetric FOG */ + struct VolumetricFog { + enum { + MAX_TEMPORAL_FRAMES = 16 + }; + + uint32_t width = 0; + uint32_t height = 0; + uint32_t depth = 0; + + float length; + float spread; + + RID light_density_map; + RID prev_light_density_map; + RID fog_map; + RID density_map; + RID light_map; + RID emissive_map; + + RID fog_uniform_set; + RID copy_uniform_set; + RID process_uniform_set_density; + RID process_uniform_set; + RID process_uniform_set2; + RID sdfgi_uniform_set; + RID sky_uniform_set; + + int last_shadow_filter = -1; + + VolumetricFog(const Vector3i &fog_size, RID p_sky_shader); + ~VolumetricFog(); + }; + + void init_fog_shader(uint32_t p_max_directional_lights, int p_roughness_layers, bool p_is_using_radiance_cubemap_array); + void free_fog_shader(); + + struct VolumetricFogSettings { + Vector2i rb_size; + double time; + bool is_using_radiance_cubemap_array; + uint32_t max_cluster_elements; + bool volumetric_fog_filter_active; + RID shadow_sampler; + RID voxel_gl_buffer; + RID shadow_atlas_depth; + RID omni_light_buffer; + RID spot_light_buffer; + RID directional_shadow_depth; + RID directional_light_buffer; + + // Objects related to our render buffer + VolumetricFog *vfog; + ClusterBuilderRD *cluster_builder; + GI *gi; + GI::SDFGI *sdfgi; + GI::RenderBuffersGI *rbgi; + RID env; + SkyRD *sky; + }; + void volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); }; } // namespace RendererRD -#endif // !FOG_RD_H +#endif // FOG_RD_H diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 3275aea13c..7b4f61bd17 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -374,15 +374,15 @@ RID GI::voxel_gi_get_sdf_texture(RID p_voxel_gi) { //////////////////////////////////////////////////////////////////////////////// // SDFGI -void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) { +void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); gi = p_gi; - num_cascades = p_env->sdfgi_cascades; - min_cell_size = p_env->sdfgi_min_cell_size; - uses_occlusion = p_env->sdfgi_use_occlusion; - y_scale_mode = p_env->sdfgi_y_scale; + num_cascades = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_cascades(p_env); + min_cell_size = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_min_cell_size(p_env); + uses_occlusion = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_use_occlusion(p_env); + y_scale_mode = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_y_scale(p_env); static const float y_scale[3] = { 2.0, 1.5, 1.0 }; y_mult = y_scale[y_scale_mode]; cascades.resize(num_cascades); @@ -1101,11 +1101,11 @@ void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 0); } - bounce_feedback = p_env->sdfgi_bounce_feedback; - energy = p_env->sdfgi_energy; - normal_bias = p_env->sdfgi_normal_bias; - probe_bias = p_env->sdfgi_probe_bias; - reads_sky = p_env->sdfgi_read_sky_light; + bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env); + energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env); + normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env); + probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env); + reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env); } void GI::SDFGI::erase() { @@ -1163,12 +1163,12 @@ void GI::SDFGI::erase() { } } -void GI::SDFGI::update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position) { - bounce_feedback = p_env->sdfgi_bounce_feedback; - energy = p_env->sdfgi_energy; - normal_bias = p_env->sdfgi_normal_bias; - probe_bias = p_env->sdfgi_probe_bias; - reads_sky = p_env->sdfgi_read_sky_light; +void GI::SDFGI::update(RID p_env, const Vector3 &p_world_position) { + bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env); + energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env); + normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env); + probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env); + reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env); int32_t drag_margin = (cascade_size / SDFGI::PROBE_DIVISOR) / 2; @@ -1268,7 +1268,7 @@ void GI::SDFGI::update_light() { RD::get_singleton()->draw_command_end_label(); } -void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky) { +void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) { RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes"); SDFGIShader::IntegratePushConstant push_constant; @@ -1284,29 +1284,29 @@ void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSk push_constant.ray_bias = probe_bias; push_constant.image_size[0] = probe_axis_count * probe_axis_count; push_constant.image_size[1] = probe_axis_count; - push_constant.store_ambient_texture = p_env->volumetric_fog_enabled; + push_constant.store_ambient_texture = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_enabled(p_env); RID sky_uniform_set = gi->sdfgi_shader.integrate_default_sky_uniform_set; push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_DISABLED; push_constant.y_mult = y_mult; - if (reads_sky && p_env) { - push_constant.sky_energy = p_env->bg_energy; + if (reads_sky && p_env.is_valid()) { + push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); - if (p_env->background == RS::ENV_BG_CLEAR_COLOR) { + if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_CLEAR_COLOR) { push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear(); push_constant.sky_color[0] = c.r; push_constant.sky_color[1] = c.g; push_constant.sky_color[2] = c.b; - } else if (p_env->background == RS::ENV_BG_COLOR) { + } else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_COLOR) { push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR; - Color c = p_env->bg_color; + Color c = RendererSceneRenderRD::get_singleton()->environment_get_bg_color(p_env); push_constant.sky_color[0] = c.r; push_constant.sky_color[1] = c.g; push_constant.sky_color[2] = c.b; - } else if (p_env->background == RS::ENV_BG_SKY) { + } else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_SKY) { if (p_sky && p_sky->radiance.is_valid()) { if (integrate_sky_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(integrate_sky_uniform_set)) { Vector<RD::Uniform> uniforms; @@ -1482,7 +1482,7 @@ void GI::SDFGI::update_cascades() { RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE); } -void GI::SDFGI::debug_draw(uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views) { +void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); @@ -1615,7 +1615,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const CameraMatrix *p_projecti push_constant.cam_transform[15] = 1; // need to properly unproject for asymmetric projection matrices in stereo.. - CameraMatrix inv_projection = p_projections[v].inverse(); + Projection inv_projection = p_projections[v].inverse(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { push_constant.inv_projection[i * 4 + j] = inv_projection.matrix[i][j]; @@ -1632,7 +1632,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const CameraMatrix *p_projecti copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true, false, false, false, RID(), p_view_count > 1); } -void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { +void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); // setup scene data @@ -1947,7 +1947,7 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r } } -void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { +void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) { //print_line("rendering region " + itos(p_region)); RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... @@ -2428,7 +2428,7 @@ void GI::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_co //////////////////////////////////////////////////////////////////////////////// // VoxelGIInstance -void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); uint32_t data_version = gi->voxel_gi_get_data_version(probe); @@ -2951,10 +2951,10 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID //this could probably be better parallelized in compute.. for (int i = 0; i < (int)p_dynamic_objects.size(); i++) { - RendererSceneRender::GeometryInstance *instance = p_dynamic_objects[i]; + RenderGeometryInstance *instance = p_dynamic_objects[i]; //transform aabb to voxel_gi - AABB aabb = (to_probe_xform * p_scene_render->geometry_instance_get_transform(instance)).xform(p_scene_render->geometry_instance_get_aabb(instance)); + AABB aabb = (to_probe_xform * instance->get_transform()).xform(instance->get_aabb()); //this needs to wrap to grid resolution to avoid jitter //also extend margin a bit just in case @@ -3015,7 +3015,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID bool y_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(1)) < 0); bool z_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(2)) > 0); - CameraMatrix cm; + Projection cm; cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]); if (p_scene_render->cull_argument.size() == 0) { @@ -3140,14 +3140,14 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID last_probe_version = gi->voxel_gi_get_version(probe); } -void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { +void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); if (mipmaps.size() == 0) { return; } - CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse()); + Projection cam_transform = (p_camera_with_transform * Projection(transform)) * Projection(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse()); int level = 0; Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); @@ -3233,7 +3233,7 @@ GI::~GI() { singleton = nullptr; } -void GI::init(RendererSceneSkyRD *p_sky) { +void GI::init(SkyRD *p_sky) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -3477,7 +3477,7 @@ void GI::free() { } } -GI::SDFGI *GI::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) { +GI::SDFGI *GI::create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) { SDFGI *sdfgi = memnew(SDFGI); sdfgi->create(p_env, p_world_position, p_requested_history_size, this); @@ -3621,7 +3621,7 @@ void GI::RenderBuffersGI::free() { } } -void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { +void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -3710,7 +3710,7 @@ void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, // Now compute the contents of our buffers. RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true); - // Render each eye seperately. + // Render each eye separately. // We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference.. // setup our push constant @@ -3960,14 +3960,14 @@ bool GI::voxel_gi_needs_update(RID p_probe) const { return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe); } -void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { +void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) { VoxelGIInstance *voxel_gi = get_probe_instance(p_probe); ERR_FAIL_COND(!voxel_gi); voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render); } -void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { +void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h index ac41ad20e1..c9e1a14e2e 100644 --- a/servers/rendering/renderer_rd/environment/gi.h +++ b/servers/rendering/renderer_rd/environment/gi.h @@ -35,8 +35,7 @@ #include "core/templates/rid_owner.h" #include "servers/rendering/environment/renderer_gi.h" #include "servers/rendering/renderer_compositor.h" -#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" -#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h" +#include "servers/rendering/renderer_rd/environment/sky.h" #include "servers/rendering/renderer_rd/shaders/environment/gi.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl.gen.h" @@ -471,8 +470,8 @@ public: Transform3D transform; - void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); - void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); + void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; mutable RID_Owner<VoxelGIInstance> voxel_gi_instance_owner; @@ -614,20 +613,20 @@ public: int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically RID integrate_sky_uniform_set; - void create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi); + void create(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi); void erase(); - void update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position); + void update(RID p_env, const Vector3 &p_world_position); void update_light(); - void update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky); + void update_probes(RID p_env, RendererRD::SkyRD::Sky *p_sky); void store_probes(); int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const; void update_cascades(); - void debug_draw(uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views); - void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); + void debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views); + void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); - void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); + void render_region(RID p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); void render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render); }; @@ -756,7 +755,7 @@ public: SHADER_SPECIALIZATION_HALF_RES = 1 << 0, SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX = 1 << 1, SHADER_SPECIALIZATION_USE_VRS = 1 << 2, - SHADER_SPECIALIZATION_VARIATIONS = 0x07, + SHADER_SPECIALIZATION_VARIATIONS = 8, }; RID default_voxel_gi_buffer; @@ -769,21 +768,21 @@ public: GI(); ~GI(); - void init(RendererSceneSkyRD *p_sky); + void init(RendererRD::SkyRD *p_sky); void free(); - SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); + SDFGI *create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render); - void process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); + void process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); RID voxel_gi_instance_create(RID p_base); void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); bool voxel_gi_needs_update(RID p_probe) const; - void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); - void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); + void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); + void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; } // namespace RendererRD -#endif /* !GI_RD_H */ +#endif // GI_RD_H diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 73175d3cf3..228d2673f2 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* renderer_scene_sky_rd.cpp */ +/* sky.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,27 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "renderer_scene_sky_rd.h" +#include "sky.h" #include "core/config/project_settings.h" #include "core/math/math_defs.h" -#include "renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/effects/copy_effects.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_server_default.h" #include "servers/rendering/rendering_server_globals.h" +using namespace RendererRD; + //////////////////////////////////////////////////////////////////////////////// // SKY SHADER -void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) { +void SkyRD::SkyShaderData::set_path_hint(const String &p_path) { + path = p_path; +} + +void SkyRD::SkyShaderData::set_code(const String &p_code) { //compile code = p_code; @@ -141,7 +147,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) { valid = true; } -void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { +void SkyRD::SkyShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { if (!p_texture.is_valid()) { if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { default_texture_params[p_name].erase(p_index); @@ -158,7 +164,7 @@ void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringNa } } -void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { +void SkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { @@ -172,15 +178,29 @@ void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_par order[E.value.order] = E.key; } } - + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); } } -void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { +void SkyRD::SkyShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; @@ -195,7 +215,7 @@ void RendererSceneSkyRD::SkyShaderData::get_instance_param_list(List<RendererMat } } -bool RendererSceneSkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const { +bool SkyRD::SkyShaderData::is_param_texture(const StringName &p_param) const { if (!uniforms.has(p_param)) { return false; } @@ -203,15 +223,15 @@ bool RendererSceneSkyRD::SkyShaderData::is_param_texture(const StringName &p_par return uniforms[p_param].texture_order >= 0; } -bool RendererSceneSkyRD::SkyShaderData::is_animated() const { +bool SkyRD::SkyShaderData::is_animated() const { return false; } -bool RendererSceneSkyRD::SkyShaderData::casts_shadows() const { +bool SkyRD::SkyShaderData::casts_shadows() const { return false; } -Variant RendererSceneSkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const { +Variant SkyRD::SkyShaderData::get_default_parameter(const StringName &p_parameter) const { if (uniforms.has(p_parameter)) { ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; @@ -220,13 +240,13 @@ Variant RendererSceneSkyRD::SkyShaderData::get_default_parameter(const StringNam return Variant(); } -RS::ShaderNativeSourceCode RendererSceneSkyRD::SkyShaderData::get_native_source_code() const { +RS::ShaderNativeSourceCode SkyRD::SkyShaderData::get_native_source_code() const { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); return scene_singleton->sky.sky_shader.shader.version_get_native_source_code(version); } -RendererSceneSkyRD::SkyShaderData::~SkyShaderData() { +SkyRD::SkyShaderData::~SkyShaderData() { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); ERR_FAIL_COND(!scene_singleton); //pipeline variants will clear themselves if shader is gone @@ -238,7 +258,7 @@ RendererSceneSkyRD::SkyShaderData::~SkyShaderData() { //////////////////////////////////////////////////////////////////////////////// // Sky material -bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +bool SkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); uniform_set_updated = true; @@ -246,7 +266,7 @@ bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const HashMap<String return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL); } -RendererSceneSkyRD::SkyMaterialData::~SkyMaterialData() { +SkyRD::SkyMaterialData::~SkyMaterialData() { free_parameters_uniform_set(uniform_set); } @@ -268,7 +288,7 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar p_array[11] = 0; } -void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) { +void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) { SkyPushConstant sky_push_constant; memset(&sky_push_constant, 0, sizeof(SkyPushConstant)); @@ -319,7 +339,7 @@ void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_ //////////////////////////////////////////////////////////////////////////////// // ReflectionData -void RendererSceneSkyRD::ReflectionData::clear_reflection_data() { +void SkyRD::ReflectionData::clear_reflection_data() { layers.clear(); radiance_base_cubemap = RID(); if (downsampled_radiance_cubemap.is_valid()) { @@ -330,7 +350,7 @@ void RendererSceneSkyRD::ReflectionData::clear_reflection_data() { coefficient_buffer = RID(); } -void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) { +void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) { //recreate radiance and all data int mipmaps = p_mipmaps; @@ -399,21 +419,22 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, 1, RD::TEXTURE_SLICE_CUBEMAP); RD::get_singleton()->set_resource_name(radiance_base_cubemap, "radiance base cubemap"); + RD::TextureFormat tf; tf.format = p_texture_format; - tf.width = 64; // Always 64x64 - tf.height = 64; + tf.width = p_low_quality ? 64 : p_size >> 1; // Always 64x64 when using REALTIME. + tf.height = p_low_quality ? 64 : p_size >> 1; tf.texture_type = RD::TEXTURE_TYPE_CUBE; tf.array_layers = 6; - tf.mipmaps = 7; + tf.mipmaps = p_low_quality ? 7 : mipmaps - 1; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView()); RD::get_singleton()->set_resource_name(downsampled_radiance_cubemap, "downsampled radiance cubemap"); { - uint32_t mmw = 64; - uint32_t mmh = 64; - downsampled_layer.mipmaps.resize(7); + uint32_t mmw = tf.width; + uint32_t mmh = tf.height; + downsampled_layer.mipmaps.resize(tf.mipmaps); for (int j = 0; j < downsampled_layer.mipmaps.size(); j++) { ReflectionData::DownsampleLayer::Mipmap &mm = downsampled_layer.mipmaps.write[j]; mm.size.width = mmw; @@ -438,7 +459,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int } } -void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { +void SkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); @@ -496,7 +517,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_us } } -void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { +void SkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); @@ -565,7 +586,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(boo RD::get_singleton()->draw_command_end_label(); // Filter radiance } -void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) { +void SkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised"); bool prefer_raster_effects = copy_effects->get_prefer_raster_effects(); @@ -590,9 +611,9 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start, } //////////////////////////////////////////////////////////////////////////////// -// RendererSceneSkyRD::Sky +// SkyRD::Sky -void RendererSceneSkyRD::Sky::free() { +void SkyRD::Sky::free() { if (radiance.is_valid()) { RD::get_singleton()->free(radiance); radiance = RID(); @@ -620,7 +641,7 @@ void RendererSceneSkyRD::Sky::free() { } } -RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) { +RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) { @@ -681,7 +702,7 @@ RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_ return texture_uniform_sets[p_version]; } -bool RendererSceneSkyRD::Sky::set_radiance_size(int p_radiance_size) { +bool SkyRD::Sky::set_radiance_size(int p_radiance_size) { ERR_FAIL_COND_V(p_radiance_size < 32 || p_radiance_size > 2048, false); if (radiance_size == p_radiance_size) { return false; @@ -702,7 +723,7 @@ bool RendererSceneSkyRD::Sky::set_radiance_size(int p_radiance_size) { return true; } -bool RendererSceneSkyRD::Sky::set_mode(RS::SkyMode p_mode) { +bool SkyRD::Sky::set_mode(RS::SkyMode p_mode) { if (mode == p_mode) { return false; } @@ -723,7 +744,7 @@ bool RendererSceneSkyRD::Sky::set_mode(RS::SkyMode p_mode) { return true; } -bool RendererSceneSkyRD::Sky::set_material(RID p_material) { +bool SkyRD::Sky::set_material(RID p_material) { if (material == p_material) { return false; } @@ -732,7 +753,7 @@ bool RendererSceneSkyRD::Sky::set_material(RID p_material) { return true; } -Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size) { +Ref<Image> SkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size) { if (radiance.is_valid()) { RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); @@ -766,37 +787,37 @@ Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(float p_energy, int p_roughnes } //////////////////////////////////////////////////////////////////////////////// -// RendererSceneSkyRD +// SkyRD -RendererRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_func() { +RendererRD::ShaderData *SkyRD::_create_sky_shader_func() { SkyShaderData *shader_data = memnew(SkyShaderData); return shader_data; } -RendererRD::ShaderData *RendererSceneSkyRD::_create_sky_shader_funcs() { +RendererRD::ShaderData *SkyRD::_create_sky_shader_funcs() { // !BAS! Why isn't _create_sky_shader_func not just static too? return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_shader_func(); }; -RendererRD::MaterialData *RendererSceneSkyRD::_create_sky_material_func(SkyShaderData *p_shader) { +RendererRD::MaterialData *SkyRD::_create_sky_material_func(SkyShaderData *p_shader) { SkyMaterialData *material_data = memnew(SkyMaterialData); material_data->shader_data = p_shader; //update will happen later anyway so do nothing. return material_data; } -RendererRD::MaterialData *RendererSceneSkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) { +RendererRD::MaterialData *SkyRD::_create_sky_material_funcs(RendererRD::ShaderData *p_shader) { // !BAS! same here, we could just make _create_sky_material_func static? return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->sky._create_sky_material_func(static_cast<SkyShaderData *>(p_shader)); }; -RendererSceneSkyRD::RendererSceneSkyRD() { +SkyRD::SkyRD() { roughness_layers = GLOBAL_GET("rendering/reflections/sky_reflections/roughness_layers"); sky_ggx_samples_quality = GLOBAL_GET("rendering/reflections/sky_reflections/ggx_samples"); sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections"); } -void RendererSceneSkyRD::init() { +void SkyRD::init() { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -891,7 +912,7 @@ void RendererSceneSkyRD::init() { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; sky_shader.compiler.initialize(actions); } @@ -949,7 +970,7 @@ void sky() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -1051,11 +1072,11 @@ void sky() { } } -void RendererSceneSkyRD::set_texture_format(RD::DataFormat p_texture_format) { +void SkyRD::set_texture_format(RD::DataFormat p_texture_format) { texture_format = p_texture_format; } -RendererSceneSkyRD::~RendererSceneSkyRD() { +SkyRD::~SkyRD() { // cleanup anything created in init... RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -1085,20 +1106,20 @@ RendererSceneSkyRD::~RendererSceneSkyRD() { RD::get_singleton()->free(index_buffer); //array gets freed as dependency } -void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { +void SkyRD::setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); SkyMaterialData *material = nullptr; - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); RID sky_material; SkyShaderData *shader_data = nullptr; if (sky) { - sky_material = sky_get_material(p_env->sky); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); if (sky_material.is_valid()) { material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); @@ -1284,27 +1305,27 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b } sky_scene_state.ubo.z_far = p_projection.get_z_far(); - sky_scene_state.ubo.fog_enabled = p_env->fog_enabled; - sky_scene_state.ubo.fog_density = p_env->fog_density; - sky_scene_state.ubo.fog_aerial_perspective = p_env->fog_aerial_perspective; - Color fog_color = p_env->fog_light_color.srgb_to_linear(); - float fog_energy = p_env->fog_light_energy; + sky_scene_state.ubo.fog_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_env); + sky_scene_state.ubo.fog_density = RendererSceneRenderRD::get_singleton()->environment_get_fog_density(p_env); + sky_scene_state.ubo.fog_aerial_perspective = RendererSceneRenderRD::get_singleton()->environment_get_fog_aerial_perspective(p_env); + Color fog_color = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_color(p_env).srgb_to_linear(); + float fog_energy = RendererSceneRenderRD::get_singleton()->environment_get_fog_light_energy(p_env); sky_scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy; sky_scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy; sky_scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy; - sky_scene_state.ubo.fog_sun_scatter = p_env->fog_sun_scatter; + sky_scene_state.ubo.fog_sun_scatter = RendererSceneRenderRD::get_singleton()->environment_get_fog_sun_scatter(p_env); RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } -void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); ERR_FAIL_COND(!sky); - RID sky_material = sky_get_material(p_env->sky); + RID sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); SkyMaterialData *material = nullptr; @@ -1326,7 +1347,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM ERR_FAIL_COND(!shader_data); - float multiplier = p_env->bg_energy; + float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY; RS::SkyMode sky_mode = sky->mode; @@ -1371,9 +1392,9 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM Vector3(0, -1, 0) }; - CameraMatrix cm; + Projection cm; cm.set_perspective(90, 1, 0.01, 10.0); - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); cm = correction * cm; @@ -1466,23 +1487,23 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM } } -void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time) { +void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); ERR_FAIL_COND(p_view_count == 0); ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); SkyMaterialData *material = nullptr; RID sky_material; - RS::EnvironmentBG background = p_env->background; + RS::EnvironmentBG background = RendererSceneRenderRD::get_singleton()->environment_get_background(p_env); if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) { ERR_FAIL_COND(!sky); - sky_material = sky_get_material(p_env->sky); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); if (sky_material.is_valid()) { material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); @@ -1508,16 +1529,16 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont ERR_FAIL_COND(!shader_data); - Basis sky_transform = p_env->sky_orientation; + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = p_env->bg_energy; - float custom_fov = p_env->sky_custom_fov; + float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); + float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera - CameraMatrix camera; + Projection camera; uint32_t view_count = p_view_count; - const CameraMatrix *projections = p_projections; + const Projection *projections = p_projections; if (custom_fov) { // With custom fov we don't support stereo... @@ -1573,20 +1594,20 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont RD::get_singleton()->draw_list_end(); } -void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); ERR_FAIL_COND(p_view_count == 0); ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); ERR_FAIL_COND(!sky); SkyMaterialData *material = nullptr; RID sky_material; - sky_material = sky_get_material(p_env->sky); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); if (sky_material.is_valid()) { material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); @@ -1606,16 +1627,16 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u ERR_FAIL_COND(!shader_data); - Basis sky_transform = p_env->sky_orientation; + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = p_env->bg_energy; - float custom_fov = p_env->sky_custom_fov; + float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); + float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera - CameraMatrix camera; + Projection camera; uint32_t view_count = p_view_count; - const CameraMatrix *projections = p_projections; + const Projection *projections = p_projections; if (custom_fov) { // With custom fov we don't support stereo... @@ -1658,23 +1679,23 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u } } -void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - ERR_FAIL_COND(!p_env); + ERR_FAIL_COND(p_env.is_null()); ERR_FAIL_COND(p_view_count == 0); ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS); - Sky *sky = get_sky(p_env->sky); + Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); SkyMaterialData *material = nullptr; RID sky_material; - RS::EnvironmentBG background = p_env->background; + RS::EnvironmentBG background = RendererSceneRenderRD::get_singleton()->environment_get_background(p_env); if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) { ERR_FAIL_COND(!sky); - sky_material = sky_get_material(p_env->sky); + sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env)); if (sky_material.is_valid()) { material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::SHADER_TYPE_SKY)); @@ -1700,16 +1721,16 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme ERR_FAIL_COND(!shader_data); - Basis sky_transform = p_env->sky_orientation; + Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env); sky_transform.invert(); - float multiplier = p_env->bg_energy; - float custom_fov = p_env->sky_custom_fov; + float multiplier = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy(p_env); + float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env); // Camera - CameraMatrix camera; + Projection camera; uint32_t view_count = p_view_count; - const CameraMatrix *projections = p_projections; + const Projection *projections = p_projections; if (custom_fov) { // With custom fov we don't support stereo... @@ -1737,7 +1758,7 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme _render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin, p_luminance_multiplier); } -void RendererSceneSkyRD::invalidate_sky(Sky *p_sky) { +void SkyRD::invalidate_sky(Sky *p_sky) { if (!p_sky->dirty) { p_sky->dirty = true; p_sky->dirty_list = dirty_sky_list; @@ -1745,7 +1766,7 @@ void RendererSceneSkyRD::invalidate_sky(Sky *p_sky) { } } -void RendererSceneSkyRD::update_dirty_skys() { +void SkyRD::update_dirty_skys() { Sky *sky = dirty_sky_list; while (sky) { @@ -1849,26 +1870,26 @@ void RendererSceneSkyRD::update_dirty_skys() { dirty_sky_list = nullptr; } -RID RendererSceneSkyRD::sky_get_material(RID p_sky) const { +RID SkyRD::sky_get_material(RID p_sky) const { Sky *sky = get_sky(p_sky); ERR_FAIL_COND_V(!sky, RID()); return sky->material; } -RID RendererSceneSkyRD::allocate_sky_rid() { +RID SkyRD::allocate_sky_rid() { return sky_owner.allocate_rid(); } -void RendererSceneSkyRD::initialize_sky_rid(RID p_rid) { +void SkyRD::initialize_sky_rid(RID p_rid) { sky_owner.initialize_rid(p_rid, Sky()); } -RendererSceneSkyRD::Sky *RendererSceneSkyRD::get_sky(RID p_sky) const { +SkyRD::Sky *SkyRD::get_sky(RID p_sky) const { return sky_owner.get_or_null(p_sky); } -void RendererSceneSkyRD::free_sky(RID p_sky) { +void SkyRD::free_sky(RID p_sky) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); @@ -1876,7 +1897,7 @@ void RendererSceneSkyRD::free_sky(RID p_sky) { sky_owner.free(p_sky); } -void RendererSceneSkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { +void SkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); @@ -1885,7 +1906,7 @@ void RendererSceneSkyRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { } } -void RendererSceneSkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { +void SkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); @@ -1894,7 +1915,7 @@ void RendererSceneSkyRD::sky_set_mode(RID p_sky, RS::SkyMode p_mode) { } } -void RendererSceneSkyRD::sky_set_material(RID p_sky, RID p_material) { +void SkyRD::sky_set_material(RID p_sky, RID p_material) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND(!sky); @@ -1903,7 +1924,7 @@ void RendererSceneSkyRD::sky_set_material(RID p_sky, RID p_material) { } } -Ref<Image> RendererSceneSkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { +Ref<Image> SkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { Sky *sky = get_sky(p_sky); ERR_FAIL_COND_V(!sky, Ref<Image>()); @@ -1912,7 +1933,7 @@ Ref<Image> RendererSceneSkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool return sky->bake_panorama(p_energy, p_bake_irradiance ? roughness_layers : 0, p_size); } -RID RendererSceneSkyRD::sky_get_radiance_texture_rd(RID p_sky) const { +RID SkyRD::sky_get_radiance_texture_rd(RID p_sky) const { Sky *sky = get_sky(p_sky); ERR_FAIL_COND_V(!sky, RID()); diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/environment/sky.h index a8ee406abc..5402705918 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/environment/sky.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* renderer_scene_sky_rd.h */ +/* sky.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_SCENE_SKY_RD_H -#define RENDERING_SERVER_SCENE_SKY_RD_H +#ifndef SKY_RD_H +#define SKY_RD_H #include "core/templates/rid_owner.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" -#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" -#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/environment/sky.glsl.gen.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -44,7 +43,9 @@ // Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound class RendererSceneRenderRD; -class RendererSceneSkyRD { +namespace RendererRD { + +class SkyRD { public: enum SkySet { SKY_SET_UNIFORMS, @@ -128,6 +129,7 @@ private: bool uses_light = false; virtual void set_code(const String &p_Code); + virtual void set_path_hint(const String &p_hint); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; @@ -141,7 +143,7 @@ private: virtual ~SkyShaderData(); }; - void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier); + void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier); public: struct SkySceneState { @@ -289,16 +291,16 @@ public: RendererRD::MaterialData *_create_sky_material_func(SkyShaderData *p_shader); static RendererRD::MaterialData *_create_sky_material_funcs(RendererRD::ShaderData *p_shader); - RendererSceneSkyRD(); + SkyRD(); void init(); void set_texture_format(RD::DataFormat p_texture_format); - ~RendererSceneSkyRD(); + ~SkyRD(); - void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); - void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer - void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void setup(RID p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); + void update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer + void update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); void invalidate_sky(Sky *p_sky); void update_dirty_skys(); @@ -317,4 +319,6 @@ public: RID sky_get_radiance_texture_rd(RID p_sky) const; }; -#endif /* RENDERING_SERVER_SCENE_SKY_RD_H */ +} // namespace RendererRD + +#endif // SKY_RD_H diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 85652a041d..6f200220f0 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -66,6 +66,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular() } specular = RD::get_singleton()->texture_create(tf, RD::TextureView()); + if (view_count == 1) { + specular_views[0] = specular; + } else { + for (uint32_t v = 0; v < view_count; v++) { + specular_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), specular, v, 0); + } + } if (msaa == RS::VIEWPORT_MSAA_DISABLED) { { @@ -80,6 +87,14 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular() tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; specular_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView()); + if (view_count == 1) { + specular_msaa_views[0] = specular_msaa; + } else { + for (uint32_t v = 0; v < view_count; v++) { + specular_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), specular_msaa, v, 0); + } + } + { Vector<RID> fb; fb.push_back(specular_msaa); @@ -175,6 +190,8 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() { for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) { color_views[v] = RID(); depth_views[v] = RID(); + specular_views[v] = RID(); + specular_msaa_views[v] = RID(); color_msaa_views[v] = RID(); depth_msaa_views[v] = RID(); normal_roughness_views[v] = RID(); @@ -758,7 +775,7 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis void RenderForwardClustered::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) { uint32_t render_total = p_params->element_count; - uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count(); uint32_t render_from = p_thread * render_total / total_threads; uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads); _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to); @@ -770,9 +787,10 @@ void RenderForwardClustered::_render_list_with_threads(RenderListParameters *p_p if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->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, &RenderForwardClustered::_render_list_thread_function, p_params); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardClustered::_render_list_thread_function, p_params, thread_draw_lists.size(), -1, true, SNAME("ForwardClusteredRenderList")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); RD::get_singleton()->draw_list_end(p_params->barrier); } else { //single threaded @@ -783,12 +801,12 @@ void RenderForwardClustered::_render_list_with_threads(RenderListParameters *p_p } void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { - //CameraMatrix projection = p_render_data->cam_projection; + //Projection projection = p_render_data->cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down - CameraMatrix correction; + Projection correction; correction.set_depth_correction(p_flip_y); correction.add_jitter_offset(p_render_data->taa_jitter); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; //store camera into ubo RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); @@ -905,7 +923,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat scene_state.ubo.use_ambient_cubemap = false; } else { float energy = environment_get_ambient_light_energy(p_render_data->environment); - Color color = environment_get_ambient_light_color(p_render_data->environment); + Color color = environment_get_ambient_light(p_render_data->environment); color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; @@ -927,16 +945,16 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat scene_state.ubo.use_reflection_cubemap = false; } - scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment); - scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment); + scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment); + scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment); uint32_t ss_flags = 0; if (p_opaque_render_buffers) { - ss_flags |= environment_is_ssao_enabled(p_render_data->environment) ? 1 : 0; - ss_flags |= environment_is_ssil_enabled(p_render_data->environment) ? 2 : 0; + ss_flags |= environment_get_ssao_enabled(p_render_data->environment) ? 1 : 0; + ss_flags |= environment_get_ssil_enabled(p_render_data->environment) ? 2 : 0; } scene_state.ubo.ss_effects_flags = ss_flags; - scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment); + scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment); scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); @@ -978,10 +996,10 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat if (render_buffers->use_taa || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) { memcpy(&scene_state.prev_ubo, &scene_state.ubo, sizeof(SceneState::UBO)); - CameraMatrix prev_correction; + Projection prev_correction; prev_correction.set_depth_correction(true); prev_correction.add_jitter_offset(p_render_data->prev_taa_jitter); - CameraMatrix prev_projection = prev_correction * p_render_data->prev_cam_projection; + Projection prev_projection = prev_correction * p_render_data->prev_cam_projection; //store camera into ubo RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix); @@ -1392,7 +1410,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (p_render_data->render_buffers.is_valid()) { render_buffer = static_cast<RenderBufferDataForwardClustered *>(render_buffers_get_data(p_render_data->render_buffers)); } - RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment); static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8 }; //first of all, make a new render pass @@ -1417,7 +1434,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool using_sdfgi = false; bool using_voxelgi = false; bool reverse_cull = false; - bool using_ssil = p_render_data->environment.is_valid() && environment_is_ssil_enabled(p_render_data->environment); + bool using_ssil = p_render_data->environment.is_valid() && environment_get_ssil_enabled(p_render_data->environment); if (render_buffer) { screen_size.x = render_buffer->width; @@ -1431,21 +1448,21 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co using_voxelgi = true; } - if (!p_render_data->environment.is_valid() && using_voxelgi) { + if (p_render_data->environment.is_null() && using_voxelgi) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI; - } else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) { - if (environment_is_sdfgi_enabled(p_render_data->environment)) { + } else if (p_render_data->environment.is_valid() && (environment_get_ssr_enabled(p_render_data->environment) || environment_get_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) { + if (environment_get_sdfgi_enabled(p_render_data->environment)) { depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also voxelgi using_sdfgi = true; } else { depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; } - if (environment_is_ssr_enabled(p_render_data->environment)) { + if (environment_get_ssr_enabled(p_render_data->environment)) { using_separate_specular = true; using_ssr = true; color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR; } - } else if (p_render_data->environment.is_valid() && (environment_is_ssao_enabled(p_render_data->environment) || using_ssil || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) { + } else if (p_render_data->environment.is_valid() && (environment_get_ssao_enabled(p_render_data->environment) || using_ssil || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) { depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS; } @@ -1486,7 +1503,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { p_render_data->environment = RID(); //no environment on interiors - env = nullptr; } reverse_cull = true; // for some reason our views are inverted @@ -1538,7 +1554,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_is_fog_enabled(p_render_data->environment)) { + if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -1548,7 +1564,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co clear_color.r *= bg_energy; clear_color.g *= bg_energy; clear_color.b *= bg_energy; - if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_is_fog_enabled(p_render_data->environment)) { + if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -1571,18 +1587,18 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - CameraMatrix projection = p_render_data->cam_projection; + Projection projection = p_render_data->cam_projection; if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); projection = correction * p_render_data->cam_projection; } - sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); - RID sky_rid = env->sky; + RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update(env, projection, p_render_data->cam_transform, time); + sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -1598,7 +1614,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES; bool depth_pre_pass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")) && depth_framebuffer.is_valid(); - bool using_ssao = depth_pre_pass && p_render_data->render_buffers.is_valid() && p_render_data->environment.is_valid() && environment_is_ssao_enabled(p_render_data->environment); + bool using_ssao = depth_pre_pass && p_render_data->render_buffers.is_valid() && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment); bool continue_depth = false; if (depth_pre_pass) { //depth pre pass @@ -1702,9 +1718,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only); - CameraMatrix dc; + Projection dc; dc.set_depth_correction(true); - CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); + Projection cm = (dc * p_render_data->cam_projection) * Projection(p_render_data->cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); RD::get_singleton()->draw_command_begin_label("Debug VoxelGIs"); for (int i = 0; i < (int)p_render_data->voxel_gi_instances->size(); i++) { @@ -1719,11 +1735,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only); - CameraMatrix dc; + Projection dc; dc.set_depth_correction(true); - CameraMatrix cms[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection cms[RendererSceneRender::MAX_RENDER_VIEWS]; for (uint32_t v = 0; v < p_render_data->view_count; v++) { - cms[v] = (dc * p_render_data->view_projection[v]) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); + cms[v] = (dc * p_render_data->view_projection[v]) * Projection(p_render_data->cam_transform.affine_inverse()); } _debug_sdfgi_probes(p_render_data->render_buffers, color_only_framebuffer, p_render_data->view_count, cms, will_continue_color, will_continue_depth); } @@ -1734,12 +1750,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Draw Sky"); if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); - CameraMatrix projection = correction * p_render_data->cam_projection; - sky.draw(env, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time); + Projection projection = correction * p_render_data->cam_projection; + sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time); } else { - sky.draw(env, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); + sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); } RD::get_singleton()->draw_command_end_label(); } @@ -1749,9 +1765,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co for (uint32_t v = 0; v < render_buffer->view_count; v++) { RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa_views[v], render_buffer->color_views[v]); } - // TODO mame this do multiview if (using_separate_specular) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular); + for (uint32_t v = 0; v < render_buffer->view_count; v++) { + RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa_views[v], render_buffer->specular_views[v]); + } } } @@ -1772,12 +1789,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (using_ssr) { RENDER_TIMESTAMP("Screen-Space Reflections"); RD::get_singleton()->draw_command_begin_label("Process Screen-Space Reflections"); - _process_ssr(p_render_data->render_buffers, color_only_framebuffer, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED); + _process_ssr(p_render_data->render_buffers, color_only_framebuffer, render_buffer->normal_roughness_views, render_buffer->specular, render_buffer->specular_views, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->view_projection, p_render_data->view_eye_offset, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED); RD::get_singleton()->draw_command_end_label(); } else { //just mix specular back RENDER_TIMESTAMP("Merge Specular"); - RendererCompositorRD::singleton->get_effects()->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID()); + copy_effects->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID(), p_render_data->view_count); } } @@ -1854,7 +1871,7 @@ void RenderForwardClustered::_render_shadow_begin() { scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &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_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &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_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -1944,7 +1961,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1983,7 +2000,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); @@ -2032,7 +2049,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); RD::get_singleton()->draw_command_begin_label("Render UV2"); @@ -2102,7 +2119,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_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) { +void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &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"); @@ -2364,7 +2381,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 14; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -2773,24 +2790,23 @@ RID RenderForwardClustered::_render_buffers_get_velocity_texture(RID p_render_bu RenderForwardClustered *RenderForwardClustered::singleton = nullptr; -void RenderForwardClustered::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - if (ginstance->dirty_list_element.in_list()) { +void RenderForwardClustered::GeometryInstanceForwardClustered::_mark_dirty() { + if (dirty_list_element.in_list()) { return; } //clear surface caches - GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches; + GeometryInstanceSurfaceDataCache *surf = surface_caches; while (surf) { GeometryInstanceSurfaceDataCache *next = surf->next; - geometry_instance_surface_alloc.free(surf); + RenderForwardClustered::get_singleton()->geometry_instance_surface_alloc.free(surf); surf = next; } - ginstance->surface_caches = nullptr; + surface_caches = nullptr; - geometry_instance_dirty_list.add(&ginstance->dirty_list_element); + RenderForwardClustered::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element); } void RenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { @@ -2958,7 +2974,7 @@ void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForw } } -void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geometry_instance) { +void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); @@ -3117,7 +3133,7 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D case Dependency::DEPENDENCY_CHANGED_PARTICLES: case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { - static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata); @@ -3131,10 +3147,10 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D } } void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { - static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } -RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) { +RenderGeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) { RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); @@ -3147,155 +3163,47 @@ RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed; ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted; - _geometry_instance_mark_dirty(ginstance); + ginstance->_mark_dirty(); return ginstance; } -void RenderForwardClustered::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->skeleton = p_skeleton; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_override = p_override; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_overlay = p_overlay; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->surface_materials = p_materials; - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} -void RenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->mesh_instance = p_mesh_instance; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) { uint64_t frame = RSG::rasterizer->get_frame_number(); - if (frame != ginstance->prev_transform_change_frame) { - ginstance->prev_transform = ginstance->transform; - ginstance->prev_transform_change_frame = frame; - ginstance->prev_transform_dirty = true; + if (frame != prev_transform_change_frame) { + prev_transform = transform; + prev_transform_change_frame = frame; + prev_transform_dirty = true; } - ginstance->transform = p_transform; - ginstance->mirror = p_transform.basis.determinant() < 0; - ginstance->data->aabb = p_aabb; - ginstance->transformed_aabb = p_transformed_aabb; - - Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); - // handle non uniform scale here - - float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); - - ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; - ginstance->lod_model_scale = max_scale; -} -void RenderForwardClustered::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lod_bias = p_lod_bias; -} -void RenderForwardClustered::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->fade_near = p_enable_near; - ginstance->fade_near_begin = p_near_begin; - ginstance->fade_near_end = p_near_end; - ginstance->fade_far = p_enable_far; - ginstance->fade_far_begin = p_far_begin; - ginstance->fade_far_end = p_far_end; + RenderGeometryInstanceBase::set_transform(p_transform, p_aabb, p_transformed_aabbb); } -void RenderForwardClustered::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->parent_fade_alpha = p_alpha; -} +void RenderForwardClustered::GeometryInstanceForwardClustered::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { + lightmap_instance = p_lightmap_instance; + lightmap_uv_scale = p_lightmap_uv_scale; + lightmap_slice_index = p_lightmap_slice_index; -void RenderForwardClustered::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->force_alpha = CLAMP(1.0 - p_transparency, 0, 1); + _mark_dirty(); } -void RenderForwardClustered::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_baked_light = p_enable; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_dynamic_gi = p_enable; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lightmap_instance = p_lightmap_instance; - ginstance->lightmap_uv_scale = p_lightmap_uv_scale; - ginstance->lightmap_slice_index = p_lightmap_slice_index; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_lightmap_capture(const Color *p_sh9) { if (p_sh9) { - if (ginstance->lightmap_sh == nullptr) { - ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc(); + if (lightmap_sh == nullptr) { + lightmap_sh = RenderForwardClustered::get_singleton()->geometry_instance_lightmap_sh.alloc(); } - memcpy(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9); + memcpy(lightmap_sh->sh, p_sh9, sizeof(Color) * 9); } else { - if (ginstance->lightmap_sh != nullptr) { - geometry_instance_lightmap_sh.free(ginstance->lightmap_sh); - ginstance->lightmap_sh = nullptr; + if (lightmap_sh != nullptr) { + RenderForwardClustered::get_singleton()->geometry_instance_lightmap_sh.free(lightmap_sh); + lightmap_sh = nullptr; } } - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->shader_parameters_offset = p_offset; - _geometry_instance_mark_dirty(ginstance); -} -void RenderForwardClustered::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->data->cast_double_sided_shadows = p_enable; - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardClustered::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->layer_mask = p_layer_mask; + _mark_dirty(); } -void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry_instance) { +void RenderForwardClustered::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); if (ginstance->lightmap_sh != nullptr) { @@ -3314,47 +3222,25 @@ void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry uint32_t RenderForwardClustered::geometry_instance_get_pair_mask() { return (1 << RS::INSTANCE_VOXEL_GI); } -void RenderForwardClustered::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { -} -void RenderForwardClustered::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { -} -void RenderForwardClustered::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { -} - -Transform3D RenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance); - ERR_FAIL_COND_V(!ginstance, Transform3D()); - return ginstance->transform; -} - -AABB RenderForwardClustered::geometry_instance_get_aabb(GeometryInstance *p_instance) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance); - ERR_FAIL_COND_V(!ginstance, AABB()); - return ginstance->data->aabb; -} -void RenderForwardClustered::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { if (p_voxel_gi_instance_count > 0) { - ginstance->voxel_gi_instances[0] = p_voxel_gi_instances[0]; + voxel_gi_instances[0] = p_voxel_gi_instances[0]; } else { - ginstance->voxel_gi_instances[0] = RID(); + voxel_gi_instances[0] = RID(); } if (p_voxel_gi_instance_count > 1) { - ginstance->voxel_gi_instances[1] = p_voxel_gi_instances[1]; + voxel_gi_instances[1] = p_voxel_gi_instances[1]; } else { - ginstance->voxel_gi_instances[1] = RID(); + voxel_gi_instances[1] = RID(); } } -void RenderForwardClustered::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { - GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->using_projectors = p_projector; - ginstance->using_softshadows = p_softshadow; - _geometry_instance_mark_dirty(ginstance); +void RenderForwardClustered::GeometryInstanceForwardClustered::set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) { + using_projectors = p_projector; + using_softshadows = p_softshadow; + _mark_dirty(); } void RenderForwardClustered::_update_shader_quality_settings() { diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index ff712a20a1..7e71406af8 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H -#define RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H +#ifndef RENDER_FORWARD_CLUSTERED_H +#define RENDER_FORWARD_CLUSTERED_H #include "core/templates/paged_allocator.h" #include "servers/rendering/renderer_rd/effects/resolve.h" @@ -117,6 +117,8 @@ class RenderForwardClustered : public RendererSceneRenderRD { uint32_t view_count = 1; RID color_views[RendererSceneRender::MAX_RENDER_VIEWS]; // we should rewrite this so we get access to the existing views in our renderer, something we can address when we reorg this RID depth_views[RendererSceneRender::MAX_RENDER_VIEWS]; // we should rewrite this so we get access to the existing views in our renderer, something we can address when we reorg this + RID specular_views[RendererSceneRender::MAX_RENDER_VIEWS]; + RID specular_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS]; RID color_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS]; RID depth_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS]; RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS]; @@ -425,7 +427,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { HashMap<Size2i, RID> sdfgi_framebuffer_size_cache; struct GeometryInstanceData; - struct GeometryInstanceForwardClustered; + class GeometryInstanceForwardClustered; struct GeometryInstanceLightmapSH { Color sh[9]; @@ -485,73 +487,48 @@ class RenderForwardClustered : public RendererSceneRenderRD { GeometryInstanceForwardClustered *owner = nullptr; }; - struct GeometryInstanceForwardClustered : public GeometryInstance { + class GeometryInstanceForwardClustered : public RenderGeometryInstanceBase { + public: + // lightmap + RID lightmap_instance; + Rect2 lightmap_uv_scale; + uint32_t lightmap_slice_index; + GeometryInstanceLightmapSH *lightmap_sh = nullptr; + //used during rendering - bool mirror = false; - bool non_uniform_scale = false; - float lod_bias = 0.0; - float lod_model_scale = 1.0; - AABB transformed_aabb; //needed for LOD - float depth = 0; + 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; uint32_t trail_steps = 1; - RID mesh_instance; bool can_sdfgi = false; bool using_projectors = false; bool using_softshadows = false; - bool fade_near = false; - float fade_near_begin = 0; - float fade_near_end = 0; - bool fade_far = false; - float fade_far_begin = 0; - float fade_far_end = 0; - float force_alpha = 1.0; - float parent_fade_alpha = 1.0; //used during setup - uint32_t base_flags = 0; uint64_t prev_transform_change_frame = 0xFFFFFFFF; bool prev_transform_dirty = true; - Transform3D transform; Transform3D prev_transform; RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE]; - RID lightmap_instance; - GeometryInstanceLightmapSH *lightmap_sh = nullptr; GeometryInstanceSurfaceDataCache *surface_caches = nullptr; SelfList<GeometryInstanceForwardClustered> dirty_list_element; - struct Data { - //data used less often goes into regular heap - RID base; - RS::InstanceType base_type; + GeometryInstanceForwardClustered() : + dirty_list_element(this) {} - RID skeleton; - Vector<RID> surface_materials; - RID material_override; - RID material_overlay; - AABB aabb; + virtual void _mark_dirty() override; - bool use_dynamic_gi = false; - bool use_baked_light = true; - bool cast_double_sided_shadows = false; - bool mirror = false; - bool dirty_dependencies = false; + virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) override; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; + virtual void set_lightmap_capture(const Color *p_sh9) override; - DependencyTracker dependency_tracker; - }; + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override {} + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {} + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {} + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - Data *data = nullptr; - - GeometryInstanceForwardClustered() : - dirty_list_element(this) {} + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override; }; static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker); @@ -566,8 +543,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh); void _geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); - void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); - void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance); void _update_dirty_geometry_instances(); /* Render List */ @@ -638,52 +614,27 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &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_mesh_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, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &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_mesh_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, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - 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) override; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override; public: + static RenderForwardClustered *get_singleton() { return singleton; } + _FORCE_INLINE_ virtual void update_uniform_sets() override { base_uniform_set_updated = true; _update_render_base_uniform_set(); } - virtual GeometryInstance *geometry_instance_create(RID p_base) override; - virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override; - virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override; - virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override; - virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override; - virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override; - virtual void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; - virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override; - virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override; - virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; - virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override; - virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override; - virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override; - - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) override; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) override; - - virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) override; + virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override; + virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; virtual uint32_t geometry_instance_get_pair_mask() override; - virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override; - virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; - virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; - virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - - virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; virtual bool free(RID p_rid) override; @@ -691,4 +642,5 @@ public: ~RenderForwardClustered(); }; } // namespace RendererSceneRenderImplementation -#endif // !RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H + +#endif // RENDER_FORWARD_CLUSTERED_H diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 1951bfe915..c84a4469ae 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -37,6 +37,10 @@ using namespace RendererSceneRenderImplementation; +void SceneShaderForwardClustered::ShaderData::set_path_hint(const String &p_path) { + path = p_path; +} + void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { //compile @@ -403,7 +407,22 @@ void SceneShaderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); @@ -663,7 +682,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; - actions.renames["FOG"] = "custom_fog"; + actions.renames["FOG"] = "fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; actions.renames["BONE_INDICES"] = "bone_attrib"; @@ -769,7 +788,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; actions.instance_uniform_index_variable = "instances.data[instance_index_interp].instance_uniforms_ofs"; compiler.initialize(actions); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 1cfe723174..fb001d6933 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RSSR_SCENE_SHADER_FC_H -#define RSSR_SCENE_SHADER_FC_H +#ifndef SCENE_SHADER_FORWARD_CLUSTERED_H +#define SCENE_SHADER_FORWARD_CLUSTERED_H #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h" @@ -180,6 +180,7 @@ public: uint32_t index = 0; virtual void set_code(const String &p_Code); + virtual void set_path_hint(const String &p_path); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; @@ -251,4 +252,5 @@ public: }; } // namespace RendererSceneRenderImplementation -#endif // !RSSR_SCENE_SHADER_FM_H + +#endif // SCENE_SHADER_FORWARD_CLUSTERED_H diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 966621c93e..a179688487 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -497,7 +497,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (p_render_data->render_buffers.is_valid()) { render_buffer = static_cast<RenderBufferDataForwardMobile *>(render_buffers_get_data(p_render_data->render_buffers)); } - RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment); RENDER_TIMESTAMP("Setup 3D Scene"); @@ -540,7 +539,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (render_buffer->color_fbs[FB_CONFIG_FOUR_SUBPASSES].is_null()) { // can't do blit subpass using_subpass_post_process = false; - } else if (env && (env->glow_enabled || env->auto_exposure || camera_effects_uses_dof(p_render_data->camera_effects))) { + } else if (p_render_data->environment.is_valid() && (environment_get_glow_enabled(p_render_data->environment) || environment_get_auto_exposure(p_render_data->environment) || camera_effects_uses_dof(p_render_data->camera_effects))) { // can't do blit subpass using_subpass_post_process = false; } @@ -570,7 +569,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) { p_render_data->environment = RID(); //no environment on interiors - env = nullptr; } reverse_cull = true; @@ -612,7 +610,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color clear_color.g *= bg_energy; clear_color.b *= bg_energy; /* - if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -624,7 +622,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color clear_color.g *= bg_energy; clear_color.b *= bg_energy; /* - if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) { + if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_get_fog_enabled(p_render_data->environment)) { draw_sky_fog_only = true; RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear())); } @@ -648,18 +646,18 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - CameraMatrix projection = p_render_data->cam_projection; + Projection projection = p_render_data->cam_projection; if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); projection = correction * p_render_data->cam_projection; } - sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); - RID sky_rid = env->sky; + RID sky_rid = environment_get_sky(p_render_data->environment); if (sky_rid.is_valid()) { - sky.update(env, projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); + sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); } else { // do not try to draw sky if invalid @@ -680,12 +678,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_begin_label("Setup Sky Resolution Buffers"); if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); - CameraMatrix projection = correction * p_render_data->cam_projection; - sky.update_res_buffers(env, 1, &projection, p_render_data->cam_transform, time); + Projection projection = correction * p_render_data->cam_projection; + sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->cam_transform, time); } else { - sky.update_res_buffers(env, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); + sky.update_res_buffers(p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); } RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers @@ -707,7 +705,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS; } - if (!is_environment(p_render_data->environment) || environment_is_fog_enabled(p_render_data->environment)) { + if (!is_environment(p_render_data->environment) || environment_get_fog_enabled(p_render_data->environment)) { spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG; } } @@ -758,9 +756,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count()); RD::get_singleton()->draw_list_begin_split(framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); - RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardMobile::_render_list_thread_function, &render_list_params); + + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, &render_list_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderList")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + } else { //single threaded RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); @@ -776,12 +777,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::DrawListID draw_list = RD::get_singleton()->draw_list_switch_to_next_pass(); if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); - CameraMatrix projection = correction * p_render_data->cam_projection; - sky.draw(draw_list, env, framebuffer, 1, &projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); + Projection projection = correction * p_render_data->cam_projection; + sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); } else { - sky.draw(draw_list, env, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); + sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); } RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass @@ -822,10 +823,12 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count()); RD::get_singleton()->draw_list_switch_to_next_pass_split(thread_draw_lists.size(), thread_draw_lists.ptr()); render_list_params.subpass = RD::get_singleton()->draw_list_get_current_pass(); - RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardMobile::_render_list_thread_function, &render_list_params); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, &render_list_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + } else { //single threaded RD::DrawListID draw_list = RD::get_singleton()->draw_list_switch_to_next_pass(); @@ -859,9 +862,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->get_thread_count()); RD::get_singleton()->draw_list_begin_split(framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), 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); - RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardMobile::_render_list_thread_function, &render_list_params); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, &render_list_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_ALL); } else { //single threaded @@ -900,7 +905,7 @@ void RenderForwardMobile::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &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_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &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_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -994,7 +999,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) { /* */ -void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); @@ -1040,7 +1045,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c RD::get_singleton()->draw_command_end_label(); } -void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering UV2"); RD::get_singleton()->draw_command_begin_label("Render UV2"); @@ -1107,11 +1112,11 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in RD::get_singleton()->draw_command_end_label(); } -void RenderForwardMobile::_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) { +void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) { // we don't do GI in low end.. } -void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1325,7 +1330,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 14; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -1543,11 +1548,11 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, // This populates our UBO with main scene data that is pushed into set 1 - //CameraMatrix projection = p_render_data->cam_projection; + //Projection projection = p_render_data->cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down - CameraMatrix correction; + Projection correction; correction.set_depth_correction(p_flip_y); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; //store camera into ubo RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); @@ -1656,7 +1661,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, scene_state.ubo.use_ambient_cubemap = false; } else { float energy = environment_get_ambient_light_energy(p_render_data->environment); - Color color = environment_get_ambient_light_color(p_render_data->environment); + Color color = environment_get_ambient_light(p_render_data->environment); color = color.srgb_to_linear(); scene_state.ubo.ambient_light_color_energy[0] = color.r * energy; scene_state.ubo.ambient_light_color_energy[1] = color.g * energy; @@ -1678,11 +1683,11 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, scene_state.ubo.use_reflection_cubemap = false; } - scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_render_data->environment); - scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment); - scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment); + scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_get_ssao_enabled(p_render_data->environment); + scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment); + scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment); - scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment); + scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment); scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment); scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment); scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment); @@ -1771,7 +1776,7 @@ void RenderForwardMobile::_render_list(RenderingDevice::DrawListID p_draw_list, void RenderForwardMobile::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) { uint32_t render_total = p_params->element_count; - uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count(); uint32_t render_from = p_thread * render_total / total_threads; uint32_t render_to = (p_thread + 1 == total_threads) ? render_total : ((p_thread + 1) * render_total / total_threads); _render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to); @@ -1783,9 +1788,11 @@ void RenderForwardMobile::_render_list_with_threads(RenderListParameters *p_para if ((uint32_t)p_params->element_count > render_list_thread_threshold && false) { // secondary command buffers need more testing at this time //multi threaded - thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + thread_draw_lists.resize(WorkerThreadPool::get_singleton()->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, &RenderForwardMobile::_render_list_thread_function, p_params); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RenderForwardMobile::_render_list_thread_function, p_params, thread_draw_lists.size(), -1, true, SNAME("ForwardMobileRenderSubpass")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + RD::get_singleton()->draw_list_end(p_params->barrier); } else { //single threaded @@ -2047,7 +2054,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr /* Geometry instance */ -RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) { +RenderGeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) { RS::InstanceType type = RSG::utilities->get_base_type(p_base); ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr); @@ -2057,165 +2064,36 @@ RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_cr ginstance->data->base = p_base; ginstance->data->base_type = type; - _geometry_instance_mark_dirty(ginstance); + ginstance->_mark_dirty(); return ginstance; } -void RenderForwardMobile::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->skeleton = p_skeleton; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_override = p_override; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->material_overlay = p_overlay; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->surface_materials = p_materials; - - _geometry_instance_mark_dirty(ginstance); - ginstance->data->dirty_dependencies = true; -} - -void RenderForwardMobile::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->mesh_instance = p_mesh_instance; - - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->transform = p_transform; - ginstance->mirror = p_transform.basis.determinant() < 0; - ginstance->data->aabb = p_aabb; - ginstance->transformed_aabb = p_transformed_aabb; - - Vector3 model_scale_vec = p_transform.basis.get_scale_abs(); - // handle non uniform scale here - - float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z)); - float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z)); - ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9; - - ginstance->lod_model_scale = max_scale; -} - -void RenderForwardMobile::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->layer_mask = p_layer_mask; -} - -void RenderForwardMobile::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lod_bias = p_lod_bias; -} - -void RenderForwardMobile::geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) { -} +void RenderForwardMobile::GeometryInstanceForwardMobile::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { + lightmap_instance = p_lightmap_instance; + lightmap_uv_scale = p_lightmap_uv_scale; + lightmap_slice_index = p_lightmap_slice_index; -void RenderForwardMobile::geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) { + _mark_dirty(); } -void RenderForwardMobile::geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) { -} - -void RenderForwardMobile::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->data->use_baked_light = p_enable; - - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) { - // !BAS! do we support this in mobile? - // GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - // ERR_FAIL_COND(!ginstance); - // ginstance->data->use_dynamic_gi = p_enable; - // _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->lightmap_instance = p_lightmap_instance; - ginstance->lightmap_uv_scale = p_lightmap_uv_scale; - ginstance->lightmap_slice_index = p_lightmap_slice_index; - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); +void RenderForwardMobile::GeometryInstanceForwardMobile::set_lightmap_capture(const Color *p_sh9) { if (p_sh9) { - if (ginstance->lightmap_sh == nullptr) { - ginstance->lightmap_sh = geometry_instance_lightmap_sh.alloc(); + if (lightmap_sh == nullptr) { + lightmap_sh = RenderForwardMobile::get_singleton()->geometry_instance_lightmap_sh.alloc(); } - memcpy(ginstance->lightmap_sh->sh, p_sh9, sizeof(Color) * 9); + memcpy(lightmap_sh->sh, p_sh9, sizeof(Color) * 9); } else { - if (ginstance->lightmap_sh != nullptr) { - geometry_instance_lightmap_sh.free(ginstance->lightmap_sh); - ginstance->lightmap_sh = nullptr; + if (lightmap_sh != nullptr) { + RenderForwardMobile::get_singleton()->geometry_instance_lightmap_sh.free(lightmap_sh); + lightmap_sh = nullptr; } } - _geometry_instance_mark_dirty(ginstance); + _mark_dirty(); } -void RenderForwardMobile::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - ginstance->shader_parameters_offset = p_offset; - _geometry_instance_mark_dirty(ginstance); -} - -void RenderForwardMobile::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->data->cast_double_sided_shadows = p_enable; - _geometry_instance_mark_dirty(ginstance); -} - -Transform3D RenderForwardMobile::geometry_instance_get_transform(GeometryInstance *p_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_instance); - ERR_FAIL_COND_V(!ginstance, Transform3D()); - return ginstance->transform; -} - -AABB RenderForwardMobile::geometry_instance_get_aabb(GeometryInstance *p_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_instance); - ERR_FAIL_COND_V(!ginstance, AABB()); - return ginstance->data->aabb; -} - -void RenderForwardMobile::geometry_instance_free(GeometryInstance *p_geometry_instance) { +void RenderForwardMobile::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); ERR_FAIL_COND(!ginstance); if (ginstance->lightmap_sh != nullptr) { @@ -2235,26 +2113,23 @@ uint32_t RenderForwardMobile::geometry_instance_get_pair_mask() { return ((1 << RS::INSTANCE_LIGHT) + (1 << RS::INSTANCE_REFLECTION_PROBE) + (1 << RS::INSTANCE_DECAL)); } -void RenderForwardMobile::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->omni_light_count = 0; - ginstance->spot_light_count = 0; +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) { + omni_light_count = 0; + spot_light_count = 0; for (uint32_t i = 0; i < p_light_instance_count; i++) { - RS::LightType type = light_instance_get_type(p_light_instances[i]); + RS::LightType type = RenderForwardMobile::get_singleton()->light_instance_get_type(p_light_instances[i]); switch (type) { case RS::LIGHT_OMNI: { - if (ginstance->omni_light_count < (uint32_t)MAX_RDL_CULL) { - ginstance->omni_lights[ginstance->omni_light_count] = light_instance_get_forward_id(p_light_instances[i]); - ginstance->omni_light_count++; + if (omni_light_count < (uint32_t)MAX_RDL_CULL) { + omni_lights[omni_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]); + omni_light_count++; } } break; case RS::LIGHT_SPOT: { - if (ginstance->spot_light_count < (uint32_t)MAX_RDL_CULL) { - ginstance->spot_lights[ginstance->spot_light_count] = light_instance_get_forward_id(p_light_instances[i]); - ginstance->spot_light_count++; + if (spot_light_count < (uint32_t)MAX_RDL_CULL) { + spot_lights[spot_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]); + spot_light_count++; } } break; default: @@ -2263,56 +2138,42 @@ void RenderForwardMobile::geometry_instance_pair_light_instances(GeometryInstanc } } -void RenderForwardMobile::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL; - for (uint32_t i = 0; i < ginstance->reflection_probe_count; i++) { - ginstance->reflection_probes[i] = reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]); +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) { + reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL; + for (uint32_t i = 0; i < reflection_probe_count; i++) { + reflection_probes[i] = RenderForwardMobile::get_singleton()->reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]); } } -void RenderForwardMobile::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL; - for (uint32_t i = 0; i < ginstance->decals_count; i++) { - ginstance->decals[i] = decal_instance_get_forward_id(p_decal_instances[i]); +void RenderForwardMobile::GeometryInstanceForwardMobile::pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) { + decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL; + for (uint32_t i = 0; i < decals_count; i++) { + decals[i] = RenderForwardMobile::get_singleton()->decal_instance_get_forward_id(p_decal_instances[i]); } } -void RenderForwardMobile::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) { - // We do not have this here! +void RenderForwardMobile::GeometryInstanceForwardMobile::set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) { + use_projector = p_projector; + use_soft_shadow = p_softshadow; } -void RenderForwardMobile::geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - ERR_FAIL_COND(!ginstance); - - ginstance->use_projector = p_projector; - ginstance->use_soft_shadow = p_softshadow; -} - -void RenderForwardMobile::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) { - GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); - if (ginstance->dirty_list_element.in_list()) { +void RenderForwardMobile::GeometryInstanceForwardMobile::_mark_dirty() { + if (dirty_list_element.in_list()) { return; } //clear surface caches - GeometryInstanceSurfaceDataCache *surf = ginstance->surface_caches; + GeometryInstanceSurfaceDataCache *surf = surface_caches; while (surf) { GeometryInstanceSurfaceDataCache *next = surf->next; - geometry_instance_surface_alloc.free(surf); + RenderForwardMobile::get_singleton()->geometry_instance_surface_alloc.free(surf); surf = next; } - ginstance->surface_caches = nullptr; + surface_caches = nullptr; - geometry_instance_dirty_list.add(&ginstance->dirty_list_element); + RenderForwardMobile::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element); } void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) { @@ -2478,7 +2339,7 @@ void RenderForwardMobile::_geometry_instance_add_surface(GeometryInstanceForward } } -void RenderForwardMobile::_geometry_instance_update(GeometryInstance *p_geometry_instance) { +void RenderForwardMobile::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton(); RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance); @@ -2632,7 +2493,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe case Dependency::DEPENDENCY_CHANGED_PARTICLES: case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { - static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata); @@ -2646,7 +2507,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe } } void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { - static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata)); + static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); } /* misc */ diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index bf4a52d466..4a7112eb81 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_MOBILE_H -#define RENDERING_SERVER_SCENE_RENDER_FORWARD_MOBILE_H +#ifndef RENDER_FORWARD_MOBILE_H +#define RENDER_FORWARD_MOBILE_H #include "core/templates/paged_allocator.h" #include "servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h" @@ -160,7 +160,7 @@ protected: // PASS_MODE_SDF, }; - struct GeometryInstanceForwardMobile; + class GeometryInstanceForwardMobile; struct GeometryInstanceSurfaceDataCache; struct RenderElementInfo; @@ -212,14 +212,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &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_mesh_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, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &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_mesh_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, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - 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) override; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override; uint64_t lightmap_texture_array_version = 0xFFFFFFFF; @@ -518,14 +518,8 @@ protected: GeometryInstanceForwardMobile *owner = nullptr; }; - // !BAS! GeometryInstanceForwardClustered and GeometryInstanceForwardMobile will likely have a lot of overlap - // may need to think about making this its own class like GeometryInstanceRD? - - struct GeometryInstanceForwardMobile : public GeometryInstance { - // setup - uint32_t base_flags = 0; - uint32_t flags_cache = 0; - + class GeometryInstanceForwardMobile : public RenderGeometryInstanceBase { + public: // this structure maps to our push constant in our shader and is populated right before our draw call struct PushConstant { float transform[16]; @@ -543,28 +537,18 @@ protected: // PushConstant push_constant; // we populate this from our instance data //used during rendering - uint32_t layer_mask = 1; RID transforms_uniform_set; - float depth = 0; - bool mirror = false; bool use_projector = false; bool use_soft_shadow = false; - Transform3D transform; bool store_transform_cache = true; // if true we copy our transform into our PushConstant, if false we use our transforms UBO and clear our PushConstants transform - bool non_uniform_scale = false; - AABB transformed_aabb; //needed for LOD - float lod_bias = 0.0; - float lod_model_scale = 1.0; - int32_t shader_parameters_offset = -1; uint32_t instance_count = 0; uint32_t trail_steps = 1; - RID mesh_instance; // lightmap uint32_t gi_offset_cache = 0; // !BAS! Should rename this to lightmap_offset_cache, in forward clustered this was shared between gi and lightmap - uint32_t lightmap_slice_index; - Rect2 lightmap_uv_scale; RID lightmap_instance; + Rect2 lightmap_uv_scale; + uint32_t lightmap_slice_index; GeometryInstanceLightmapSH *lightmap_sh = nullptr; // culled light info @@ -582,30 +566,20 @@ protected: // do we use this? SelfList<GeometryInstanceForwardMobile> dirty_list_element; - struct Data { - //data used less often goes into regular heap - RID base; - RS::InstanceType base_type; - - RID skeleton; - Vector<RID> surface_materials; - RID material_override; - RID material_overlay; - AABB aabb; - - bool use_baked_light = true; - bool cast_double_sided_shadows = false; - // bool mirror = false; // !BAS! Does not seem used, we already have this in the main struct + GeometryInstanceForwardMobile() : + dirty_list_element(this) {} - bool dirty_dependencies = false; + virtual void _mark_dirty() override; - DependencyTracker dependency_tracker; - }; + virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; + virtual void set_lightmap_capture(const Color *p_sh9) override; - Data *data = nullptr; + virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override; + virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; + virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override; + virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {} - GeometryInstanceForwardMobile() : - dirty_list_element(this) {} + virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override; }; _FORCE_INLINE_ void _fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance); @@ -613,6 +587,8 @@ protected: void _update_shader_quality_settings() override; public: + static RenderForwardMobile *get_singleton() { return singleton; } + virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth) override; static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker); @@ -627,41 +603,13 @@ public: void _geometry_instance_add_surface_with_material(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh); void _geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, RID p_mat_src, RID p_mesh); void _geometry_instance_add_surface(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, RID p_material, RID p_mesh); - void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance); - void _geometry_instance_update(GeometryInstance *p_geometry_instance); + void _geometry_instance_update(RenderGeometryInstance *p_geometry_instance); void _update_dirty_geometry_instances(); - virtual GeometryInstance *geometry_instance_create(RID p_base) override; - virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override; - virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override; - virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_overlay) override; - virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override; - virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override; - virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override; - virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override; - virtual void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override; - virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) override; - virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) override; - virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override; - virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override; - virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override; - virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override; - virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override; - - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) override; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) override; - - virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) override; + virtual RenderGeometryInstance *geometry_instance_create(RID p_base) override; + virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override; virtual uint32_t geometry_instance_get_pair_mask() override; - virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override; - virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override; - virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override; - virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override; - - virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) override; virtual bool free(RID p_rid) override; @@ -674,4 +622,5 @@ public: ~RenderForwardMobile(); }; } // namespace RendererSceneRenderImplementation -#endif // !RENDERING_SERVER_SCENE_RENDER_FORWARD_MOBILE_H + +#endif // RENDER_FORWARD_MOBILE_H diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index dd00dc2bf9..c6eac298e7 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -39,6 +39,10 @@ using namespace RendererSceneRenderImplementation; /* ShaderData */ +void SceneShaderForwardMobile::ShaderData::set_path_hint(const String &p_path) { + path = p_path; +} + void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { //compile @@ -360,7 +364,22 @@ void SceneShaderForwardMobile::ShaderData::get_param_list(List<PropertyInfo> *p_ } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); @@ -565,7 +584,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; actions.renames["DEPTH"] = "gl_FragDepth"; actions.renames["OUTPUT_IS_SRGB"] = "true"; - actions.renames["FOG"] = "custom_fog"; + actions.renames["FOG"] = "fog"; actions.renames["RADIANCE"] = "custom_radiance"; actions.renames["IRRADIANCE"] = "custom_irradiance"; actions.renames["BONE_INDICES"] = "bone_attrib"; @@ -666,7 +685,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs"; actions.apply_luminance_multiplier = true; // apply luminance multiplier to screen texture diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index 88c2143b09..0dbed0b07a 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RSSR_SCENE_SHADER_FM_H -#define RSSR_SCENE_SHADER_FM_H +#ifndef SCENE_SHADER_FORWARD_MOBILE_H +#define SCENE_SHADER_FORWARD_MOBILE_H #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl.gen.h" @@ -139,6 +139,8 @@ public: uint32_t index = 0; virtual void set_code(const String &p_Code); + virtual void set_path_hint(const String &p_path); + virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; @@ -210,4 +212,5 @@ public: }; } // namespace RendererSceneRenderImplementation -#endif // !RSSR_SCENE_SHADER_FM_H + +#endif // SCENE_SHADER_FORWARD_MOBILE_H diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h index ad83fc76b7..882e459bcd 100644 --- a/servers/rendering/renderer_rd/pipeline_cache_rd.h +++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h @@ -97,4 +97,4 @@ public: ~PipelineCacheRD(); }; -#endif // RENDER_PIPELINE_CACHE_RD_H +#endif // PIPELINE_CACHE_RD_H diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 7d55be1216..0b59ca6931 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -528,7 +528,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend } if (rect->flags & CANVAS_RECT_TRANSPOSE) { - dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform + push_constant.flags |= FLAGS_TRANSPOSE_RECT; } if (rect->flags & CANVAS_RECT_CLIP_UV) { @@ -1031,7 +1031,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 9; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); + u.append_id(RendererRD::MaterialStorage::get_singleton()->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -1304,7 +1304,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p Size2i ssize = texture_storage->render_target_get_size(p_to_render_target); Transform3D screen_transform; - screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); + screen_transform.translate_local(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f)); _update_transform_to_mat4(screen_transform, state_buffer.screen_transform); _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform); @@ -1584,7 +1584,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, RD::InitialAction initial_action = i == 0 ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE; RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, initial_action, i != 3 ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, initial_action, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); - CameraMatrix projection; + Projection projection; { real_t fov = 90; real_t nearp = p_near; @@ -1600,7 +1600,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, } Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); - projection = projection * CameraMatrix(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); + projection = projection * Projection(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { @@ -1673,9 +1673,9 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh Rect2i rect(0, p_shadow_index * 2, state.shadow_texture_size, 2); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR_REGION, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR_REGION, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); - CameraMatrix projection; + Projection projection; projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance); - projection = projection * CameraMatrix(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse()); + projection = projection * Projection(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { @@ -1743,7 +1743,7 @@ void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstan RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc); - CameraMatrix projection; + Projection projection; ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { @@ -1968,6 +1968,10 @@ void RendererCanvasRenderRD::occluder_polygon_set_cull_mode(RID p_occluder, RS:: oc->cull_mode = p_mode; } +void RendererCanvasRenderRD::CanvasShaderData::set_path_hint(const String &p_path) { + path = p_path; +} + void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) { //compile @@ -2181,7 +2185,22 @@ void RendererCanvasRenderRD::CanvasShaderData::get_param_list(List<PropertyInfo> } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); @@ -2450,7 +2469,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() { actions.default_repeat = ShaderLanguage::REPEAT_DISABLE; actions.base_varying_index = 4; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; shader.compiler.initialize(actions); } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 2ab5a7c831..1c0567b677 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_CANVAS_RENDER_RD_H -#define RENDERING_SERVER_CANVAS_RENDER_RD_H +#ifndef RENDERER_CANVAS_RENDER_RD_H +#define RENDERER_CANVAS_RENDER_RD_H #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_compositor.h" @@ -178,6 +178,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { bool uses_time = false; virtual void set_code(const String &p_Code); + virtual void set_path_hint(const String &p_path); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; @@ -464,4 +465,4 @@ public: ~RendererCanvasRenderRD(); }; -#endif // RASTERIZER_CANVAS_RD_H +#endif // RENDERER_CANVAS_RENDER_RD_H diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 2be55743fb..564c26bfe4 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -28,11 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_COMPOSITOR_RD_H -#define RENDERING_SERVER_COMPOSITOR_RD_H +#ifndef RENDERER_COMPOSITOR_RD_H +#define RENDERER_COMPOSITOR_RD_H #include "core/os/os.h" -#include "core/templates/thread_work_pool.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/effects_rd.h" #include "servers/rendering/renderer_rd/environment/fog.h" @@ -148,4 +147,5 @@ public: RendererCompositorRD(); ~RendererCompositorRD(); }; -#endif // RASTERIZER_RD_H + +#endif // RENDERER_COMPOSITOR_RD_H diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp deleted file mode 100644 index 0d9477d850..0000000000 --- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************/ -/* renderer_scene_environment_rd.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" - -uint64_t RendererSceneEnvironmentRD::auto_exposure_counter = 2; - -void RendererSceneEnvironmentRD::set_ambient_light(const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { - ambient_light = p_color; - ambient_source = p_ambient; - ambient_light_energy = p_energy; - ambient_sky_contribution = p_sky_contribution; - reflection_source = p_reflection_source; -} - -void RendererSceneEnvironmentRD::set_tonemap(RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { - exposure = p_exposure; - tone_mapper = p_tone_mapper; - if (!auto_exposure && p_auto_exposure) { - auto_exposure_version = ++auto_exposure_counter; - } - auto_exposure = p_auto_exposure; - white = p_white; - min_luminance = p_min_luminance; - max_luminance = p_max_luminance; - auto_exp_speed = p_auto_exp_speed; - auto_exp_scale = p_auto_exp_scale; -} - -void RendererSceneEnvironmentRD::set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { - ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7"); - glow_enabled = p_enable; - glow_levels = p_levels; - glow_intensity = p_intensity; - glow_strength = p_strength; - glow_mix = p_mix; - glow_bloom = p_bloom_threshold; - glow_blend_mode = p_blend_mode; - glow_hdr_bleed_threshold = p_hdr_bleed_threshold; - glow_hdr_bleed_scale = p_hdr_bleed_scale; - glow_hdr_luminance_cap = p_hdr_luminance_cap; - glow_map_strength = p_glow_map_strength; - glow_map = p_glow_map; -} - -void RendererSceneEnvironmentRD::set_sdfgi(bool p_enable, int 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) { - sdfgi_enabled = p_enable; - sdfgi_cascades = p_cascades; - sdfgi_min_cell_size = p_min_cell_size; - sdfgi_use_occlusion = p_use_occlusion; - sdfgi_bounce_feedback = p_bounce_feedback; - sdfgi_read_sky_light = p_read_sky; - sdfgi_energy = p_energy; - sdfgi_normal_bias = p_normal_bias; - sdfgi_probe_bias = p_probe_bias; - sdfgi_y_scale = p_y_scale; -} - -void RendererSceneEnvironmentRD::set_fog(bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { - fog_enabled = p_enable; - fog_light_color = p_light_color; - fog_light_energy = p_light_energy; - fog_sun_scatter = p_sun_scatter; - fog_density = p_density; - fog_height = p_height; - fog_height_density = p_height_density; - fog_aerial_perspective = p_fog_aerial_perspective; -} - -void RendererSceneEnvironmentRD::set_volumetric_fog(bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { - volumetric_fog_enabled = p_enable; - volumetric_fog_density = p_density; - volumetric_fog_scattering = p_albedo; - volumetric_fog_emission = p_emission; - volumetric_fog_emission_energy = p_emission_energy; - volumetric_fog_anisotropy = p_anisotropy, - volumetric_fog_length = p_length; - volumetric_fog_detail_spread = p_detail_spread; - volumetric_fog_gi_inject = p_gi_inject; - volumetric_fog_temporal_reprojection = p_temporal_reprojection; - volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount; - volumetric_fog_ambient_inject = p_ambient_inject; -} - -void RendererSceneEnvironmentRD::set_ssr(bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { - ssr_enabled = p_enable; - ssr_max_steps = p_max_steps; - ssr_fade_in = p_fade_int; - ssr_fade_out = p_fade_out; - ssr_depth_tolerance = p_depth_tolerance; -} - -void RendererSceneEnvironmentRD::set_ssao(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) { - ssao_enabled = p_enable; - ssao_radius = p_radius; - ssao_intensity = p_intensity; - ssao_power = p_power; - ssao_detail = p_detail; - ssao_horizon = p_horizon; - ssao_sharpness = p_sharpness; - ssao_direct_light_affect = p_light_affect; - ssao_ao_channel_affect = p_ao_channel_affect; -} diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h deleted file mode 100644 index 4e170b8cfb..0000000000 --- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************/ -/* renderer_scene_environment_rd.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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_SCENE_ENVIRONMENT_RD_H -#define RENDERING_SERVER_SCENE_ENVIRONMENT_RD_H - -#include "servers/rendering/renderer_scene_render.h" -#include "servers/rendering/rendering_device.h" - -class RendererSceneEnvironmentRD { -private: - static uint64_t auto_exposure_counter; - -public: - // BG - RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR; - RID sky; - float sky_custom_fov = 0.0; - Basis sky_orientation; - Color bg_color; - float bg_energy = 1.0; - int canvas_max_layer = 0; - RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG; - Color ambient_light; - float ambient_light_energy = 1.0; - float ambient_sky_contribution = 1.0; - RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG; - - /// Tonemap - - RS::EnvironmentToneMapper tone_mapper; - float exposure = 1.0; - float white = 1.0; - bool auto_exposure = false; - float min_luminance = 0.2; - float max_luminance = 8.0; - float auto_exp_speed = 0.2; - float auto_exp_scale = 0.5; - uint64_t auto_exposure_version = 0; - - // Fog - bool fog_enabled = false; - Color fog_light_color = Color(0.5, 0.6, 0.7); - float fog_light_energy = 1.0; - float fog_sun_scatter = 0.0; - float fog_density = 0.001; - float fog_height = 0.0; - float fog_height_density = 0.0; //can be negative to invert effect - float fog_aerial_perspective = 0.0; - - /// Volumetric Fog - /// - bool volumetric_fog_enabled = false; - float volumetric_fog_density = 0.01; - Color volumetric_fog_scattering = Color(1, 1, 1); - Color volumetric_fog_emission = Color(0, 0, 0); - float volumetric_fog_emission_energy = 0.0; - float volumetric_fog_anisotropy = 0.2; - float volumetric_fog_length = 64.0; - float volumetric_fog_detail_spread = 2.0; - float volumetric_fog_gi_inject = 0.0; - bool volumetric_fog_temporal_reprojection = true; - float volumetric_fog_temporal_reprojection_amount = 0.9; - float volumetric_fog_ambient_inject = 0.0; - - /// Glow - - bool glow_enabled = false; - Vector<float> glow_levels; - float glow_intensity = 0.8; - float glow_strength = 1.0; - float glow_bloom = 0.0; - float glow_mix = 0.01; - RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT; - float glow_hdr_bleed_threshold = 1.0; - float glow_hdr_luminance_cap = 12.0; - float glow_hdr_bleed_scale = 2.0; - float glow_map_strength = 0.0f; - RID glow_map = RID(); - - /// SSAO - - bool ssao_enabled = false; - float ssao_radius = 1.0; - float ssao_intensity = 2.0; - float ssao_power = 1.5; - float ssao_detail = 0.5; - float ssao_horizon = 0.06; - float ssao_sharpness = 0.98; - float ssao_direct_light_affect = 0.0; - float ssao_ao_channel_affect = 0.0; - - /// SSR - /// - bool ssr_enabled = false; - int ssr_max_steps = 64; - float ssr_fade_in = 0.15; - float ssr_fade_out = 2.0; - float ssr_depth_tolerance = 0.2; - - /// SSIL - /// - bool ssil_enabled = false; - float ssil_radius = 5.0; - float ssil_intensity = 1.0; - float ssil_sharpness = 0.98; - float ssil_normal_rejection = 1.0; - - /// SDFGI - bool sdfgi_enabled = false; - int sdfgi_cascades = 4; - float sdfgi_min_cell_size = 0.2; - bool sdfgi_use_occlusion = false; - float sdfgi_bounce_feedback = 0.5; - bool sdfgi_read_sky_light = true; - float sdfgi_energy = 1.0; - float sdfgi_normal_bias = 1.1; - float sdfgi_probe_bias = 1.1; - RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_75_PERCENT; - - /// Adjustments - - bool adjustments_enabled = false; - float adjustments_brightness = 1.0f; - float adjustments_contrast = 1.0f; - float adjustments_saturation = 1.0f; - bool use_1d_color_correction = false; - RID color_correction = RID(); - - void set_ambient_light(const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source); - void set_tonemap(RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); - void set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map); - void set_sdfgi(bool p_enable, int 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); - void set_fog(bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective); - void set_volumetric_fog(bool p_enable, float p_density, const Color &p_scatterin, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject); - void set_ssr(bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance); - void set_ssao(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); -}; - -#endif /* !RENDERING_SERVER_SCENE_ENVIRONMENT_RD_H */ diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index a2a0538e04..cf231fa4ef 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -51,9 +51,8 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) { } void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); - bool needs_sdfgi = env && env->sdfgi_enabled; + bool needs_sdfgi = p_environment.is_valid() && environment_get_sdfgi_enabled(p_environment); if (!needs_sdfgi) { if (rb->sdfgi != nullptr) { @@ -68,7 +67,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment static const uint32_t history_frames_to_converge[RS::ENV_SDFGI_CONVERGE_MAX] = { 5, 10, 15, 20, 25, 30 }; uint32_t requested_history_size = history_frames_to_converge[gi.sdfgi_frames_to_converge]; - if (rb->sdfgi && (rb->sdfgi->num_cascades != env->sdfgi_cascades || rb->sdfgi->min_cell_size != env->sdfgi_min_cell_size || requested_history_size != rb->sdfgi->history_size || rb->sdfgi->uses_occlusion != env->sdfgi_use_occlusion || rb->sdfgi->y_scale_mode != env->sdfgi_y_scale)) { + if (rb->sdfgi && (rb->sdfgi->num_cascades != environment_get_sdfgi_cascades(p_environment) || rb->sdfgi->min_cell_size != environment_get_sdfgi_min_cell_size(p_environment) || requested_history_size != rb->sdfgi->history_size || rb->sdfgi->uses_occlusion != environment_get_sdfgi_use_occlusion(p_environment) || rb->sdfgi->y_scale_mode != environment_get_sdfgi_y_scale(p_environment))) { //configuration changed, erase rb->sdfgi->erase(); memdelete(rb->sdfgi); @@ -78,10 +77,10 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment RendererRD::GI::SDFGI *sdfgi = rb->sdfgi; if (sdfgi == nullptr) { // re-create - rb->sdfgi = gi.create_sdfgi(env, p_world_position, requested_history_size); + rb->sdfgi = gi.create_sdfgi(p_environment, p_world_position, requested_history_size); } else { //check for updates - rb->sdfgi->update(env, p_world_position); + rb->sdfgi->update(p_environment, p_world_position); } } @@ -159,145 +158,6 @@ Ref<Image> RendererSceneRenderRD::sky_bake_panorama(RID p_sky, float p_energy, b return sky.sky_bake_panorama(p_sky, p_energy, p_bake_irradiance, p_size); } -RID RendererSceneRenderRD::environment_allocate() { - return environment_owner.allocate_rid(); -} -void RendererSceneRenderRD::environment_initialize(RID p_rid) { - environment_owner.initialize_rid(p_rid, RendererSceneEnvironmentRD()); -} - -void RendererSceneRenderRD::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->background = p_bg; -} - -void RendererSceneRenderRD::environment_set_sky(RID p_env, RID p_sky) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky = p_sky; -} - -void RendererSceneRenderRD::environment_set_sky_custom_fov(RID p_env, float p_scale) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky_custom_fov = p_scale; -} - -void RendererSceneRenderRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->sky_orientation = p_orientation; -} - -void RendererSceneRenderRD::environment_set_bg_color(RID p_env, const Color &p_color) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->bg_color = p_color; -} - -void RendererSceneRenderRD::environment_set_bg_energy(RID p_env, float p_energy) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->bg_energy = p_energy; -} - -void RendererSceneRenderRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->canvas_max_layer = p_max_layer; -} - -void RendererSceneRenderRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->set_ambient_light(p_color, p_ambient, p_energy, p_sky_contribution, p_reflection_source); -} - -RS::EnvironmentBG RendererSceneRenderRD::environment_get_background(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX); - return env->background; -} - -RID RendererSceneRenderRD::environment_get_sky(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RID()); - return env->sky; -} - -float RendererSceneRenderRD::environment_get_sky_custom_fov(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->sky_custom_fov; -} - -Basis RendererSceneRenderRD::environment_get_sky_orientation(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Basis()); - return env->sky_orientation; -} - -Color RendererSceneRenderRD::environment_get_bg_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Color()); - return env->bg_color; -} - -float RendererSceneRenderRD::environment_get_bg_energy(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->bg_energy; -} - -int RendererSceneRenderRD::environment_get_canvas_max_layer(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->canvas_max_layer; -} - -Color RendererSceneRenderRD::environment_get_ambient_light_color(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Color()); - return env->ambient_light; -} - -RS::EnvironmentAmbientSource RendererSceneRenderRD::environment_get_ambient_source(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); - return env->ambient_source; -} - -float RendererSceneRenderRD::environment_get_ambient_light_energy(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->ambient_light_energy; -} - -float RendererSceneRenderRD::environment_get_ambient_sky_contribution(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->ambient_sky_contribution; -} - -RS::EnvironmentReflectionSource RendererSceneRenderRD::environment_get_reflection_source(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED); - return env->reflection_source; -} - -void RendererSceneRenderRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->set_tonemap(p_tone_mapper, p_exposure, p_white, p_auto_exposure, p_min_luminance, p_max_luminance, p_auto_exp_speed, p_auto_exp_scale); -} - -void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - env->set_glow(p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap, p_glow_map_strength, p_glow_map); -} - void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enable) { glow_bicubic_upscale = p_enable; } @@ -306,79 +166,6 @@ 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, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - if (!is_dynamic_gi_supported()) { - return; - } - - env->set_sdfgi(p_enable, p_cascades, p_min_cell_size, p_y_scale, p_use_occlusion, p_bounce_feedback, p_read_sky, p_energy, p_normal_bias, p_probe_bias); -} - -void RendererSceneRenderRD::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->set_fog(p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_fog_aerial_perspective); -} - -bool RendererSceneRenderRD::environment_is_fog_enabled(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - - return env->fog_enabled; -} -Color RendererSceneRenderRD::environment_get_fog_light_color(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Color()); - return env->fog_light_color; -} -float RendererSceneRenderRD::environment_get_fog_light_energy(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_light_energy; -} -float RendererSceneRenderRD::environment_get_fog_sun_scatter(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_sun_scatter; -} -float RendererSceneRenderRD::environment_get_fog_density(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_density; -} -float RendererSceneRenderRD::environment_get_fog_height(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - - return env->fog_height; -} -float RendererSceneRenderRD::environment_get_fog_height_density(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_height_density; -} - -float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) const { - const RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0); - return env->fog_aerial_perspective; -} - -void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - if (!is_volumetric_supported()) { - return; - } - - env->set_volumetric_fog(p_enable, p_density, p_albedo, p_emission, p_emission_energy, p_anisotropy, p_length, p_detail_spread, p_gi_inject, p_temporal_reprojection, p_temporal_reprojection_amount, p_ambient_inject); -} - void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) { volumetric_fog_size = p_size; volumetric_fog_depth = p_depth; @@ -399,13 +186,6 @@ void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::Env gi.sdfgi_frames_to_update_light = p_update; } -void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->set_ssr(p_enable, p_max_steps, p_fade_int, p_fade_out, p_depth_tolerance); -} - void RendererSceneRenderRD::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) { ssr_roughness_quality = p_quality; } @@ -414,13 +194,6 @@ RS::EnvironmentSSRRoughnessQuality RendererSceneRenderRD::environment_get_ssr_ro return ssr_roughness_quality; } -void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->set_ssao(p_enable, p_radius, p_intensity, p_power, p_detail, p_horizon, p_sharpness, p_light_affect, p_ao_channel_affect); -} - void RendererSceneRenderRD::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) { ssao_quality = p_quality; ssao_half_size = p_half_size; @@ -430,17 +203,6 @@ void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQual ssao_fadeout_to = p_fadeout_to; } -void RendererSceneRenderRD::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->ssil_enabled = p_enable; - env->ssil_radius = p_radius; - env->ssil_intensity = p_intensity; - env->ssil_sharpness = p_sharpness; - env->ssil_normal_rejection = p_normal_rejection; -} - void RendererSceneRenderRD::environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) { ssil_quality = p_quality; ssil_half_size = p_half_size; @@ -450,56 +212,16 @@ void RendererSceneRenderRD::environment_set_ssil_quality(RS::EnvironmentSSILQual ssil_fadeout_to = p_fadeout_to; } -bool RendererSceneRenderRD::environment_is_ssao_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - return env->ssao_enabled; -} - -float RendererSceneRenderRD::environment_get_ssao_ao_affect(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0.0); - return env->ssao_ao_channel_affect; -} - -float RendererSceneRenderRD::environment_get_ssao_light_affect(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, 0.0); - return env->ssao_direct_light_affect; -} - -bool RendererSceneRenderRD::environment_is_ssil_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - return env->ssil_enabled; -} - -bool RendererSceneRenderRD::environment_is_ssr_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - return env->ssr_enabled; -} -bool RendererSceneRenderRD::environment_is_sdfgi_enabled(RID p_env) const { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, false); - return env->sdfgi_enabled; -} - -bool RendererSceneRenderRD::is_environment(RID p_env) const { - return environment_owner.owns(p_env); -} - Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND_V(!env, Ref<Image>()); + ERR_FAIL_COND_V(p_env.is_null(), Ref<Image>()); - RS::EnvironmentBG environment_background = env->background; + RS::EnvironmentBG environment_background = environment_get_background(p_env); if (environment_background == RS::ENV_BG_CAMERA_FEED || environment_background == RS::ENV_BG_CANVAS || environment_background == RS::ENV_BG_KEEP) { return Ref<Image>(); //nothing to bake } - RS::EnvironmentAmbientSource ambient_source = env->ambient_source; + RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(p_env); bool use_ambient_light = false; bool use_cube_map = false; @@ -509,14 +231,14 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba use_cube_map = (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && environment_background == RS::ENV_BG_SKY) || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY; use_ambient_light = use_cube_map || ambient_source == RS::ENV_AMBIENT_SOURCE_COLOR; } - use_cube_map = use_cube_map || (environment_background == RS::ENV_BG_SKY && env->sky.is_valid()); + use_cube_map = use_cube_map || (environment_background == RS::ENV_BG_SKY && environment_get_sky(p_env).is_valid()); Color ambient_color; - float ambient_color_sky_mix; + float ambient_color_sky_mix = 0.0; if (use_ambient_light) { - ambient_color_sky_mix = env->ambient_sky_contribution; - const float ambient_energy = env->ambient_light_energy; - ambient_color = env->ambient_light; + ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_env); + const float ambient_energy = environment_get_ambient_light_energy(p_env); + ambient_color = environment_get_ambient_light(p_env); ambient_color = ambient_color.srgb_to_linear(); ambient_color.r *= ambient_energy; ambient_color.g *= ambient_energy; @@ -524,7 +246,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba } if (use_cube_map) { - Ref<Image> panorama = sky_bake_panorama(env->sky, env->bg_energy, p_bake_irradiance, p_size); + Ref<Image> panorama = sky_bake_panorama(environment_get_sky(p_env), environment_get_bg_energy(p_env), p_bake_irradiance, p_size); if (use_ambient_light) { for (int x = 0; x < p_size.width; x++) { for (int y = 0; y < p_size.height; y++) { @@ -534,8 +256,8 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba } return panorama; } else { - const float bg_energy = env->bg_energy; - Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : env->bg_color); + const float bg_energy = environment_get_bg_energy(p_env); + Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : environment_get_bg_color(p_env)); panorama_color = panorama_color.srgb_to_linear(); panorama_color.r *= bg_energy; panorama_color.g *= bg_energy; @@ -558,29 +280,28 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba //////////////////////////////////////////////////////////// RID RendererSceneRenderRD::fog_volume_instance_create(RID p_fog_volume) { - FogVolumeInstance fvi; - fvi.volume = p_fog_volume; - return fog_volume_instance_owner.make_rid(fvi); + return RendererRD::Fog::get_singleton()->fog_volume_instance_create(p_fog_volume); } + void RendererSceneRenderRD::fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) { - FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + RendererRD::Fog::FogVolumeInstance *fvi = RendererRD::Fog::get_singleton()->get_fog_volume_instance(p_fog_volume_instance); ERR_FAIL_COND(!fvi); fvi->transform = p_transform; } void RendererSceneRenderRD::fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) { - FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + RendererRD::Fog::FogVolumeInstance *fvi = RendererRD::Fog::get_singleton()->get_fog_volume_instance(p_fog_volume_instance); ERR_FAIL_COND(!fvi); fvi->active = p_active; } RID RendererSceneRenderRD::fog_volume_instance_get_volume(RID p_fog_volume_instance) const { - FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + RendererRD::Fog::FogVolumeInstance *fvi = RendererRD::Fog::get_singleton()->get_fog_volume_instance(p_fog_volume_instance); ERR_FAIL_COND_V(!fvi, RID()); return fvi->volume; } Vector3 RendererSceneRenderRD::fog_volume_instance_get_position(RID p_fog_volume_instance) const { - FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance); + RendererRD::Fog::FogVolumeInstance *fvi = RendererRD::Fog::get_singleton()->get_fog_volume_instance(p_fog_volume_instance); ERR_FAIL_COND_V(!fvi, Vector3()); return fvi->transform.get_origin(); @@ -1430,7 +1151,7 @@ void RendererSceneRenderRD::light_instance_set_aabb(RID p_light_instance, const light_instance->aabb = p_aabb; } -void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { +void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -1526,7 +1247,7 @@ bool RendererSceneRenderRD::voxel_gi_needs_update(RID p_probe) const { return gi.voxel_gi_needs_update(p_probe); } -void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) { +void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) { if (!is_dynamic_gi_supported()) { return; } @@ -1534,7 +1255,7 @@ void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_ins gi.voxel_gi_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this); } -void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { +void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); @@ -1891,60 +1612,9 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { rb->ss_effects.linear_depth_slices.clear(); } - if (rb->ss_effects.ssao.ao_final.is_valid()) { - RD::get_singleton()->free(rb->ss_effects.ssao.ao_deinterleaved); - RD::get_singleton()->free(rb->ss_effects.ssao.ao_pong); - RD::get_singleton()->free(rb->ss_effects.ssao.ao_final); - - RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[0]); - RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[1]); - - rb->ss_effects.ssao.ao_deinterleaved = RID(); - rb->ss_effects.ssao.ao_pong = RID(); - rb->ss_effects.ssao.ao_final = RID(); - rb->ss_effects.ssao.importance_map[0] = RID(); - rb->ss_effects.ssao.importance_map[1] = RID(); - - rb->ss_effects.ssao.ao_deinterleaved_slices.clear(); - rb->ss_effects.ssao.ao_pong_slices.clear(); - } - - if (rb->ss_effects.ssil.ssil_final.is_valid()) { - RD::get_singleton()->free(rb->ss_effects.ssil.ssil_final); - RD::get_singleton()->free(rb->ss_effects.ssil.deinterleaved); - RD::get_singleton()->free(rb->ss_effects.ssil.pong); - RD::get_singleton()->free(rb->ss_effects.ssil.edges); - RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[0]); - RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[1]); - - rb->ss_effects.ssil.ssil_final = RID(); - rb->ss_effects.ssil.deinterleaved = RID(); - rb->ss_effects.ssil.pong = RID(); - rb->ss_effects.ssil.edges = RID(); - rb->ss_effects.ssil.deinterleaved_slices.clear(); - rb->ss_effects.ssil.pong_slices.clear(); - rb->ss_effects.ssil.edges_slices.clear(); - rb->ss_effects.ssil.importance_map[0] = RID(); - rb->ss_effects.ssil.importance_map[1] = RID(); - - RD::get_singleton()->free(rb->ss_effects.last_frame); - rb->ss_effects.last_frame = RID(); - rb->ss_effects.last_frame_slices.clear(); - } - - if (rb->ssr.blur_radius[0].is_valid()) { - RD::get_singleton()->free(rb->ssr.blur_radius[0]); - RD::get_singleton()->free(rb->ssr.blur_radius[1]); - rb->ssr.blur_radius[0] = RID(); - rb->ssr.blur_radius[1] = RID(); - } - - if (rb->ssr.depth_scaled.is_valid()) { - RD::get_singleton()->free(rb->ssr.depth_scaled); - rb->ssr.depth_scaled = RID(); - RD::get_singleton()->free(rb->ssr.normal_scaled); - rb->ssr.normal_scaled = RID(); - } + ss_effects->ssao_free(rb->ss_effects.ssao); + ss_effects->ssil_free(rb->ss_effects.ssil); + ss_effects->ssr_free(rb->ssr); if (rb->taa.history.is_valid()) { RD::get_singleton()->free(rb->taa.history); @@ -1964,7 +1634,7 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { rb->rbgi.free(); } -void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { +void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const Projection &p_camera) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); @@ -1982,7 +1652,9 @@ void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatri RendererCompositorRD::singleton->get_effects()->sub_surface_scattering(rb->internal_texture, rb->sss_texture, rb->depth_texture, p_camera, Size2i(rb->internal_width, rb->internal_height), sss_scale, sss_depth_scale, sss_quality); } -void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) { +void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_slices, RID p_specular_buffer, const RID *p_metallic_slices, const Color &p_metallic_mask, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive) { + ERR_FAIL_NULL(ss_effects); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); @@ -1990,161 +1662,45 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb if (!can_use_effects) { //just copy - RendererCompositorRD::singleton->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, RID()); + copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, RID(), rb->view_count); return; } - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); - ERR_FAIL_COND(!env); + ERR_FAIL_COND(p_environment.is_null()); - ERR_FAIL_COND(!env->ssr_enabled); + ERR_FAIL_COND(!environment_get_ssr_enabled(p_environment)); - if (rb->ssr.depth_scaled.is_null()) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32_SFLOAT; - tf.width = rb->internal_width / 2; - tf.height = rb->internal_height / 2; - tf.texture_type = RD::TEXTURE_TYPE_2D; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT; - - rb->ssr.depth_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); - - tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM; - - rb->ssr.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); + Size2i half_size = Size2i(rb->internal_width / 2, rb->internal_height / 2); + if (rb->ssr.output.is_null()) { + ss_effects->ssr_allocate_buffers(rb->ssr, _render_buffers_get_color_format(), ssr_roughness_quality, half_size, rb->view_count); } - - if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED && !rb->ssr.blur_radius[0].is_valid()) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = rb->internal_width / 2; - tf.height = rb->internal_height / 2; - tf.texture_type = RD::TEXTURE_TYPE_2D; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; - - rb->ssr.blur_radius[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->ssr.blur_radius[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } - - if (rb->blur[0].texture.is_null()) { - _allocate_blur_textures(rb); + RID texture_slices[RendererSceneRender::MAX_RENDER_VIEWS]; + RID depth_slices[RendererSceneRender::MAX_RENDER_VIEWS]; + for (uint32_t v = 0; v < rb->view_count; v++) { + texture_slices[v] = rb->views[v].view_texture; + depth_slices[v] = rb->views[v].view_depth; } - - RendererCompositorRD::singleton->get_effects()->screen_space_reflection(rb->internal_texture, p_normal_buffer, ssr_roughness_quality, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].layers[0].mipmaps[1].texture, rb->blur[1].layers[0].mipmaps[0].texture, Size2i(rb->internal_width / 2, rb->internal_height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection); - RendererCompositorRD::singleton->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->blur[0].layers[0].mipmaps[1].texture); + ss_effects->screen_space_reflection(rb->ssr, texture_slices, p_normal_slices, ssr_roughness_quality, p_metallic_slices, p_metallic_mask, depth_slices, half_size, environment_get_ssr_max_steps(p_environment), environment_get_ssr_fade_in(p_environment), environment_get_ssr_fade_out(p_environment), environment_get_ssr_depth_tolerance(p_environment), rb->view_count, p_projections, p_eye_offsets); + copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->ssr.output, rb->view_count); } -void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { +void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection) { + ERR_FAIL_NULL(ss_effects); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); - ERR_FAIL_COND(!env); + ERR_FAIL_COND(p_environment.is_null()); RENDER_TIMESTAMP("Process SSAO"); - if (rb->ss_effects.ssao.ao_final.is_valid() && ssao_using_half_size != ssao_half_size) { - RD::get_singleton()->free(rb->ss_effects.ssao.ao_deinterleaved); - RD::get_singleton()->free(rb->ss_effects.ssao.ao_pong); - RD::get_singleton()->free(rb->ss_effects.ssao.ao_final); - - RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[0]); - RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[1]); - - rb->ss_effects.ssao.ao_deinterleaved = RID(); - rb->ss_effects.ssao.ao_pong = RID(); - rb->ss_effects.ssao.ao_final = RID(); - rb->ss_effects.ssao.importance_map[0] = RID(); - rb->ss_effects.ssao.importance_map[1] = RID(); - rb->ss_effects.ssao.ao_deinterleaved_slices.clear(); - rb->ss_effects.ssao.ao_pong_slices.clear(); - } - - int buffer_width; - int buffer_height; - int half_width; - int half_height; - if (ssao_half_size) { - buffer_width = (rb->internal_width + 3) / 4; - buffer_height = (rb->internal_height + 3) / 4; - half_width = (rb->internal_width + 7) / 8; - half_height = (rb->internal_height + 7) / 8; - } else { - buffer_width = (rb->internal_width + 1) / 2; - buffer_height = (rb->internal_height + 1) / 2; - half_width = (rb->internal_width + 3) / 4; - half_height = (rb->internal_height + 3) / 4; - } - bool uniform_sets_are_invalid = false; - if (rb->ss_effects.ssao.ao_deinterleaved.is_null()) { - { - rb->ss_effects.ssao.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.linear_depth, 0, ssao_half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY); - } - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8G8_UNORM; - tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; - tf.width = buffer_width; - tf.height = buffer_height; - tf.array_layers = 4; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ss_effects.ssao.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_deinterleaved, "SSAO De-interleaved Array"); - for (uint32_t i = 0; i < 4; i++) { - RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssao.ao_deinterleaved, i, 0); - rb->ss_effects.ssao.ao_deinterleaved_slices.push_back(slice); - RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " "); - } - } - - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8G8_UNORM; - tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; - tf.width = buffer_width; - tf.height = buffer_height; - tf.array_layers = 4; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ss_effects.ssao.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_pong, "SSAO De-interleaved Array Pong"); - for (uint32_t i = 0; i < 4; i++) { - RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssao.ao_pong, i, 0); - rb->ss_effects.ssao.ao_pong_slices.push_back(slice); - RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " Pong"); - } - } - - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = half_width; - tf.height = half_height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ss_effects.ssao.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.importance_map[0], "SSAO Importance Map"); - rb->ss_effects.ssao.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.importance_map[1], "SSAO Importance Map Pong"); - } - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = rb->internal_width; - tf.height = rb->internal_height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ss_effects.ssao.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_final, "SSAO Final"); - } - ssao_using_half_size = ssao_half_size; - uniform_sets_are_invalid = true; - } - - EffectsRD::SSAOSettings settings; - settings.radius = env->ssao_radius; - settings.intensity = env->ssao_intensity; - settings.power = env->ssao_power; - settings.detail = env->ssao_detail; - settings.horizon = env->ssao_horizon; - settings.sharpness = env->ssao_sharpness; + RendererRD::SSEffects::SSAOSettings settings; + settings.radius = environment_get_ssao_radius(p_environment); + settings.intensity = environment_get_ssao_intensity(p_environment); + settings.power = environment_get_ssao_power(p_environment); + settings.detail = environment_get_ssao_detail(p_environment); + settings.horizon = environment_get_ssao_horizon(p_environment); + settings.sharpness = environment_get_ssao_sharpness(p_environment); settings.quality = ssao_quality; settings.half_size = ssao_half_size; @@ -2153,152 +1709,26 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen settings.fadeout_from = ssao_fadeout_from; settings.fadeout_to = ssao_fadeout_to; settings.full_screen_size = Size2i(rb->internal_width, rb->internal_height); - settings.half_screen_size = Size2i(buffer_width, buffer_height); - settings.quarter_screen_size = Size2i(half_width, half_height); - RendererCompositorRD::singleton->get_effects()->generate_ssao(p_normal_buffer, rb->ss_effects.ssao.depth_texture_view, rb->ss_effects.ssao.ao_deinterleaved, rb->ss_effects.ssao.ao_deinterleaved_slices, rb->ss_effects.ssao.ao_pong, rb->ss_effects.ssao.ao_pong_slices, rb->ss_effects.ssao.ao_final, rb->ss_effects.ssao.importance_map[0], rb->ss_effects.ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssao.gather_uniform_set, rb->ss_effects.ssao.importance_map_uniform_set); + ss_effects->ssao_allocate_buffers(rb->ss_effects.ssao, settings, rb->ss_effects.linear_depth); + ss_effects->generate_ssao(rb->ss_effects.ssao, p_normal_buffer, p_projection, settings); } -void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform) { +void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform) { + ERR_FAIL_NULL(ss_effects); + RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); - ERR_FAIL_COND(!env); + ERR_FAIL_COND(p_environment.is_null()); RENDER_TIMESTAMP("Process SSIL"); - if (rb->ss_effects.ssil.ssil_final.is_valid() && ssil_using_half_size != ssil_half_size) { - RD::get_singleton()->free(rb->ss_effects.ssil.ssil_final); - RD::get_singleton()->free(rb->ss_effects.ssil.deinterleaved); - RD::get_singleton()->free(rb->ss_effects.ssil.pong); - RD::get_singleton()->free(rb->ss_effects.ssil.edges); - RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[0]); - RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[1]); - - rb->ss_effects.ssil.ssil_final = RID(); - rb->ss_effects.ssil.deinterleaved = RID(); - rb->ss_effects.ssil.pong = RID(); - rb->ss_effects.ssil.edges = RID(); - rb->ss_effects.ssil.deinterleaved_slices.clear(); - rb->ss_effects.ssil.pong_slices.clear(); - rb->ss_effects.ssil.edges_slices.clear(); - rb->ss_effects.ssil.importance_map[0] = RID(); - rb->ss_effects.ssil.importance_map[1] = RID(); - } - - int buffer_width; - int buffer_height; - int half_width; - int half_height; - if (ssil_half_size) { - buffer_width = (rb->width + 3) / 4; - buffer_height = (rb->height + 3) / 4; - half_width = (rb->width + 7) / 8; - half_height = (rb->height + 7) / 8; - } else { - buffer_width = (rb->width + 1) / 2; - buffer_height = (rb->height + 1) / 2; - half_width = (rb->width + 3) / 4; - half_height = (rb->height + 3) / 4; - } - bool uniform_sets_are_invalid = false; - if (rb->ss_effects.ssil.ssil_final.is_null()) { - { - rb->ss_effects.ssil.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.linear_depth, 0, ssil_half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY); - } - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.width = rb->width; - tf.height = rb->height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; - rb->ss_effects.ssil.ssil_final = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.ssil_final, "SSIL texture"); - RD::get_singleton()->texture_clear(rb->ss_effects.ssil.ssil_final, Color(0, 0, 0, 0), 0, 1, 0, 1); - if (rb->ss_effects.last_frame.is_null()) { - tf.mipmaps = 6; - rb->ss_effects.last_frame = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.last_frame, "Last Frame Radiance"); - RD::get_singleton()->texture_clear(rb->ss_effects.last_frame, Color(0, 0, 0, 0), 0, tf.mipmaps, 0, 1); - for (uint32_t i = 0; i < 6; i++) { - RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.last_frame, 0, i); - rb->ss_effects.last_frame_slices.push_back(slice); - RD::get_singleton()->set_resource_name(slice, "Last Frame Radiance Mip " + itos(i) + " "); - } - } - } - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; - tf.width = buffer_width; - tf.height = buffer_height; - tf.array_layers = 4; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ss_effects.ssil.deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.deinterleaved, "SSIL deinterleaved buffer"); - for (uint32_t i = 0; i < 4; i++) { - RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.deinterleaved, i, 0); - rb->ss_effects.ssil.deinterleaved_slices.push_back(slice); - RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer array " + itos(i) + " "); - } - } - - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; - tf.width = buffer_width; - tf.height = buffer_height; - tf.array_layers = 4; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ss_effects.ssil.pong = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.pong, "SSIL deinterleaved pong buffer"); - for (uint32_t i = 0; i < 4; i++) { - RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.pong, i, 0); - rb->ss_effects.ssil.pong_slices.push_back(slice); - RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer pong array " + itos(i) + " "); - } - } - - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; - tf.width = buffer_width; - tf.height = buffer_height; - tf.array_layers = 4; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ss_effects.ssil.edges = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.edges, "SSIL edges buffer"); - for (uint32_t i = 0; i < 4; i++) { - RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.edges, i, 0); - rb->ss_effects.ssil.edges_slices.push_back(slice); - RD::get_singleton()->set_resource_name(slice, "SSIL edges buffer slice " + itos(i) + " "); - } - } - - { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = half_width; - tf.height = half_height; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ss_effects.ssil.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.importance_map[0], "SSIL Importance Map"); - rb->ss_effects.ssil.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.importance_map[1], "SSIL Importance Map Pong"); - } - uniform_sets_are_invalid = true; - ssil_using_half_size = ssil_half_size; - } - - EffectsRD::SSILSettings settings; - settings.radius = env->ssil_radius; - settings.intensity = env->ssil_intensity; - settings.sharpness = env->ssil_sharpness; - settings.normal_rejection = env->ssil_normal_rejection; + RendererRD::SSEffects::SSILSettings settings; + settings.radius = environment_get_ssil_radius(p_environment); + settings.intensity = environment_get_ssil_intensity(p_environment); + settings.sharpness = environment_get_ssil_sharpness(p_environment); + settings.normal_rejection = environment_get_ssil_normal_rejection(p_environment); settings.quality = ssil_quality; settings.half_size = ssil_half_size; @@ -2307,17 +1737,16 @@ void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environmen settings.fadeout_from = ssil_fadeout_from; settings.fadeout_to = ssil_fadeout_to; settings.full_screen_size = Size2i(rb->width, rb->height); - settings.half_screen_size = Size2i(buffer_width, buffer_height); - settings.quarter_screen_size = Size2i(half_width, half_height); - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); - CameraMatrix projection = correction * p_projection; + Projection projection = correction * p_projection; Transform3D transform = p_transform; transform.set_origin(Vector3(0.0, 0.0, 0.0)); - CameraMatrix last_frame_projection = rb->ss_effects.last_frame_projection * CameraMatrix(rb->ss_effects.last_frame_transform.affine_inverse()) * CameraMatrix(transform) * projection.inverse(); + Projection last_frame_projection = rb->ss_effects.last_frame_projection * Projection(rb->ss_effects.last_frame_transform.affine_inverse()) * Projection(transform) * projection.inverse(); - RendererCompositorRD::singleton->get_effects()->screen_space_indirect_lighting(rb->ss_effects.last_frame, rb->ss_effects.ssil.ssil_final, p_normal_buffer, rb->ss_effects.ssil.depth_texture_view, rb->ss_effects.ssil.deinterleaved, rb->ss_effects.ssil.deinterleaved_slices, rb->ss_effects.ssil.pong, rb->ss_effects.ssil.pong_slices, rb->ss_effects.ssil.importance_map[0], rb->ss_effects.ssil.importance_map[1], rb->ss_effects.ssil.edges, rb->ss_effects.ssil.edges_slices, p_projection, last_frame_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssil.gather_uniform_set, rb->ss_effects.ssil.importance_map_uniform_set, rb->ss_effects.ssil.projection_uniform_set); + ss_effects->ssil_allocate_buffers(rb->ss_effects.ssil, settings, rb->ss_effects.linear_depth); + ss_effects->screen_space_indirect_lighting(rb->ss_effects.ssil, p_normal_buffer, p_projection, last_frame_projection, settings); rb->ss_effects.last_frame_projection = projection; rb->ss_effects.last_frame_transform = transform; } @@ -2326,15 +1755,15 @@ void RendererSceneRenderRD::_copy_framebuffer_to_ssil(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - if (rb->ss_effects.last_frame.is_valid()) { - copy_effects->copy_to_rect(rb->texture, rb->ss_effects.last_frame, Rect2i(0, 0, rb->width, rb->height)); + if (rb->ss_effects.ssil.last_frame.is_valid()) { + copy_effects->copy_to_rect(rb->texture, rb->ss_effects.ssil.last_frame, Rect2i(0, 0, rb->width, rb->height)); int width = rb->width; int height = rb->height; - for (int i = 0; i < rb->ss_effects.last_frame_slices.size() - 1; i++) { + for (int i = 0; i < rb->ss_effects.ssil.last_frame_slices.size() - 1; i++) { width = MAX(1, width >> 1); height = MAX(1, height >> 1); - copy_effects->make_mipmap(rb->ss_effects.last_frame_slices[i], rb->ss_effects.last_frame_slices[i + 1], Size2i(width, height)); + copy_effects->make_mipmap(rb->ss_effects.ssil.last_frame_slices[i], rb->ss_effects.ssil.last_frame_slices[i + 1], Size2i(width, height)); } } } @@ -2431,7 +1860,6 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); // Glow and override exposure (if enabled). CameraEffects *camfx = camera_effects_owner.get_or_null(p_render_data->camera_effects); @@ -2491,21 +1919,21 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RD::get_singleton()->draw_command_end_label(); } - if (can_use_effects && env && env->auto_exposure) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_auto_exposure(p_render_data->environment)) { RENDER_TIMESTAMP("Auto exposure"); RD::get_singleton()->draw_command_begin_label("Auto exposure"); if (rb->luminance.current.is_null()) { _allocate_luminance_textures(rb); } - bool set_immediate = env->auto_exposure_version != rb->auto_exposure_version; - rb->auto_exposure_version = env->auto_exposure_version; + bool set_immediate = environment_get_auto_exposure_version(p_render_data->environment) != rb->auto_exposure_version; + rb->auto_exposure_version = environment_get_auto_exposure_version(p_render_data->environment); - double step = env->auto_exp_speed * time_step; + double step = environment_get_auto_exp_speed(p_render_data->environment) * time_step; if (can_use_storage) { - RendererCompositorRD::singleton->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); + RendererCompositorRD::singleton->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, environment_get_min_luminance(p_render_data->environment), environment_get_max_luminance(p_render_data->environment), step, set_immediate); } else { - RendererCompositorRD::singleton->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate); + RendererCompositorRD::singleton->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, environment_get_min_luminance(p_render_data->environment), environment_get_max_luminance(p_render_data->environment), step, set_immediate); } // Swap final reduce with prev luminance. SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]); @@ -2519,7 +1947,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende int max_glow_level = -1; - if (can_use_effects && env && env->glow_enabled) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { RENDER_TIMESTAMP("Glow"); RD::get_singleton()->draw_command_begin_label("Gaussian Glow"); @@ -2530,7 +1958,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende } for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { - if (env->glow_levels[i] > 0.0) { + if (environment_get_glow_levels(p_render_data->environment)[i] > 0.0) { if (i >= rb->blur[1].layers[0].mipmaps.size()) { max_glow_level = rb->blur[1].layers[0].mipmaps.size() - 1; } else { @@ -2547,19 +1975,19 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende if (i == 0) { RID luminance_texture; - if (env->auto_exposure && rb->luminance.current.is_valid()) { + if (environment_get_auto_exposure(p_render_data->environment) && rb->luminance.current.is_valid()) { luminance_texture = rb->luminance.current; } if (can_use_storage) { - copy_effects->gaussian_glow(rb->views[l].view_texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + copy_effects->gaussian_glow(rb->views[l].view_texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), environment_get_glow_strength(p_render_data->environment), glow_high_quality, true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, environment_get_auto_exp_scale(p_render_data->environment)); } else { - copy_effects->gaussian_glow_raster(rb->views[l].view_texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + copy_effects->gaussian_glow_raster(rb->views[l].view_texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), environment_get_glow_strength(p_render_data->environment), glow_high_quality, true, environment_get_glow_hdr_luminance_cap(p_render_data->environment), environment_get_exposure(p_render_data->environment), environment_get_glow_bloom(p_render_data->environment), environment_get_glow_hdr_bleed_threshold(p_render_data->environment), environment_get_glow_hdr_bleed_scale(p_render_data->environment), luminance_texture, environment_get_auto_exp_scale(p_render_data->environment)); } } else { if (can_use_storage) { - copy_effects->gaussian_glow(rb->blur[1].layers[l].mipmaps[i - 1].texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + copy_effects->gaussian_glow(rb->blur[1].layers[l].mipmaps[i - 1].texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), environment_get_glow_strength(p_render_data->environment), glow_high_quality); } else { - copy_effects->gaussian_glow_raster(rb->blur[1].layers[l].mipmaps[i - 1].texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + copy_effects->gaussian_glow_raster(rb->blur[1].layers[l].mipmaps[i - 1].texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), environment_get_glow_strength(p_render_data->environment), glow_high_quality); } } } @@ -2574,28 +2002,28 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende RendererRD::ToneMapper::TonemapSettings tonemap; - if (can_use_effects && env && env->auto_exposure && rb->luminance.current.is_valid()) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_auto_exposure(p_render_data->environment) && rb->luminance.current.is_valid()) { tonemap.use_auto_exposure = true; tonemap.exposure_texture = rb->luminance.current; - tonemap.auto_exposure_grey = env->auto_exp_scale; + tonemap.auto_exposure_grey = environment_get_auto_exp_scale(p_render_data->environment); } else { tonemap.exposure_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); } - if (can_use_effects && env && env->glow_enabled) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { tonemap.use_glow = true; - tonemap.glow_mode = RendererRD::ToneMapper::TonemapSettings::GlowMode(env->glow_blend_mode); - tonemap.glow_intensity = env->glow_blend_mode == RS::ENV_GLOW_BLEND_MODE_MIX ? env->glow_mix : env->glow_intensity; + tonemap.glow_mode = RendererRD::ToneMapper::TonemapSettings::GlowMode(environment_get_glow_blend_mode(p_render_data->environment)); + tonemap.glow_intensity = environment_get_glow_blend_mode(p_render_data->environment) == RS::ENV_GLOW_BLEND_MODE_MIX ? environment_get_glow_mix(p_render_data->environment) : environment_get_glow_intensity(p_render_data->environment); for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { - tonemap.glow_levels[i] = env->glow_levels[i]; + tonemap.glow_levels[i] = environment_get_glow_levels(p_render_data->environment)[i]; } tonemap.glow_texture_size.x = rb->blur[1].layers[0].mipmaps[0].width; tonemap.glow_texture_size.y = rb->blur[1].layers[0].mipmaps[0].height; tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale; tonemap.glow_texture = rb->blur[1].texture; - if (env->glow_map.is_valid()) { - tonemap.glow_map_strength = env->glow_map_strength; - tonemap.glow_map = texture_storage->texture_get_rd_texture(env->glow_map); + if (environment_get_glow_map(p_render_data->environment).is_valid()) { + tonemap.glow_map_strength = environment_get_glow_map_strength(p_render_data->environment); + tonemap.glow_map = texture_storage->texture_get_rd_texture(environment_get_glow_map(p_render_data->environment)); } else { tonemap.glow_map_strength = 0.0f; tonemap.glow_map = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE); @@ -2613,10 +2041,10 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.use_debanding = rb->use_debanding; tonemap.texture_size = Vector2i(rb->internal_width, rb->internal_height); - if (env) { - tonemap.tonemap_mode = env->tone_mapper; - tonemap.white = env->white; - tonemap.exposure = env->exposure; + if (p_render_data->environment.is_valid()) { + tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment); + tonemap.white = environment_get_white(p_render_data->environment); + tonemap.exposure = environment_get_exposure(p_render_data->environment); } if (camfx && camfx->override_exposure_enabled) { @@ -2627,15 +2055,15 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.use_1d_color_correction = false; tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); - if (can_use_effects && env) { - tonemap.use_bcs = env->adjustments_enabled; - tonemap.brightness = env->adjustments_brightness; - tonemap.contrast = env->adjustments_contrast; - tonemap.saturation = env->adjustments_saturation; - if (env->adjustments_enabled && env->color_correction.is_valid()) { + if (can_use_effects && p_render_data->environment.is_valid()) { + tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment); + tonemap.brightness = environment_get_adjustments_brightness(p_render_data->environment); + tonemap.contrast = environment_get_adjustments_contrast(p_render_data->environment); + tonemap.saturation = environment_get_adjustments_saturation(p_render_data->environment); + if (environment_get_adjustments_enabled(p_render_data->environment) && environment_get_color_correction(p_render_data->environment).is_valid()) { tonemap.use_color_correction = true; - tonemap.use_1d_color_correction = env->use_1d_color_correction; - tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(env->color_correction); + tonemap.use_1d_color_correction = environment_get_use_1d_color_correction(p_render_data->environment); + tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(environment_get_color_correction(p_render_data->environment)); } } @@ -2665,7 +2093,6 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); // Override exposure (if enabled). CameraEffects *camfx = camera_effects_owner.get_or_null(p_render_data->camera_effects); @@ -2675,10 +2102,10 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr RendererRD::ToneMapper::TonemapSettings tonemap; - if (env) { - tonemap.tonemap_mode = env->tone_mapper; - tonemap.exposure = env->exposure; - tonemap.white = env->white; + if (p_render_data->environment.is_valid()) { + tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment); + tonemap.exposure = environment_get_exposure(p_render_data->environment); + tonemap.white = environment_get_white(p_render_data->environment); } if (camfx && camfx->override_exposure_enabled) { @@ -2688,10 +2115,10 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr // We don't support glow or auto exposure here, if they are needed, don't use subpasses! // The problem is that we need to use the result so far and process them before we can // apply this to our results. - if (can_use_effects && env && env->glow_enabled) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_glow_enabled(p_render_data->environment)) { ERR_FAIL_MSG("Glow is not supported when using subpasses."); } - if (can_use_effects && env && env->auto_exposure) { + if (can_use_effects && p_render_data->environment.is_valid() && environment_get_auto_exposure(p_render_data->environment)) { ERR_FAIL_MSG("Glow is not supported when using subpasses."); } @@ -2705,15 +2132,15 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr tonemap.use_1d_color_correction = false; tonemap.color_correction_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE); - if (can_use_effects && env) { - tonemap.use_bcs = env->adjustments_enabled; - tonemap.brightness = env->adjustments_brightness; - tonemap.contrast = env->adjustments_contrast; - tonemap.saturation = env->adjustments_saturation; - if (env->adjustments_enabled && env->color_correction.is_valid()) { + if (can_use_effects && p_render_data->environment.is_valid()) { + tonemap.use_bcs = environment_get_adjustments_enabled(p_render_data->environment); + tonemap.brightness = environment_get_adjustments_brightness(p_render_data->environment); + tonemap.contrast = environment_get_adjustments_contrast(p_render_data->environment); + tonemap.saturation = environment_get_adjustments_saturation(p_render_data->environment); + if (environment_get_adjustments_enabled(p_render_data->environment) && environment_get_color_correction(p_render_data->environment).is_valid()) { tonemap.use_color_correction = true; - tonemap.use_1d_color_correction = env->use_1d_color_correction; - tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(env->color_correction); + tonemap.use_1d_color_correction = environment_get_use_1d_color_correction(p_render_data->environment); + tonemap.color_correction_texture = texture_storage->texture_get_rd_texture(environment_get_color_correction(p_render_data->environment)); } } @@ -2817,18 +2244,6 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID } } -void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) { - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env); - ERR_FAIL_COND(!env); - - env->adjustments_enabled = p_enable; - env->adjustments_brightness = p_brightness; - env->adjustments_contrast = p_contrast; - env->adjustments_saturation = p_saturation; - env->use_1d_color_correction = p_use_1d_color_correction; - env->color_correction = p_color_correction; -} - RID RendererSceneRenderRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); @@ -3033,7 +2448,7 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() { return true; } -void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { +void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -3044,11 +2459,9 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p p_internal_width = p_width; } - if (p_width != p_internal_width) { - float fsr_mipmap_bias = -log2f(p_width / p_internal_width) + p_fsr_mipmap_bias; - material_storage->sampler_rd_configure_custom(fsr_mipmap_bias); - update_uniform_sets(); - } + const float texture_mipmap_bias = -log2f(p_width / p_internal_width) + p_texture_mipmap_bias; + material_storage->sampler_rd_configure_custom(texture_mipmap_bias); + update_uniform_sets(); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); @@ -3480,17 +2893,17 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light_storage->light_directional_get_blend_splits(base); for (int j = 0; j < 4; j++) { Rect2 atlas_rect = li->shadow_transform[j].atlas_rect; - CameraMatrix matrix = li->shadow_transform[j].camera; + Projection matrix = li->shadow_transform[j].camera; float split = li->shadow_transform[MIN(limit, j)].split; - CameraMatrix bias; + Projection bias; bias.set_light_bias(); - CameraMatrix rectm; + Projection rectm; rectm.set_light_atlas_rect(atlas_rect); Transform3D modelview = (inverse_transform * li->shadow_transform[j].transform).inverse(); - CameraMatrix shadow_mtx = rectm * bias * matrix * modelview; + Projection shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; float bias_scale = li->shadow_transform[j].bias_scale; light_data.shadow_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale; @@ -3758,16 +3171,16 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.direction[1] = omni_offset.y * float(rect.size.height); } else if (type == RS::LIGHT_SPOT) { Transform3D modelview = (inverse_transform * light_transform).inverse(); - CameraMatrix bias; + Projection bias; bias.set_light_bias(); - CameraMatrix shadow_mtx = bias * li->shadow_transform[0].camera * modelview; + Projection shadow_mtx = bias * li->shadow_transform[0].camera * modelview; RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrix); if (size > 0.0 && light_data.soft_shadow_scale > 0.0) { // Only enable PCSS-like soft shadows if blurring is enabled. // Otherwise, performance would decrease with no visual difference. - CameraMatrix cm = li->shadow_transform[0].camera; + Projection cm = li->shadow_transform[0].camera; float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle)); light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width; } else { @@ -3978,242 +3391,10 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const //////////////////////////////////////////////////////////////////////////////// // FOG SHADER -void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) { - //compile - - code = p_code; - valid = false; - ubo_size = 0; - uniforms.clear(); - - if (code.is_empty()) { - return; //just invalid, but no error - } - - ShaderCompiler::GeneratedCode gen_code; - ShaderCompiler::IdentifierActions actions; - actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE; - - uses_time = false; - - actions.usage_flag_pointers["TIME"] = &uses_time; - - actions.uniforms = &uniforms; - - RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); - - Error err = scene_singleton->volumetric_fog.compiler.compile(RS::SHADER_FOG, code, &actions, path, gen_code); - ERR_FAIL_COND_MSG(err != OK, "Fog shader compilation failed."); - - if (version.is_null()) { - version = scene_singleton->volumetric_fog.shader.version_create(); - } - - scene_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines); - ERR_FAIL_COND(!scene_singleton->volumetric_fog.shader.version_is_valid(version)); - - ubo_size = gen_code.uniform_total_size; - ubo_offsets = gen_code.uniform_offsets; - texture_uniforms = gen_code.texture_uniforms; - - pipeline = RD::get_singleton()->compute_pipeline_create(scene_singleton->volumetric_fog.shader.version_get_shader(version, 0)); - - valid = true; -} - -void RendererSceneRenderRD::FogShaderData::set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) { - if (!p_texture.is_valid()) { - if (default_texture_params.has(p_name) && default_texture_params[p_name].has(p_index)) { - default_texture_params[p_name].erase(p_index); - - if (default_texture_params[p_name].is_empty()) { - default_texture_params.erase(p_name); - } - } - } else { - if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = HashMap<int, RID>(); - } - default_texture_params[p_name][p_index] = p_texture; - } -} - -void RendererSceneRenderRD::FogShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - RBMap<int, StringName> order; - - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - if (E.value.texture_order >= 0) { - order[E.value.texture_order + 100000] = E.key; - } else { - order[E.value.order] = E.key; - } - } - - for (const KeyValue<int, StringName> &E : order) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); - pi.name = E.value; - p_param_list->push_back(pi); - } -} - -void RendererSceneRenderRD::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { - if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { - continue; - } - - RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E.value); - p.info.name = E.key; //supply name - p.index = E.value.instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); - p_param_list->push_back(p); - } -} - -bool RendererSceneRenderRD::FogShaderData::is_param_texture(const StringName &p_param) const { - if (!uniforms.has(p_param)) { - return false; - } - - return uniforms[p_param].texture_order >= 0; -} - -bool RendererSceneRenderRD::FogShaderData::is_animated() const { - return false; -} - -bool RendererSceneRenderRD::FogShaderData::casts_shadows() const { - return false; -} - -Variant RendererSceneRenderRD::FogShaderData::get_default_parameter(const StringName &p_parameter) const { - if (uniforms.has(p_parameter)) { - ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter]; - Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value; - return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.array_size, uniform.hint); - } - return Variant(); -} - -RS::ShaderNativeSourceCode RendererSceneRenderRD::FogShaderData::get_native_source_code() const { - RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); - - return scene_singleton->volumetric_fog.shader.version_get_native_source_code(version); -} - -RendererSceneRenderRD::FogShaderData::~FogShaderData() { - RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); - ERR_FAIL_COND(!scene_singleton); - //pipeline variants will clear themselves if shader is gone - if (version.is_valid()) { - scene_singleton->volumetric_fog.shader.version_free(version); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Fog material - -bool RendererSceneRenderRD::FogMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { - RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); - - uniform_set_updated = true; - - return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, scene_singleton->volumetric_fog.shader.version_get_shader(shader_data->version, 0), VolumetricFogShader::FogSet::FOG_SET_MATERIAL); -} - -RendererSceneRenderRD::FogMaterialData::~FogMaterialData() { - free_parameters_uniform_set(uniform_set); -} - -RendererRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_func() { - FogShaderData *shader_data = memnew(FogShaderData); - return shader_data; -} - -RendererRD::ShaderData *RendererSceneRenderRD::_create_fog_shader_funcs() { - return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->_create_fog_shader_func(); -}; - -RendererRD::MaterialData *RendererSceneRenderRD::_create_fog_material_func(FogShaderData *p_shader) { - FogMaterialData *material_data = memnew(FogMaterialData); - material_data->shader_data = p_shader; - //update will happen later anyway so do nothing. - return material_data; -} - -RendererRD::MaterialData *RendererSceneRenderRD::_create_fog_material_funcs(RendererRD::ShaderData *p_shader) { - return static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton)->_create_fog_material_func(static_cast<FogShaderData *>(p_shader)); -}; - -//////////////////////////////////////////////////////////////////////////////// -// Volumetric Fog - -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); - RD::get_singleton()->free(rb->volumetric_fog->density_map); - RD::get_singleton()->free(rb->volumetric_fog->light_map); - RD::get_singleton()->free(rb->volumetric_fog->emissive_map); - - if (rb->volumetric_fog->fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) { - RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set); - } - if (rb->volumetric_fog->process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) { - RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set_density); - } - if (rb->volumetric_fog->process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) { - RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set); - } - if (rb->volumetric_fog->process_uniform_set2.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set2)) { - RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set2); - } - if (rb->volumetric_fog->sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->sdfgi_uniform_set)) { - RD::get_singleton()->free(rb->volumetric_fog->sdfgi_uniform_set); - } - if (rb->volumetric_fog->sky_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->sky_uniform_set)) { - RD::get_singleton()->free(rb->volumetric_fog->sky_uniform_set); - } - - memdelete(rb->volumetric_fog); - - rb->volumetric_fog = nullptr; -} - -Vector3i RendererSceneRenderRD::_point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform) { - Vector3 view_position = p_cam_transform.affine_inverse().xform(p_point); - view_position.z = MIN(view_position.z, -0.01); // Clamp to the front of camera - Vector3 fog_position = Vector3(0, 0, 0); - - view_position.y = -view_position.y; - fog_position.z = -view_position.z / fog_end; - fog_position.x = (view_position.x / (2 * (fog_near_size.x * (1.0 - fog_position.z) + fog_far_size.x * fog_position.z))) + 0.5; - fog_position.y = (view_position.y / (2 * (fog_near_size.y * (1.0 - fog_position.z) + fog_far_size.y * fog_position.z))) + 0.5; - fog_position.z = Math::pow(float(fog_position.z), float(1.0 / volumetric_fog_detail_spread)); - fog_position = fog_position * fog_size - Vector3(0.5, 0.5, 0.5); - - fog_position.x = CLAMP(fog_position.x, 0.0, fog_size.x); - fog_position.y = CLAMP(fog_position.y, 0.0, fog_size.y); - fog_position.z = CLAMP(fog_position.z, 0.0, fog_size.z); - - return Vector3i(fog_position); -} - -void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) { - RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - +void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) { ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment); float ratio = float(rb->width) / float((rb->width + rb->height) / 2); uint32_t target_width = uint32_t(float(volumetric_fog_size) * ratio); @@ -4221,694 +3402,49 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e if (rb->volumetric_fog) { //validate - if (!env || !env->volumetric_fog_enabled || rb->volumetric_fog->width != target_width || rb->volumetric_fog->height != target_height || rb->volumetric_fog->depth != volumetric_fog_depth) { - _volumetric_fog_erase(rb); + if (p_environment.is_null() || !environment_get_volumetric_fog_enabled(p_environment) || rb->volumetric_fog->width != target_width || rb->volumetric_fog->height != target_height || rb->volumetric_fog->depth != volumetric_fog_depth) { + memdelete(rb->volumetric_fog); + rb->volumetric_fog = nullptr; } } - if (!env || !env->volumetric_fog_enabled) { + if (p_environment.is_null() || !environment_get_volumetric_fog_enabled(p_environment)) { //no reason to enable or update, bye return; } - RENDER_TIMESTAMP("> Volumetric Fog"); - RD::get_singleton()->draw_command_begin_label("Volumetric Fog"); - - if (env && env->volumetric_fog_enabled && !rb->volumetric_fog) { + if (p_environment.is_valid() && environment_get_volumetric_fog_enabled(p_environment) && !rb->volumetric_fog) { //required volumetric fog but not existing, create - rb->volumetric_fog = memnew(VolumetricFog); - rb->volumetric_fog->width = target_width; - rb->volumetric_fog->height = target_height; - rb->volumetric_fog->depth = volumetric_fog_depth; - - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; - tf.width = target_width; - tf.height = target_height; - tf.depth = volumetric_fog_depth; - tf.texture_type = RD::TEXTURE_TYPE_3D; - 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()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->light_density_map, "Fog light-density map"); - - 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()->set_resource_name(rb->volumetric_fog->prev_light_density_map, "Fog previous light-density map"); - 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()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->fog_map, "Fog map"); - -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) - Vector<uint8_t> dm; - dm.resize(target_width * target_height * volumetric_fog_depth * 4); - dm.fill(0); - - rb->volumetric_fog->density_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->density_map, "Fog density map"); - rb->volumetric_fog->light_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->light_map, "Fog light map"); - rb->volumetric_fog->emissive_map = RD::get_singleton()->storage_buffer_create(dm.size(), dm); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->emissive_map, "Fog emissive map"); -#else - tf.format = RD::DATA_FORMAT_R32_UINT; - tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT; - rb->volumetric_fog->density_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->density_map, "Fog density map"); - RD::get_singleton()->texture_clear(rb->volumetric_fog->density_map, Color(0, 0, 0, 0), 0, 1, 0, 1); - rb->volumetric_fog->light_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->light_map, "Fog light map"); - RD::get_singleton()->texture_clear(rb->volumetric_fog->light_map, Color(0, 0, 0, 0), 0, 1, 0, 1); - rb->volumetric_fog->emissive_map = RD::get_singleton()->texture_create(tf, RD::TextureView()); - RD::get_singleton()->set_resource_name(rb->volumetric_fog->emissive_map, "Fog emissive map"); - RD::get_singleton()->texture_clear(rb->volumetric_fog->emissive_map, Color(0, 0, 0, 0), 0, 1, 0, 1); -#endif - - Vector<RD::Uniform> uniforms; - { - RD::Uniform u; - u.binding = 0; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.append_id(rb->volumetric_fog->fog_map); - uniforms.push_back(u); - } - - rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky.sky_shader.default_shader_rd, RendererSceneSkyRD::SKY_SET_FOG); + rb->volumetric_fog = memnew(RendererRD::Fog::VolumetricFog(Vector3i(target_width, target_height, volumetric_fog_depth), sky.sky_shader.default_shader_rd)); } - if (p_fog_volumes.size() > 0) { - RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes"); - - RENDER_TIMESTAMP("Render FogVolumes"); - - VolumetricFogShader::VolumeUBO params; - - Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); - Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); - float z_near = p_cam_projection.get_z_near(); - float z_far = p_cam_projection.get_z_far(); - float fog_end = env->volumetric_fog_length; - - Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); - Vector2 fog_near_size; - if (p_cam_projection.is_orthogonal()) { - fog_near_size = fog_far_size; - } else { - fog_near_size = Vector2(); - } - - params.fog_frustum_size_begin[0] = fog_near_size.x; - params.fog_frustum_size_begin[1] = fog_near_size.y; - - params.fog_frustum_size_end[0] = fog_far_size.x; - params.fog_frustum_size_end[1] = fog_far_size.y; - - params.fog_frustum_end = fog_end; - params.z_near = z_near; - params.z_far = z_far; - params.time = time; - - params.fog_volume_size[0] = rb->volumetric_fog->width; - params.fog_volume_size[1] = rb->volumetric_fog->height; - params.fog_volume_size[2] = rb->volumetric_fog->depth; - - params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection; - params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; - params.detail_spread = env->volumetric_fog_detail_spread; - params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount; - - Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; - RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view); - RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform); - - RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), ¶ms, RD::BARRIER_MASK_COMPUTE); - - if (rb->volumetric_fog->fog_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) { - Vector<RD::Uniform> uniforms; - - { - RD::Uniform u; -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 1; - u.append_id(rb->volumetric_fog->emissive_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 2; - u.append_id(volumetric_fog.volume_ubo); - uniforms.push_back(u); - } - - { - RD::Uniform u; -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 3; - u.append_id(rb->volumetric_fog->density_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 4; - u.append_id(rb->volumetric_fog->light_map); - uniforms.push_back(u); - } - - rb->volumetric_fog->fog_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); - } - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - bool any_uses_time = false; - - for (int i = 0; i < (int)p_fog_volumes.size(); i++) { - FogVolumeInstance *fog_volume_instance = fog_volume_instance_owner.get_or_null(p_fog_volumes[i]); - ERR_FAIL_COND(!fog_volume_instance); - RID fog_volume = fog_volume_instance->volume; - - RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume); - - FogMaterialData *material = nullptr; - - if (fog_material.is_valid()) { - material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); - if (!material || !material->shader_data->valid) { - material = nullptr; - } - } - - if (!material) { - fog_material = volumetric_fog.default_material; - material = static_cast<FogMaterialData *>(material_storage->material_get_data(fog_material, RendererRD::SHADER_TYPE_FOG)); - } - - ERR_FAIL_COND(!material); - - FogShaderData *shader_data = material->shader_data; - - ERR_FAIL_COND(!shader_data); - - any_uses_time |= shader_data->uses_time; - - Vector3i min = Vector3i(); - Vector3i max = Vector3i(); - Vector3i kernel_size = Vector3i(); - - Vector3 position = fog_volume_instance->transform.get_origin(); - RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume); - Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume); - - if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) { - // Local fog volume. - Vector3i points[8]; - points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - points[2] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - points[3] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - points[4] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - points[5] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - points[6] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - points[7] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform); - - min = Vector3i(int32_t(rb->volumetric_fog->width) - 1, int32_t(rb->volumetric_fog->height) - 1, int32_t(rb->volumetric_fog->depth) - 1); - max = Vector3i(1, 1, 1); - - for (int j = 0; j < 8; j++) { - min = Vector3i(MIN(min.x, points[j].x), MIN(min.y, points[j].y), MIN(min.z, points[j].z)); - max = Vector3i(MAX(max.x, points[j].x), MAX(max.y, points[j].y), MAX(max.z, points[j].z)); - } - - kernel_size = max - min; - } else { - // Volume type global runs on all cells - extents = Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); - min = Vector3i(0, 0, 0); - kernel_size = Vector3i(int32_t(rb->volumetric_fog->width), int32_t(rb->volumetric_fog->height), int32_t(rb->volumetric_fog->depth)); - } - - if (kernel_size.x == 0 || kernel_size.y == 0 || kernel_size.z == 0) { - continue; - } - - volumetric_fog.push_constant.position[0] = position.x; - volumetric_fog.push_constant.position[1] = position.y; - volumetric_fog.push_constant.position[2] = position.z; - volumetric_fog.push_constant.extents[0] = extents.x; - volumetric_fog.push_constant.extents[1] = extents.y; - volumetric_fog.push_constant.extents[2] = extents.z; - volumetric_fog.push_constant.corner[0] = min.x; - volumetric_fog.push_constant.corner[1] = min.y; - volumetric_fog.push_constant.corner[2] = min.z; - volumetric_fog.push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume)); - RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), volumetric_fog.push_constant.transform); - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->fog_uniform_set, VolumetricFogShader::FogSet::FOG_SET_UNIFORMS); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &volumetric_fog.push_constant, sizeof(VolumetricFogShader::FogPushConstant)); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, volumetric_fog.base_uniform_set, VolumetricFogShader::FogSet::FOG_SET_BASE); - if (material->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(material->uniform_set)) { // Material may not have a uniform set. - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, material->uniform_set, VolumetricFogShader::FogSet::FOG_SET_MATERIAL); - } - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, kernel_size.x, kernel_size.y, kernel_size.z); - } - if (any_uses_time || env->volumetric_fog_temporal_reprojection) { - RenderingServerDefault::redraw_request(); - } - - RD::get_singleton()->draw_command_end_label(); - - RD::get_singleton()->compute_list_end(); - } - - if (rb->volumetric_fog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) { - //re create uniform set if needed - Vector<RD::Uniform> uniforms; - Vector<RD::Uniform> copy_uniforms; - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 1; - ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); - if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); - } else { - u.append_id(shadow_atlas->depth); - } - - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 2; - if (directional_shadow.depth.is_valid()) { - u.append_id(directional_shadow.depth); - } else { - u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK)); - } - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 3; - u.append_id(get_omni_light_buffer()); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 4; - u.append_id(get_spot_light_buffer()); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 5; - u.append_id(get_directional_light_buffer()); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 6; - u.append_id(rb->cluster_builder->get_cluster_buffer()); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 7; - u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 8; - u.append_id(rb->volumetric_fog->light_density_map); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 9; - u.append_id(rb->volumetric_fog->fog_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 9; - u.append_id(rb->volumetric_fog->prev_light_density_map); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 10; - u.append_id(shadow_sampler); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 11; - u.append_id(render_buffers_get_voxel_gi_buffer(p_render_buffers)); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 12; - for (int i = 0; i < RendererRD::GI::MAX_VOXEL_GI_INSTANCES; i++) { - u.append_id(rb->rbgi.voxel_gi_textures[i]); - } - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 13; - u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 14; - u.append_id(volumetric_fog.params_ubo); - uniforms.push_back(u); - copy_uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 15; - u.append_id(rb->volumetric_fog->prev_light_density_map); - uniforms.push_back(u); - } - { - RD::Uniform u; -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 16; - u.append_id(rb->volumetric_fog->density_map); - uniforms.push_back(u); - } - { - RD::Uniform u; -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 17; - u.append_id(rb->volumetric_fog->light_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; -#else - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; -#endif - u.binding = 18; - u.append_id(rb->volumetric_fog->emissive_map); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 19; - RID radiance_texture = texture_storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); - RID sky_texture = env->sky.is_valid() ? sky.sky_get_radiance_texture_rd(env->sky) : RID(); - u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture); - uniforms.push_back(u); - } - - rb->volumetric_fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0); - - rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); - - RID aux7 = uniforms.write[7].get_id(0); - RID aux8 = uniforms.write[8].get_id(0); - - uniforms.write[7].set_id(0, aux8); - uniforms.write[8].set_id(0, aux7); - - rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0); - - uniforms.remove_at(8); - uniforms.write[7].set_id(0, aux7); - rb->volumetric_fog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); - } - - bool using_sdfgi = env->volumetric_fog_gi_inject > 0.0001 && env->sdfgi_enabled && (rb->sdfgi != nullptr); - - if (using_sdfgi) { - if (rb->volumetric_fog->sdfgi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->sdfgi_uniform_set)) { - Vector<RD::Uniform> uniforms; - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 0; - u.append_id(gi.sdfgi_ubo); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 1; - u.append_id(rb->sdfgi->ambient_texture); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 2; - u.append_id(rb->sdfgi->occlusion_texture); - uniforms.push_back(u); - } - - rb->volumetric_fog->sdfgi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI), 1); - } - } - - rb->volumetric_fog->length = env->volumetric_fog_length; - rb->volumetric_fog->spread = env->volumetric_fog_detail_spread; - - VolumetricFogShader::ParamsUBO params; - - Vector2 frustum_near_size = p_cam_projection.get_viewport_half_extents(); - Vector2 frustum_far_size = p_cam_projection.get_far_plane_half_extents(); - float z_near = p_cam_projection.get_z_near(); - float z_far = p_cam_projection.get_z_far(); - float fog_end = env->volumetric_fog_length; - - Vector2 fog_far_size = frustum_near_size.lerp(frustum_far_size, (fog_end - z_near) / (z_far - z_near)); - Vector2 fog_near_size; - if (p_cam_projection.is_orthogonal()) { - fog_near_size = fog_far_size; - } else { - fog_near_size = Vector2(); - } - - params.fog_frustum_size_begin[0] = fog_near_size.x; - params.fog_frustum_size_begin[1] = fog_near_size.y; - - params.fog_frustum_size_end[0] = fog_far_size.x; - params.fog_frustum_size_end[1] = fog_far_size.y; - - params.ambient_inject = env->volumetric_fog_ambient_inject * env->ambient_light_energy; - params.z_far = z_far; - - params.fog_frustum_end = fog_end; - - Color ambient_color = env->ambient_light.srgb_to_linear(); - params.ambient_color[0] = ambient_color.r; - params.ambient_color[1] = ambient_color.g; - params.ambient_color[2] = ambient_color.b; - params.sky_contribution = env->ambient_sky_contribution; - - params.fog_volume_size[0] = rb->volumetric_fog->width; - params.fog_volume_size[1] = rb->volumetric_fog->height; - params.fog_volume_size[2] = rb->volumetric_fog->depth; - - params.directional_light_count = p_directional_light_count; - - Color emission = env->volumetric_fog_emission.srgb_to_linear(); - params.base_emission[0] = emission.r * env->volumetric_fog_emission_energy; - params.base_emission[1] = emission.g * env->volumetric_fog_emission_energy; - params.base_emission[2] = emission.b * env->volumetric_fog_emission_energy; - params.base_density = env->volumetric_fog_density; - - Color base_scattering = env->volumetric_fog_scattering.srgb_to_linear(); - params.base_scattering[0] = base_scattering.r; - params.base_scattering[1] = base_scattering.g; - params.base_scattering[2] = base_scattering.b; - params.phase_g = env->volumetric_fog_anisotropy; - - params.detail_spread = env->volumetric_fog_detail_spread; - params.gi_inject = env->volumetric_fog_gi_inject; - - params.cam_rotation[0] = p_cam_transform.basis[0][0]; - params.cam_rotation[1] = p_cam_transform.basis[1][0]; - params.cam_rotation[2] = p_cam_transform.basis[2][0]; - params.cam_rotation[3] = 0; - params.cam_rotation[4] = p_cam_transform.basis[0][1]; - params.cam_rotation[5] = p_cam_transform.basis[1][1]; - params.cam_rotation[6] = p_cam_transform.basis[2][1]; - params.cam_rotation[7] = 0; - params.cam_rotation[8] = p_cam_transform.basis[0][2]; - params.cam_rotation[9] = p_cam_transform.basis[1][2]; - params.cam_rotation[10] = p_cam_transform.basis[2][2]; - params.cam_rotation[11] = 0; - params.filter_axis = 0; - params.max_voxel_gi_instances = env->volumetric_fog_gi_inject > 0.001 ? p_voxel_gi_count : 0; - params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES; - - Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform; - RendererRD::MaterialStorage::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(); - params.cluster_shift = get_shift_from_power_of_2(cluster_size); - - uint32_t cluster_screen_width = (rb->width - 1) / cluster_size + 1; - uint32_t cluster_screen_height = (rb->height - 1) / cluster_size + 1; - params.max_cluster_element_count_div_32 = max_cluster_elements / 32; - params.cluster_type_size = cluster_screen_width * cluster_screen_height * (params.max_cluster_element_count_div_32 + 32); - params.cluster_width = cluster_screen_width; - - params.screen_size[0] = rb->width; - params.screen_size[1] = rb->height; - } - - Basis sky_transform = env->sky_orientation; - sky_transform = sky_transform.inverse() * p_cam_transform.basis; - RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform); - - 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::BARRIER_MASK_COMPUTE); - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set_density, 0); - - 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); - RD::get_singleton()->compute_list_add_barrier(compute_list); - - // Copy fog to history buffer - if (env->volumetric_fog_temporal_reprojection) { - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->copy_uniform_set, 0); - 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(); - - if (volumetric_fog_filter_active) { - 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.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set, 0); - 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 - - params.filter_axis = 1; - RD::get_singleton()->buffer_update(volumetric_fog.params_ubo, 0, sizeof(VolumetricFogShader::ParamsUBO), ¶ms); + if (rb->volumetric_fog) { + RendererRD::Fog::VolumetricFogSettings settings; + settings.rb_size = Vector2i(rb->width, rb->height); + settings.time = time; + settings.is_using_radiance_cubemap_array = is_using_radiance_cubemap_array(); + settings.max_cluster_elements = max_cluster_elements; + settings.volumetric_fog_filter_active = volumetric_fog_filter_active; + + settings.shadow_sampler = shadow_sampler; + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); + settings.shadow_atlas_depth = shadow_atlas ? shadow_atlas->depth : RID(); + settings.voxel_gl_buffer = render_buffers_get_voxel_gi_buffer(p_render_buffers); + settings.omni_light_buffer = get_omni_light_buffer(); + settings.spot_light_buffer = get_spot_light_buffer(); + settings.directional_shadow_depth = directional_shadow.depth; + settings.directional_light_buffer = get_directional_light_buffer(); - compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set2, 0); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth); + settings.vfog = rb->volumetric_fog; + settings.cluster_builder = rb->cluster_builder; + settings.rbgi = &rb->rbgi; + settings.sdfgi = rb->sdfgi; + settings.env = p_environment; + settings.sky = &sky; + settings.gi = &gi; - RD::get_singleton()->compute_list_add_barrier(compute_list); - RD::get_singleton()->draw_command_end_label(); + RendererRD::Fog::get_singleton()->volumetric_fog_update(settings, p_cam_projection, p_cam_transform, p_prev_cam_inv_transform, p_shadow_atlas, p_directional_light_count, p_use_directional_shadows, p_positional_light_count, p_voxel_gi_count, p_fog_volumes); } - - 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.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set, 0); - 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::BARRIER_MASK_RASTER); - - RENDER_TIMESTAMP("< Volumetric Fog"); - RD::get_singleton()->draw_command_end_label(); - RD::get_singleton()->draw_command_end_label(); } bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) { @@ -4930,8 +3466,7 @@ void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bo return; } - RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_render_data->environment); - rb->sdfgi->update_probes(env, sky.sky_owner.get_or_null(env->sky)); + rb->sdfgi->update_probes(p_render_data->environment, sky.sky_owner.get_or_null(environment_get_sky(p_render_data->environment))); } } } @@ -5031,7 +3566,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //use a later barrier } - if (p_render_data->render_buffers.is_valid()) { + if (p_render_data->render_buffers.is_valid() && ss_effects) { if (p_use_ssao || p_use_ssil) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers); ERR_FAIL_COND(!rb); @@ -5056,7 +3591,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool invalidate_uniform_set = true; } - RendererCompositorRD::singleton->get_effects()->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection); + ss_effects->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection); } if (p_use_ssao) { @@ -5113,7 +3648,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool } } -void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info) { +void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); // getting this here now so we can direct call a bunch of things more easily @@ -5308,7 +3843,7 @@ void RendererSceneRenderRD::_debug_draw_cluster(RID p_render_buffers) { } } -void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { +void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) { LightInstance *light_instance = light_instance_owner.get_or_null(p_light); ERR_FAIL_COND(!light_instance); @@ -5329,7 +3864,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, bool flip_y = false; - CameraMatrix light_projection; + Projection light_projection; Transform3D light_transform; if (RSG::light_storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) { @@ -5471,7 +4006,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, 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); + light_instance_set_shadow_transform(p_light, Projection(), light_instance->transform, zfar, 0, 0, 0); } } else { @@ -5480,16 +4015,16 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } } -void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { _render_material(p_cam_transform, p_cam_projection, p_cam_orthogonal, p_instances, p_framebuffer, p_region); } -void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) { +void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) { RendererRD::ParticlesStorage *particles_storage = RendererRD::ParticlesStorage::get_singleton(); ERR_FAIL_COND(!particles_storage->particles_collision_is_heightfield(p_collider)); Vector3 extents = particles_storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale(); - CameraMatrix cm; + Projection cm; cm.set_orthogonal(-extents.x, extents.x, -extents.z, extents.z, 0, extents.y * 2.0); Vector3 cam_pos = p_transform.origin; @@ -5514,15 +4049,15 @@ bool RendererSceneRenderRD::free(RID p_rid) { rb->sdfgi = nullptr; } if (rb->volumetric_fog) { - _volumetric_fog_erase(rb); + memdelete(rb->volumetric_fog); + rb->volumetric_fog = nullptr; } if (rb->cluster_builder) { memdelete(rb->cluster_builder); } render_buffers_owner.free(p_rid); - } else if (environment_owner.owns(p_rid)) { - //not much to delete, just free it - environment_owner.free(p_rid); + } else if (is_environment(p_rid)) { + environment_free(p_rid); } else if (camera_effects_owner.owns(p_rid)) { //not much to delete, just free it camera_effects_owner.free(p_rid); @@ -5589,8 +4124,8 @@ bool RendererSceneRenderRD::free(RID p_rid) { } else if (shadow_atlas_owner.owns(p_rid)) { shadow_atlas_set_size(p_rid, 0); shadow_atlas_owner.free(p_rid); - } else if (fog_volume_instance_owner.owns(p_rid)) { - fog_volume_instance_owner.free(p_rid); + } else if (RendererRD::Fog::get_singleton()->owns_fog_volume_instance(p_rid)) { + RendererRD::Fog::get_singleton()->fog_instance_free(p_rid); } else { return false; } @@ -5662,7 +4197,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto //RID sampled_light; - GeometryInstance *gi = geometry_instance_create(p_base); + RenderGeometryInstance *gi = geometry_instance_create(p_base); uint32_t sc = RSG::mesh_storage->mesh_get_surface_count(p_base); Vector<RID> materials; @@ -5674,7 +4209,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto } } - geometry_instance_set_surface_materials(gi, materials); + gi->set_surface_materials(materials); if (cull_argument.size() == 0) { cull_argument.push_back(nullptr); @@ -5784,8 +4319,6 @@ RendererSceneRenderRD::RendererSceneRenderRD() { } void RendererSceneRenderRD::init() { - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - max_cluster_elements = get_max_elements(); directional_shadow.size = GLOBAL_GET("rendering/shadows/directional_shadow/size"); @@ -5836,124 +4369,7 @@ void RendererSceneRenderRD::init() { } if (is_volumetric_supported()) { - { - // Initialize local fog shader - Vector<String> volumetric_fog_modes; - volumetric_fog_modes.push_back(""); - volumetric_fog.shader.initialize(volumetric_fog_modes); - - material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_shader_funcs); - material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_FOG, _create_fog_material_funcs); - volumetric_fog.volume_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::VolumeUBO)); - } - - { - ShaderCompiler::DefaultIdentifierActions actions; - - actions.renames["TIME"] = "scene_params.time"; - actions.renames["PI"] = _MKSTR(Math_PI); - actions.renames["TAU"] = _MKSTR(Math_TAU); - actions.renames["E"] = _MKSTR(Math_E); - actions.renames["WORLD_POSITION"] = "world.xyz"; - actions.renames["OBJECT_POSITION"] = "params.position"; - actions.renames["UVW"] = "uvw"; - actions.renames["EXTENTS"] = "params.extents"; - actions.renames["ALBEDO"] = "albedo"; - actions.renames["DENSITY"] = "density"; - actions.renames["EMISSION"] = "emission"; - actions.renames["SDF"] = "sdf"; - - actions.usage_defines["SDF"] = "#define SDF_USED\n"; - actions.usage_defines["DENSITY"] = "#define DENSITY_USED\n"; - actions.usage_defines["ALBEDO"] = "#define ALBEDO_USED\n"; - actions.usage_defines["EMISSION"] = "#define EMISSION_USED\n"; - - actions.sampler_array_name = "material_samplers"; - actions.base_texture_binding_index = 1; - actions.texture_layout_set = VolumetricFogShader::FogSet::FOG_SET_MATERIAL; - actions.base_uniform_string = "material."; - - actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; - actions.default_repeat = ShaderLanguage::REPEAT_DISABLE; - actions.global_buffer_array_variable = "global_variables.data"; - - volumetric_fog.compiler.initialize(actions); - } - - { - // default material and shader for fog shader - volumetric_fog.default_shader = material_storage->shader_allocate(); - material_storage->shader_initialize(volumetric_fog.default_shader); - material_storage->shader_set_code(volumetric_fog.default_shader, R"( -// Default fog shader. - -shader_type fog; - -void fog() { - DENSITY = 1.0; - ALBEDO = vec3(1.0); -} -)"); - volumetric_fog.default_material = material_storage->material_allocate(); - material_storage->material_initialize(volumetric_fog.default_material); - material_storage->material_set_shader(volumetric_fog.default_material, volumetric_fog.default_shader); - - FogMaterialData *md = static_cast<FogMaterialData *>(material_storage->material_get_data(volumetric_fog.default_material, RendererRD::SHADER_TYPE_FOG)); - volumetric_fog.default_shader_rd = volumetric_fog.shader.version_get_shader(md->shader_data->version, 0); - - Vector<RD::Uniform> uniforms; - - { - Vector<RID> ids; - ids.resize(12); - RID *ids_ptr = ids.ptrw(); - ids_ptr[0] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[1] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[2] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[3] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[4] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[5] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - ids_ptr[6] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[7] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[8] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[9] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[10] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - ids_ptr[11] = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); - - RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); - uniforms.push_back(u); - } - - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 2; - u.append_id(RendererRD::MaterialStorage::get_singleton()->global_variables_get_storage_buffer()); - uniforms.push_back(u); - } - - volumetric_fog.base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.default_shader_rd, VolumetricFogShader::FogSet::FOG_SET_BASE); - } - { - String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(cluster.max_directional_lights) + "\n"; - defines += "\n#define MAX_SKY_LOD " + itos(get_roughness_layers() - 1) + ".0\n"; - if (is_using_radiance_cubemap_array()) { - defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n"; - } - Vector<String> volumetric_fog_modes; - volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n"); - volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n#define ENABLE_SDFGI\n"); - volumetric_fog_modes.push_back("\n#define MODE_FILTER\n"); - volumetric_fog_modes.push_back("\n#define MODE_FOG\n"); - volumetric_fog_modes.push_back("\n#define MODE_COPY\n"); - - volumetric_fog.process_shader.initialize(volumetric_fog_modes, defines); - volumetric_fog.process_shader_version = volumetric_fog.process_shader.version_create(); - for (int i = 0; i < VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_MAX; i++) { - volumetric_fog.process_pipelines[i] = RD::get_singleton()->compute_pipeline_create(volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, i)); - } - volumetric_fog.params_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(VolumetricFogShader::ParamsUBO)); - } + RendererRD::Fog::get_singleton()->init_fog_shader(cluster.max_directional_lights, get_roughness_layers(), is_using_radiance_cubemap_array()); } { @@ -6000,11 +4416,12 @@ void fog() { copy_effects = memnew(RendererRD::CopyEffects(!can_use_storage)); tone_mapper = memnew(RendererRD::ToneMapper); vrs = memnew(RendererRD::VRS); + if (can_use_storage) { + ss_effects = memnew(RendererRD::SSEffects); + } } RendererSceneRenderRD::~RendererSceneRenderRD() { - RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); - if (bokeh_dof) { memdelete(bokeh_dof); } @@ -6017,6 +4434,9 @@ RendererSceneRenderRD::~RendererSceneRenderRD() { if (vrs) { memdelete(vrs); } + if (ss_effects) { + memdelete(ss_effects); + } for (const KeyValue<int, ShadowCubemap> &E : shadow_cubemaps) { RD::get_singleton()->free(E.value.cubemap); @@ -6031,11 +4451,7 @@ RendererSceneRenderRD::~RendererSceneRenderRD() { } if (is_volumetric_supported()) { - volumetric_fog.process_shader.version_free(volumetric_fog.process_shader_version); - RD::get_singleton()->free(volumetric_fog.volume_ubo); - RD::get_singleton()->free(volumetric_fog.params_ubo); - material_storage->shader_free(volumetric_fog.default_shader); - material_storage->material_free(volumetric_fog.default_material); + RendererRD::Fog::get_singleton()->free_fog_shader(); } memdelete_arr(directional_penumbra_shadow_kernel); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index d11bbd183e..09ec2a9efd 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_SCENE_RENDER_RD_H -#define RENDERING_SERVER_SCENE_RENDER_RD_H +#ifndef RENDERER_SCENE_RENDER_RD_H +#define RENDERER_SCENE_RENDER_RD_H #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" @@ -37,13 +37,12 @@ #include "servers/rendering/renderer_rd/cluster_builder_rd.h" #include "servers/rendering/renderer_rd/effects/bokeh_dof.h" #include "servers/rendering/renderer_rd/effects/copy_effects.h" +#include "servers/rendering/renderer_rd/effects/ss_effects.h" #include "servers/rendering/renderer_rd/effects/tone_mapper.h" #include "servers/rendering/renderer_rd/effects/vrs.h" +#include "servers/rendering/renderer_rd/environment/fog.h" #include "servers/rendering/renderer_rd/environment/gi.h" -#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" -#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h" -#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl.gen.h" +#include "servers/rendering/renderer_rd/environment/sky.h" #include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/rendering_device.h" @@ -52,24 +51,24 @@ struct RenderDataRD { RID render_buffers; Transform3D cam_transform; - CameraMatrix cam_projection; + Projection cam_projection; Vector2 taa_jitter; bool cam_orthogonal = false; // For stereo rendering uint32_t view_count = 1; Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS]; - CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; Transform3D prev_cam_transform; - CameraMatrix prev_cam_projection; + Projection prev_cam_projection; Vector2 prev_taa_jitter; - CameraMatrix prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; float z_near = 0.0; float z_far = 0.0; - const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr; + const PagedArray<RenderGeometryInstance *> *instances = nullptr; const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *reflection_probes = nullptr; const PagedArray<RID> *voxel_gi_instances = nullptr; @@ -98,7 +97,7 @@ struct RenderDataRD { }; class RendererSceneRenderRD : public RendererSceneRender { - friend RendererSceneSkyRD; + friend RendererRD::SkyRD; friend RendererRD::GI; protected: @@ -122,16 +121,16 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 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 Transform3D &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_mesh_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, RendererScene::RenderInfo *p_render_info = nullptr) = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &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_mesh_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, RendererScene::RenderInfo *p_render_info = nullptr) = 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 Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, 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; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &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<RenderGeometryInstance *> &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; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) = 0; - void _debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); + void _debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void _debug_draw_cluster(RID p_render_buffers); RenderBufferData *render_buffers_get_data(RID p_render_buffers); @@ -140,10 +139,11 @@ protected: virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) = 0; virtual RID _render_buffers_get_velocity_texture(RID p_render_buffers) = 0; - void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection); - void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive); - void _process_sss(RID p_render_buffers, const CameraMatrix &p_camera); - void _process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform); + void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection); + void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, const Color &p_metallic_mask, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive); + void _process_sss(RID p_render_buffers, const Projection &p_camera); + void _process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform); + void _copy_framebuffer_to_ssil(RID p_render_buffers); void _process_taa(RID p_render_buffers, RID p_velocity_buffer, float p_z_near, float p_z_far); @@ -160,19 +160,12 @@ protected: void _disable_clear_request(const RenderDataRD *p_render_data); // needed for a single argument calls (material and uv2) - PagedArrayPool<GeometryInstance *> cull_argument_pool; - PagedArray<GeometryInstance *> cull_argument; //need this to exist + PagedArrayPool<RenderGeometryInstance *> cull_argument_pool; + PagedArray<RenderGeometryInstance *> cull_argument; //need this to exist + RendererRD::SSEffects *ss_effects = nullptr; RendererRD::GI gi; - RendererSceneSkyRD sky; - - RendererSceneEnvironmentRD *get_environment(RID p_environment) { - if (p_environment.is_valid()) { - return environment_owner.get_or_null(p_environment); - } else { - return nullptr; - } - }; + RendererRD::SkyRD sky; //used for mobile renderer mostly @@ -209,7 +202,7 @@ private: struct Reflection { RID owner; - RendererSceneSkyRD::ReflectionData data; + RendererRD::SkyRD::ReflectionData data; RID fbs[6]; }; @@ -362,7 +355,7 @@ private: struct LightInstance { struct ShadowTransform { - CameraMatrix camera; + Projection camera; Transform3D transform; float farplane; float split; @@ -404,21 +397,10 @@ private: mutable RID_Owner<LightInstance> light_instance_owner; - /* FOG VOLUMES */ - - struct FogVolumeInstance { - RID volume; - Transform3D transform; - bool active = false; - }; - - mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner; - /* ENVIRONMENT */ RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM; bool ssao_half_size = false; - bool ssao_using_half_size = false; float ssao_adaptive_target = 0.5; int ssao_blur_passes = 2; float ssao_fadeout_from = 50.0; @@ -436,8 +418,6 @@ private: bool glow_high_quality = false; RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW; - mutable RID_Owner<RendererSceneEnvironmentRD, true> environment_owner; - /* CAMERA EFFECTS */ struct CameraEffects { @@ -469,8 +449,6 @@ private: ClusterBuilderSharedDataRD cluster_builder_shared; ClusterBuilderRD *current_cluster_builder = nullptr; - struct VolumetricFog; - struct RenderBuffers { RenderBufferData *data = nullptr; int internal_width = 0; @@ -506,8 +484,8 @@ private: Vector<View> views; RendererRD::GI::SDFGI *sdfgi = nullptr; - VolumetricFog *volumetric_fog = nullptr; RendererRD::GI::RenderBuffersGI rbgi; + RendererRD::Fog::VolumetricFog *volumetric_fog = nullptr; ClusterBuilderRD *cluster_builder = nullptr; @@ -561,47 +539,14 @@ private: RID downsample_uniform_set; - RID last_frame; - Vector<RID> last_frame_slices; - - CameraMatrix last_frame_projection; + Projection last_frame_projection; Transform3D last_frame_transform; - struct SSAO { - RID ao_deinterleaved; - Vector<RID> ao_deinterleaved_slices; - RID ao_pong; - Vector<RID> ao_pong_slices; - RID ao_final; - RID importance_map[2]; - RID depth_texture_view; - - RID gather_uniform_set; - RID importance_map_uniform_set; - } ssao; - - struct SSIL { - RID ssil_final; - RID deinterleaved; - Vector<RID> deinterleaved_slices; - RID pong; - Vector<RID> pong_slices; - RID edges; - Vector<RID> edges_slices; - RID importance_map[2]; - RID depth_texture_view; - - RID gather_uniform_set; - RID importance_map_uniform_set; - RID projection_uniform_set; - } ssil; + RendererRD::SSEffects::SSAORenderBuffers ssao; + RendererRD::SSEffects::SSILRenderBuffers ssil; } ss_effects; - struct SSR { - RID normal_scaled; - RID depth_scaled; - RID blur_radius[2]; - } ssr; + RendererRD::SSEffects::SSRRenderBuffers ssr; struct TAA { RID history; @@ -780,203 +725,6 @@ private: bool depth_prepass_used; // this does not seem used anywhere... } render_state; - struct VolumetricFog { - enum { - MAX_TEMPORAL_FRAMES = 16 - }; - - uint32_t width = 0; - uint32_t height = 0; - uint32_t depth = 0; - - float length; - float spread; - - RID light_density_map; - RID prev_light_density_map; - RID fog_map; - RID density_map; - RID light_map; - RID emissive_map; - - RID fog_uniform_set; - RID copy_uniform_set; - RID process_uniform_set_density; - RID process_uniform_set; - RID process_uniform_set2; - RID sdfgi_uniform_set; - RID sky_uniform_set; - - int last_shadow_filter = -1; - }; - - struct VolumetricFogShader { - enum FogSet { - FOG_SET_BASE, - FOG_SET_UNIFORMS, - FOG_SET_MATERIAL, - FOG_SET_MAX, - }; - - struct FogPushConstant { - float position[3]; - float pad; - - float extents[3]; - float pad2; - - int32_t corner[3]; - uint32_t shape; - - float transform[16]; - }; - - struct VolumeUBO { - float fog_frustum_size_begin[2]; - float fog_frustum_size_end[2]; - - float fog_frustum_end; - float z_near; - float z_far; - float time; - - int32_t fog_volume_size[3]; - uint32_t directional_light_count; - - uint32_t use_temporal_reprojection; - uint32_t temporal_frame; - float detail_spread; - float temporal_blend; - - float to_prev_view[16]; - float transform[16]; - }; - - ShaderCompiler compiler; - VolumetricFogShaderRD shader; - FogPushConstant push_constant; - RID volume_ubo; - - RID default_shader; - RID default_material; - RID default_shader_rd; - - RID base_uniform_set; - - RID params_ubo; - - enum { - VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY, - VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI, - VOLUMETRIC_FOG_PROCESS_SHADER_FILTER, - VOLUMETRIC_FOG_PROCESS_SHADER_FOG, - VOLUMETRIC_FOG_PROCESS_SHADER_COPY, - VOLUMETRIC_FOG_PROCESS_SHADER_MAX, - }; - - struct ParamsUBO { - float fog_frustum_size_begin[2]; - float fog_frustum_size_end[2]; - - float fog_frustum_end; - float ambient_inject; - float z_far; - uint32_t filter_axis; - - float ambient_color[3]; - float sky_contribution; - - int32_t fog_volume_size[3]; - uint32_t directional_light_count; - - float base_emission[3]; - float base_density; - - float base_scattering[3]; - float phase_g; - - float detail_spread; - float gi_inject; - uint32_t max_voxel_gi_instances; - uint32_t cluster_type_size; - - float screen_size[2]; - uint32_t cluster_shift; - uint32_t cluster_width; - - 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]; - float radiance_inverse_xform[12]; - }; - - VolumetricFogProcessShaderRD process_shader; - - RID process_shader_version; - RID process_pipelines[VOLUMETRIC_FOG_PROCESS_SHADER_MAX]; - - } volumetric_fog; - - uint32_t volumetric_fog_depth = 128; - uint32_t volumetric_fog_size = 128; - bool volumetric_fog_filter_active = true; - - Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform); - void _volumetric_fog_erase(RenderBuffers *rb); - void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); - - struct FogShaderData : public RendererRD::ShaderData { - bool valid = false; - RID version; - - RID pipeline; - HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; - Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; - - Vector<uint32_t> ubo_offsets; - uint32_t ubo_size = 0; - - String path; - String code; - HashMap<StringName, HashMap<int, RID>> default_texture_params; - - bool uses_time = false; - - virtual void set_code(const String &p_Code); - virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); - virtual void get_param_list(List<PropertyInfo> *p_param_list) const; - virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; - virtual bool is_param_texture(const StringName &p_param) const; - virtual bool is_animated() const; - virtual bool casts_shadows() const; - virtual Variant get_default_parameter(const StringName &p_parameter) const; - virtual RS::ShaderNativeSourceCode get_native_source_code() const; - - FogShaderData() {} - virtual ~FogShaderData(); - }; - - struct FogMaterialData : public RendererRD::MaterialData { - FogShaderData *shader_data = nullptr; - RID uniform_set; - bool uniform_set_updated; - - virtual void set_render_priority(int p_priority) {} - virtual void set_next_pass(RID p_pass) {} - virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); - virtual ~FogMaterialData(); - }; - - RendererRD::ShaderData *_create_fog_shader_func(); - static RendererRD::ShaderData *_create_fog_shader_funcs(); - - RendererRD::MaterialData *_create_fog_material_func(FogShaderData *p_shader); - static RendererRD::MaterialData *_create_fog_material_funcs(RendererRD::ShaderData *p_shader); - RID shadow_sampler; uint64_t scene_pass = 0; @@ -991,11 +739,18 @@ private: uint32_t max_cluster_elements = 512; - 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_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); + void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); + + /* Volumetric Fog */ + + uint32_t volumetric_fog_size = 128; + uint32_t volumetric_fog_depth = 128; + bool volumetric_fog_filter_active = true; + + void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); public: - virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0; - virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0; + static RendererSceneRenderRD *get_singleton() { return singleton; } /* GI */ @@ -1057,65 +812,16 @@ public: /* ENVIRONMENT API */ - virtual RID environment_allocate() override; - virtual void environment_initialize(RID p_rid) override; - - virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override; - virtual void environment_set_sky(RID p_env, RID p_sky) override; - virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) override; - virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override; - virtual void environment_set_bg_color(RID p_env, const Color &p_color) override; - virtual void environment_set_bg_energy(RID p_env, float p_energy) override; - virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override; - virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override; - - virtual RS::EnvironmentBG environment_get_background(RID p_env) const override; - RID environment_get_sky(RID p_env) const; - float environment_get_sky_custom_fov(RID p_env) const; - Basis environment_get_sky_orientation(RID p_env) const; - Color environment_get_bg_color(RID p_env) const; - float environment_get_bg_energy(RID p_env) const; - virtual int environment_get_canvas_max_layer(RID p_env) const override; - Color environment_get_ambient_light_color(RID p_env) const; - RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const; - float environment_get_ambient_light_energy(RID p_env) const; - float environment_get_ambient_sky_contribution(RID p_env) const; - RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const; - - virtual bool is_environment(RID p_env) const override; - - virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override; virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) override; virtual void environment_glow_set_use_high_quality(bool p_enable) override; - 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) override; - bool environment_is_fog_enabled(RID p_env) const; - Color environment_get_fog_light_color(RID p_env) const; - float environment_get_fog_light_energy(RID p_env) const; - float environment_get_fog_sun_scatter(RID p_env) const; - float environment_get_fog_density(RID p_env) const; - float environment_get_fog_height(RID p_env) const; - float environment_get_fog_height_density(RID p_env) const; - float environment_get_fog_aerial_perspective(RID p_env) const; - - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) override; - virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override; virtual void environment_set_volumetric_fog_filter_active(bool p_enable) override; - 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) override; - virtual 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; 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) override; - virtual void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override; + virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override; - bool environment_is_ssao_enabled(RID p_env) const; - float environment_get_ssao_ao_affect(RID p_env) const; - float environment_get_ssao_light_affect(RID p_env) const; - bool environment_is_ssil_enabled(RID p_env) const; - 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, int 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; + virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override; virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override; virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override; @@ -1123,9 +829,6 @@ public: virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override; RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const; - virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override; - virtual 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; - virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override; /* CAMERA EFFECTS */ @@ -1150,7 +853,7 @@ public: virtual RID light_instance_create(RID p_light) override; virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override; virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override; - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override; + virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override; virtual void light_instance_mark_visible(RID p_light_instance) override; _FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) { @@ -1199,7 +902,7 @@ public: return Rect2(x / float(shadow_atlas->size), y / float(shadow_atlas->size), width / float(shadow_atlas->size), height / float(shadow_atlas->size)); } - _FORCE_INLINE_ CameraMatrix light_instance_get_shadow_camera(RID p_light_instance, int p_index) { + _FORCE_INLINE_ Projection light_instance_get_shadow_camera(RID p_light_instance, int p_index) { LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].camera; } @@ -1393,7 +1096,7 @@ public: virtual RID voxel_gi_instance_create(RID p_base) override; virtual void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override; virtual bool voxel_gi_needs_update(RID p_probe) const override; - virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override; + virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) override; virtual void voxel_gi_set_quality(RS::VoxelGIQuality p_quality) override { gi.voxel_gi_quality = p_quality; } /* render buffers */ @@ -1402,7 +1105,7 @@ public: virtual RD::DataFormat _render_buffers_get_color_format(); virtual bool _render_buffers_can_be_storage(); virtual RID render_buffers_create() override; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override; virtual void gi_set_use_half_resolution(bool p_enable) override; RID render_buffers_get_depth_texture(RID p_render_buffers); @@ -1436,11 +1139,11 @@ public: virtual void update_uniform_sets(){}; - virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info = nullptr) override; + virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info = nullptr) override; - virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; - virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override; virtual void set_scene_pass(uint64_t p_pass) override { scene_pass = p_pass; @@ -1519,4 +1222,4 @@ public: ~RendererSceneRenderRD(); }; -#endif // RASTERIZER_SCENE_RD_H +#endif // RENDERER_SCENE_RENDER_RD_H diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index 04e05380f1..c9b6d09d4c 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -177,7 +177,7 @@ void ShaderRD::_build_variant_code(StringBuilder &builder, uint32_t p_variant, c for (const KeyValue<StringName, CharString> &E : p_version->code_sections) { builder.append(String("#define ") + String(E.key) + "_CODE_USED\n"); } -#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED) +#if defined(MACOS_ENABLED) || defined(IOS_ENABLED) builder.append("#define MOLTENVK_USED\n"); #endif } break; @@ -476,7 +476,9 @@ void ShaderRD::_compile_version(Version *p_version) { #if 1 - RendererThreadPool::singleton->thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &ShaderRD::_compile_variant, p_version, variant_defines.size(), -1, true, SNAME("ShaderCompilation")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); + #else for (int i = 0; i < variant_defines.size(); i++) { _compile_variant(i, p_version); diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index 12f57b0178..2ea6965c09 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl @@ -138,10 +138,10 @@ layout(set = 0, binding = 7) uniform texture2D sdf_texture; layout(set = 0, binding = 8) uniform sampler material_samplers[12]; -layout(set = 0, binding = 9, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 9, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; /* SET1: Is reserved for the material */ diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl index a416891ff2..d85ab3af2e 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl @@ -32,12 +32,17 @@ layout(push_constant, std430) uniform Params { bool use_half_res; uint metallic_mask; - mat4 projection; + uint view_index; + uint pad1; + uint pad2; + uint pad3; } params; +#include "screen_space_reflection_inc.glsl" + vec2 view_to_screen(vec3 view_pos, out float w) { - vec4 projected = params.projection * vec4(view_pos, 1.0); + vec4 projected = scene_data.projection[params.view_index] * vec4(view_pos, 1.0); projected.xyz /= projected.w; projected.xy = projected.xy * 0.5 + 0.5; w = projected.w; @@ -46,24 +51,16 @@ vec2 view_to_screen(vec3 view_pos, out float w) { #define M_PI 3.14159265359 -vec3 reconstructCSPosition(vec2 S, float z) { - if (params.orthogonal) { - return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z); - } else { - return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z); - } -} - void main() { // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC.xy, params.screen_size))) { //too large, do nothing return; } vec2 pixel_size = 1.0 / vec2(params.screen_size); - vec2 uv = vec2(ssC) * pixel_size; + vec2 uv = vec2(ssC.xy) * pixel_size; uv += pixel_size * 0.5; @@ -77,7 +74,12 @@ void main() { normal = normalize(normal); normal.y = -normal.y; //because this code reads flipped - vec3 view_dir = normalize(vertex); + vec3 view_dir; + if (sc_multiview) { + view_dir = normalize(vertex + scene_data.eye_offset[params.view_index].xyz); + } else { + view_dir = normalize(vertex); + } vec3 ray_dir = normalize(reflect(view_dir, normal)); if (dot(ray_dir, normal) < 0.001) { @@ -154,6 +156,11 @@ void main() { // convert to linear depth depth = imageLoad(source_depth, ivec2(pos - 0.5)).r; + if (sc_multiview) { + depth = depth * 2.0 - 1.0; + depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near)); + depth = -depth; + } z_from = z_to; z_to = z / w; @@ -222,13 +229,16 @@ void main() { blur_radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h); } } + + // Isn't this going to be overwritten after our endif? final_color = imageLoad(source_diffuse, ivec2((final_pos - 0.5) * pixel_size)); imageStore(blur_radius_image, ssC, vec4(blur_radius / 255.0)); //stored in r8 -#endif +#endif // MODE_ROUGH final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend); + //change blend by metallic vec4 metallic_mask = unpackUnorm4x8(params.metallic_mask); final_color.a *= dot(metallic_mask, texelFetch(source_metallic, ssC << 1, 0)); diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl index 20e1712496..a63d60e0b2 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl @@ -22,7 +22,7 @@ layout(push_constant, std430) uniform Params { bool orthogonal; float edge_tolerance; int increment; - uint pad; + uint view_index; ivec2 screen_size; bool vertical; @@ -30,6 +30,8 @@ layout(push_constant, std430) uniform Params { } params; +#include "screen_space_reflection_inc.glsl" + #define GAUSS_TABLE_SIZE 15 const float gauss_table[GAUSS_TABLE_SIZE + 1] = float[]( @@ -64,14 +66,6 @@ float gauss_weight(float p_val) { #define M_PI 3.14159265359 -vec3 reconstructCSPosition(vec2 S, float z) { - if (params.orthogonal) { - return vec3((S.xy * params.proj_info.xy + params.proj_info.zw), z); - } else { - return vec3((S.xy * params.proj_info.xy + params.proj_info.zw) * z, z); - } -} - void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, ivec2 texcoord, ivec2 increment, vec3 p_pos, vec3 normal, float p_limit_radius) { for (int i = 1; i < params.steps; i++) { float d = float(i * params.increment); @@ -110,7 +104,7 @@ void main() { // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC.xy, params.screen_size))) { //too large, do nothing return; } @@ -130,13 +124,13 @@ void main() { ivec2 direction = ivec2(params.increment, 0); #endif float depth = imageLoad(source_depth, ssC).r; - vec3 pos = reconstructCSPosition(vec2(ssC) + 0.5, depth); + vec3 pos = reconstructCSPosition(vec2(ssC.xy) + 0.5, depth); vec3 normal = imageLoad(source_normal, ssC).xyz * 2.0 - 1.0; normal = normalize(normal); normal.y = -normal.y; - do_filter(accum, accum_radius, divisor, ssC, direction, pos, normal, radius); - do_filter(accum, accum_radius, divisor, ssC, -direction, pos, normal, radius); + do_filter(accum, accum_radius, divisor, ssC.xy, direction, pos, normal, radius); + do_filter(accum, accum_radius, divisor, ssC.xy, -direction, pos, normal, radius); if (divisor > 0.0) { accum /= divisor; diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_inc.glsl new file mode 100644 index 0000000000..26405ab040 --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_inc.glsl @@ -0,0 +1,28 @@ +layout(constant_id = 0) const bool sc_multiview = false; + +layout(set = 4, binding = 0, std140) uniform SceneData { + mat4x4 projection[2]; + mat4x4 inv_projection[2]; + vec4 eye_offset[2]; +} +scene_data; + +vec3 reconstructCSPosition(vec2 screen_pos, float z) { + if (sc_multiview) { + vec4 pos; + pos.xy = (2.0 * vec2(screen_pos) / vec2(params.screen_size)) - 1.0; + pos.z = z * 2.0 - 1.0; + pos.w = 1.0; + + pos = scene_data.inv_projection[params.view_index] * pos; + pos.xyz /= pos.w; + + return pos.xyz; + } else { + if (params.orthogonal) { + return vec3((screen_pos.xy * params.proj_info.xy + params.proj_info.zw), z); + } else { + return vec3((screen_pos.xy * params.proj_info.xy + params.proj_info.zw) * z, z); + } + } +} diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl index 3f537e273a..a7da0812df 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl @@ -6,6 +6,11 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +/* Specialization Constants (Toggles) */ + +layout(constant_id = 0) const bool sc_multiview = false; + +/* inputs */ layout(set = 0, binding = 0) uniform sampler2D source_ssr; layout(set = 1, binding = 0) uniform sampler2D source_depth; layout(set = 1, binding = 1) uniform sampler2D source_normal; @@ -28,7 +33,7 @@ void main() { // Pixel being shaded ivec2 ssC = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing + if (any(greaterThanEqual(ssC.xy, params.screen_size))) { //too large, do nothing return; } //do not filter, SSR will generate arctifacts if this is done @@ -57,13 +62,19 @@ void main() { normal.xyz += nr.xyz * 2.0 - 1.0; normal.w += nr.w; - d = d * 2.0 - 1.0; - if (params.orthogonal) { - d = ((d + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0; + if (sc_multiview) { + // we're doing a full unproject so we need the value as is. + depth += d; } else { - d = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - d * (params.camera_z_far - params.camera_z_near)); + // unproject our Z value so we can use it directly. + d = d * 2.0 - 1.0; + if (params.orthogonal) { + d = ((d + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0; + } else { + d = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - d * (params.camera_z_far - params.camera_z_near)); + } + depth += -d; } - depth += -d; } color /= 4.0; @@ -71,17 +82,22 @@ void main() { normal.xyz = normalize(normal.xyz / 4.0) * 0.5 + 0.5; normal.w /= 4.0; } else { - color = texelFetch(source_ssr, ssC << 1, 0); - depth = texelFetch(source_depth, ssC << 1, 0).r; - normal = texelFetch(source_normal, ssC << 1, 0); - - depth = depth * 2.0 - 1.0; - if (params.orthogonal) { - depth = ((depth + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0; - } else { - depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near)); + ivec2 ofs = ssC << 1; + + color = texelFetch(source_ssr, ofs, 0); + depth = texelFetch(source_depth, ofs, 0).r; + normal = texelFetch(source_normal, ofs, 0); + + if (!sc_multiview) { + // unproject our Z value so we can use it directly. + depth = depth * 2.0 - 1.0; + if (params.orthogonal) { + depth = ((depth + (params.camera_z_far + params.camera_z_near) / (params.camera_z_far - params.camera_z_near)) * (params.camera_z_far - params.camera_z_near)) / 2.0; + } else { + depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near)); + } + depth = -depth; } - depth = -depth; } imageStore(dest_ssr, ssC, color); diff --git a/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl b/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl new file mode 100644 index 0000000000..c62144fdaf --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl @@ -0,0 +1,112 @@ +#[vertex] + +#version 450 + +#VERSION_DEFINES + +#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview) +#extension GL_EXT_multiview : enable +#endif + +#ifdef USE_MULTIVIEW +#ifdef has_VK_KHR_multiview +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +// !BAS! This needs to become an input once we implement our fallback! +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#else // USE_MULTIVIEW +// Set to zero, not supported in non stereo +#define ViewIndex 0 +#endif //USE_MULTIVIEW + +#ifdef USE_MULTIVIEW +layout(location = 0) out vec3 uv_interp; +#else // USE_MULTIVIEW +layout(location = 0) out vec2 uv_interp; +#endif //USE_MULTIVIEW + +void main() { + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + +#ifdef USE_MULTIVIEW + uv_interp = vec3(base_arr[gl_VertexIndex], ViewIndex); + + gl_Position = vec4(uv_interp.xy * 2.0 - 1.0, 0.0, 1.0); +#else + uv_interp = base_arr[gl_VertexIndex]; + + gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); +#endif +} + +#[fragment] + +#version 450 + +#VERSION_DEFINES + +#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview) +#extension GL_EXT_multiview : enable +#endif + +#ifdef USE_MULTIVIEW +#ifdef has_VK_KHR_multiview +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +// !BAS! This needs to become an input once we implement our fallback! +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#else // USE_MULTIVIEW +// Set to zero, not supported in non stereo +#define ViewIndex 0 +#endif //USE_MULTIVIEW + +#ifdef USE_MULTIVIEW +layout(location = 0) in vec3 uv_interp; +#else // USE_MULTIVIEW +layout(location = 0) in vec2 uv_interp; +#endif //USE_MULTIVIEW + +#ifdef USE_MULTIVIEW +layout(set = 0, binding = 0) uniform sampler2DArray specular; +#else // USE_MULTIVIEW +layout(set = 0, binding = 0) uniform sampler2D specular; +#endif //USE_MULTIVIEW + +#ifdef MODE_SSR + +#ifdef USE_MULTIVIEW +layout(set = 1, binding = 0) uniform sampler2DArray ssr; +#else // USE_MULTIVIEW +layout(set = 1, binding = 0) uniform sampler2D ssr; +#endif //USE_MULTIVIEW + +#endif + +#ifdef MODE_MERGE + +#ifdef USE_MULTIVIEW +layout(set = 2, binding = 0) uniform sampler2DArray diffuse; +#else // USE_MULTIVIEW +layout(set = 2, binding = 0) uniform sampler2D diffuse; +#endif //USE_MULTIVIEW + +#endif + +layout(location = 0) out vec4 frag_color; + +void main() { + frag_color.rgb = texture(specular, uv_interp).rgb; + frag_color.a = 0.0; +#ifdef MODE_SSR + + vec4 ssr_color = texture(ssr, uv_interp); + frag_color.rgb = mix(frag_color.rgb, ssr_color.rgb, ssr_color.a); +#endif + +#ifdef MODE_MERGE + frag_color += texture(diffuse, uv_interp); +#endif + //added using additive blend +} diff --git a/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl index 134aae5ce7..134aae5ce7 100644 --- a/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl diff --git a/servers/rendering/renderer_rd/shaders/ssao.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao.glsl index 2a87e273bc..2a87e273bc 100644 --- a/servers/rendering/renderer_rd/shaders/ssao.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssao.glsl diff --git a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl index f42734c46d..f42734c46d 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl diff --git a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl index 04f98964e8..04f98964e8 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl diff --git a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl index f6a9a92fac..f6a9a92fac 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl diff --git a/servers/rendering/renderer_rd/shaders/ssil.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil.glsl index 513791dfbf..513791dfbf 100644 --- a/servers/rendering/renderer_rd/shaders/ssil.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssil.glsl diff --git a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl index 47c56571f6..47c56571f6 100644 --- a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl diff --git a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl index 6b6b02739d..6b6b02739d 100644 --- a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl diff --git a/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl index 9e86ac0cf0..9e86ac0cf0 100644 --- a/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl diff --git a/servers/rendering/renderer_rd/shaders/environment/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl index 5f34e7112d..6ea8cb1377 100644 --- a/servers/rendering/renderer_rd/shaders/environment/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl @@ -659,7 +659,7 @@ void main() { if (sc_use_vrs) { ivec2 vrs_pos; - // Currenty we use a 16x16 texel, possibly some day make this configurable. + // Currently we use a 16x16 texel, possibly some day make this configurable. if (sc_half_res) { vrs_pos = pos >> 3; } else { diff --git a/servers/rendering/renderer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index 5b4594da99..e825020a4e 100644 --- a/servers/rendering/renderer_rd/shaders/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -77,10 +77,10 @@ params; layout(set = 0, binding = 0) uniform sampler material_samplers[12]; -layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; layout(set = 0, binding = 2, std140) uniform SceneData { bool volumetric_fog_enabled; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl index eee609fb48..4658afd02d 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl @@ -21,17 +21,17 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; #define DENSITY_SCALE 1024.0 -#include "cluster_data_inc.glsl" -#include "light_data_inc.glsl" +#include "../cluster_data_inc.glsl" +#include "../light_data_inc.glsl" #define M_PI 3.14159265359 layout(set = 0, binding = 1) uniform sampler material_samplers[12]; -layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; layout(push_constant, std430) uniform Params { vec3 position; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index fdbd7d3e35..e74cfad65c 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -19,8 +19,8 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #endif -#include "cluster_data_inc.glsl" -#include "light_data_inc.glsl" +#include "../cluster_data_inc.glsl" +#include "../light_data_inc.glsl" #define M_PI 3.14159265359 diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index acb62b812e..4369bddc83 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -25,10 +25,10 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; layout(set = 0, binding = 1) uniform sampler material_samplers[12]; -layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; /* Set 1: FRAME AND PARTICLE DATA */ diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl index 0c23de96c3..f0717294ef 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl @@ -129,10 +129,10 @@ layout(set = 0, binding = 13, std430) restrict readonly buffer Decals { } decals; -layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalShaderUniformData { vec4 data[]; } -global_variables; +global_shader_uniforms; struct SDFVoxelGICascadeData { vec3 position; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl index 7413d8730a..98ad674ce0 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -118,10 +118,10 @@ layout(set = 0, binding = 13, std430) restrict readonly buffer Decals { } decals; -layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 14, std430) restrict readonly buffer GlobalShaderUniformData { highp vec4 data[]; } -global_variables; +global_shader_uniforms; /* Set 1: Render Pass (changes per render pass) */ diff --git a/servers/rendering/renderer_rd/shaders/specular_merge.glsl b/servers/rendering/renderer_rd/shaders/specular_merge.glsl deleted file mode 100644 index 3579c35cce..0000000000 --- a/servers/rendering/renderer_rd/shaders/specular_merge.glsl +++ /dev/null @@ -1,53 +0,0 @@ -#[vertex] - -#version 450 - -#VERSION_DEFINES - -layout(location = 0) out vec2 uv_interp; - -void main() { - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); - uv_interp = base_arr[gl_VertexIndex]; - - gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); -} - -#[fragment] - -#version 450 - -#VERSION_DEFINES - -layout(location = 0) in vec2 uv_interp; - -layout(set = 0, binding = 0) uniform sampler2D specular; - -#ifdef MODE_SSR - -layout(set = 1, binding = 0) uniform sampler2D ssr; - -#endif - -#ifdef MODE_MERGE - -layout(set = 2, binding = 0) uniform sampler2D diffuse; - -#endif - -layout(location = 0) out vec4 frag_color; - -void main() { - frag_color.rgb = texture(specular, uv_interp).rgb; - frag_color.a = 0.0; -#ifdef MODE_SSR - - vec4 ssr_color = texture(ssr, uv_interp); - frag_color.rgb = mix(frag_color.rgb, ssr_color.rgb, ssr_color.a); -#endif - -#ifdef MODE_MERGE - frag_color += texture(diffuse, uv_interp); -#endif - //added using additive blend -} diff --git a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl index ddd984ad83..b0a0839836 100644 --- a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl @@ -189,7 +189,7 @@ vec3 sample_catmull_rom_9(sampler2D stex, vec2 uv, vec2 resolution) { // Source: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1 // License: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae - // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding + // We're going to sample a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding // down the sample location to get the exact center of our "starting" texel. The starting texel will be at // location [1, 1] in the grid, where [0, 0] is the top left corner. vec2 sample_pos = uv * resolution; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index fb25e4da7e..2fb8f92fff 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -368,4 +368,4 @@ public: } // namespace RendererRD -#endif // !LIGHT_STORAGE_RD_H +#endif // LIGHT_STORAGE_RD_H diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index fcd25852eb..0bac26213b 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -172,75 +172,96 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } break; case ShaderLanguage::TYPE_IVEC2: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 2 * p_array_size; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 2 * p_array_size; - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 2, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - } else { - gui[j] = 0; - gui[j + 1] = 0; + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 2, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + } + gui[j + 2] = 0; // ignored + gui[j + 3] = 0; // ignored } - gui[j + 2] = 0; // ignored - gui[j + 3] = 0; // ignored + } else { + Vector2i v = value; + gui[0] = v.x; + gui[1] = v.y; } } break; case ShaderLanguage::TYPE_IVEC3: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 3 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 3, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - gui[j + 2] = r[i + 2]; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 3 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 3, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + gui[j + 2] = r[i + 2]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored } - gui[j + 3] = 0; // ignored + } else { + Vector3i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; } } break; case ShaderLanguage::TYPE_IVEC4: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 4 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0; i < count; i += 4) { - if (i < s) { - gui[i] = r[i]; - gui[i + 1] = r[i + 1]; - gui[i + 2] = r[i + 2]; - gui[i + 3] = r[i + 3]; - } else { - gui[i] = 0; - gui[i + 1] = 0; - gui[i + 2] = 0; - gui[i + 3] = 0; + if (p_array_size <= 0) { + p_array_size = 1; } + int count = 4 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0; i < count; i += 4) { + if (i < s) { + gui[i] = r[i]; + gui[i + 1] = r[i + 1]; + gui[i + 2] = r[i + 2]; + gui[i + 3] = r[i + 3]; + } else { + gui[i] = 0; + gui[i + 1] = 0; + gui[i + 2] = 0; + gui[i + 3] = 0; + } + } + } else { + Vector4i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } break; case ShaderLanguage::TYPE_UINT: { @@ -267,75 +288,96 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } break; case ShaderLanguage::TYPE_UVEC2: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 2 * p_array_size; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 2 * p_array_size; - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 2, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - } else { - gui[j] = 0; - gui[j + 1] = 0; + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 2, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + } + gui[j + 2] = 0; // ignored + gui[j + 3] = 0; // ignored } - gui[j + 2] = 0; // ignored - gui[j + 3] = 0; // ignored + } else { + Vector2i v = value; + gui[0] = v.x; + gui[1] = v.y; } } break; case ShaderLanguage::TYPE_UVEC3: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 3 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 3, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - gui[j + 2] = r[i + 2]; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + if (p_array_size <= 0) { + p_array_size = 1; } - gui[j + 3] = 0; // ignored + int count = 3 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 3, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + gui[j + 2] = r[i + 2]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored + } + } else { + Vector3i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; } } break; case ShaderLanguage::TYPE_UVEC4: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 4 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0; i < count; i++) { - if (i < s) { - gui[i] = r[i]; - gui[i + 1] = r[i + 1]; - gui[i + 2] = r[i + 2]; - gui[i + 3] = r[i + 3]; - } else { - gui[i] = 0; - gui[i + 1] = 0; - gui[i + 2] = 0; - gui[i + 3] = 0; + if (p_array_size <= 0) { + p_array_size = 1; } + int count = 4 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0; i < count; i++) { + if (i < s) { + gui[i] = r[i]; + gui[i + 1] = r[i + 1]; + gui[i + 2] = r[i + 2]; + gui[i + 3] = r[i + 3]; + } else { + gui[i] = 0; + gui[i + 1] = 0; + gui[i + 2] = 0; + gui[i + 3] = 0; + } + } + } else { + Vector4i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } break; case ShaderLanguage::TYPE_FLOAT: { @@ -514,13 +556,20 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[1] = v.y; gui[2] = v.z; gui[3] = v.w; - } else { + } else if (value.get_type() == Variant::PLANE) { Plane v = value; gui[0] = v.normal.x; gui[1] = v.normal.y; gui[2] = v.normal.z; gui[3] = v.d; + } else { + Vector4 v = value; + + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } } break; @@ -670,7 +719,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[i + 15] = 1; } } - } else { + } else if (value.get_type() == Variant::TRANSFORM3D) { Transform3D v = value; gui[0] = v.basis.rows[0][0]; gui[1] = v.basis.rows[1][0]; @@ -691,6 +740,13 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[13] = v.origin.y; gui[14] = v.origin.z; gui[15] = 1; + } else { + Projection v = value; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + gui[i * 4 + j] = v.matrix[i][j]; + } + } } } break; default: { @@ -911,7 +967,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { //this is a global variable, get the index to it - GlobalVariables::Variable *gv = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *gv = material_storage->global_shader_uniforms.variables.getptr(E.key); uint32_t index = 0; if (gv) { index = gv->buffer_index; @@ -967,9 +1023,9 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag if (uses_global_buffer != (global_buffer_E != nullptr)) { if (uses_global_buffer) { - global_buffer_E = material_storage->global_variables.materials_using_buffer.push_back(self); + global_buffer_E = material_storage->global_shader_uniforms.materials_using_buffer.push_back(self); } else { - material_storage->global_variables.materials_using_buffer.erase(global_buffer_E); + material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E); global_buffer_E = nullptr; } } @@ -980,20 +1036,20 @@ MaterialData::~MaterialData() { if (global_buffer_E) { //unregister global buffers - material_storage->global_variables.materials_using_buffer.erase(global_buffer_E); + material_storage->global_shader_uniforms.materials_using_buffer.erase(global_buffer_E); } if (global_texture_E) { //unregister global textures for (const KeyValue<StringName, uint64_t> &E : used_global_textures) { - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } } //unregister material from those using global textures - material_storage->global_variables.materials_using_texture.erase(global_texture_E); + material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E); } if (uniform_buffer.is_valid()) { @@ -1023,7 +1079,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet if (p_texture_uniforms[i].global) { uses_global_textures = true; - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(uniform_name); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name); if (v) { if (v->buffer_index >= 0) { WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); @@ -1193,7 +1249,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet if (E.value != global_textures_pass) { to_delete.push_back(E.key); - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); + GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } @@ -1207,9 +1263,9 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet //handle registering/unregistering global textures if (uses_global_textures != (global_texture_E != nullptr)) { if (uses_global_textures) { - global_texture_E = material_storage->global_variables.materials_using_texture.push_back(self); + global_texture_E = material_storage->global_shader_uniforms.materials_using_texture.push_back(self); } else { - material_storage->global_variables.materials_using_texture.erase(global_texture_E); + material_storage->global_shader_uniforms.materials_using_texture.erase(global_texture_E); global_texture_E = nullptr; } } @@ -1441,22 +1497,22 @@ MaterialStorage::MaterialStorage() { shader_data_request_func[i] = nullptr; } - static_assert(sizeof(GlobalVariables::Value) == 16); + static_assert(sizeof(GlobalShaderUniforms::Value) == 16); - global_variables.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); - global_variables.buffer_values = memnew_arr(GlobalVariables::Value, global_variables.buffer_size); - memset(global_variables.buffer_values, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size); - global_variables.buffer_usage = memnew_arr(GlobalVariables::ValueUsage, global_variables.buffer_size); - global_variables.buffer_dirty_regions = memnew_arr(bool, global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); - memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE); - global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size); + global_shader_uniforms.buffer_size = MAX(4096, (int)GLOBAL_GET("rendering/limits/global_shader_variables/buffer_size")); + global_shader_uniforms.buffer_values = memnew_arr(GlobalShaderUniforms::Value, global_shader_uniforms.buffer_size); + memset(global_shader_uniforms.buffer_values, 0, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer_usage = memnew_arr(GlobalShaderUniforms::ValueUsage, global_shader_uniforms.buffer_size); + global_shader_uniforms.buffer_dirty_regions = memnew_arr(bool, global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); + memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE); + global_shader_uniforms.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size); } MaterialStorage::~MaterialStorage() { - memdelete_arr(global_variables.buffer_values); - memdelete_arr(global_variables.buffer_usage); - memdelete_arr(global_variables.buffer_dirty_regions); - RD::get_singleton()->free(global_variables.buffer); + memdelete_arr(global_shader_uniforms.buffer_values); + memdelete_arr(global_shader_uniforms.buffer_usage); + memdelete_arr(global_shader_uniforms.buffer_dirty_regions); + RD::get_singleton()->free(global_shader_uniforms.buffer); // buffers @@ -1577,17 +1633,17 @@ void MaterialStorage::sampler_rd_configure_custom(float p_mipmap_bias) { } } -/* GLOBAL VARIABLE API */ +/* GLOBAL SHADER UNIFORM API */ -int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) { +int32_t MaterialStorage::_global_shader_uniform_allocate(uint32_t p_elements) { int32_t idx = 0; - while (idx + p_elements <= global_variables.buffer_size) { - if (global_variables.buffer_usage[idx].elements == 0) { + while (idx + p_elements <= global_shader_uniforms.buffer_size) { + if (global_shader_uniforms.buffer_usage[idx].elements == 0) { bool valid = true; for (uint32_t i = 1; i < p_elements; i++) { - if (global_variables.buffer_usage[idx + i].elements > 0) { + if (global_shader_uniforms.buffer_usage[idx + i].elements > 0) { valid = false; - idx += i + global_variables.buffer_usage[idx + i].elements; + idx += i + global_shader_uniforms.buffer_usage[idx + i].elements; break; } } @@ -1598,17 +1654,17 @@ int32_t MaterialStorage::_global_variable_allocate(uint32_t p_elements) { return idx; } else { - idx += global_variables.buffer_usage[idx].elements; + idx += global_shader_uniforms.buffer_usage[idx].elements; } } return -1; } -void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) { +void MaterialStorage::_global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; bool b = p_value; bv.x = b ? 1.0 : 0.0; bv.y = 0.0; @@ -1617,7 +1673,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_BVEC2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1625,7 +1681,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0.0; } break; case RS::GLOBAL_VAR_TYPE_BVEC3: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1633,7 +1689,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0.0; } break; case RS::GLOBAL_VAR_TYPE_BVEC4: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; uint32_t bvec = p_value; bv.x = (bvec & 1) ? 1.0 : 0.0; bv.y = (bvec & 2) ? 1.0 : 0.0; @@ -1641,7 +1697,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = (bvec & 8) ? 1.0 : 0.0; } break; case RS::GLOBAL_VAR_TYPE_INT: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; int32_t v = p_value; bv.x = v; bv.y = 0; @@ -1649,7 +1705,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC2: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector2i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1657,7 +1713,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC3: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector3i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1665,7 +1721,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_IVEC4: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Vector<int32_t> v = p_value; bv.x = v.size() >= 1 ? v[0] : 0; bv.y = v.size() >= 2 ? v[1] : 0; @@ -1673,7 +1729,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size() >= 4 ? v[3] : 0; } break; case RS::GLOBAL_VAR_TYPE_RECT2I: { - GlobalVariables::ValueInt &bv = *(GlobalVariables::ValueInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueInt &bv = *(GlobalShaderUniforms::ValueInt *)&global_shader_uniforms.buffer_values[p_index]; Rect2i v = p_value; bv.x = v.position.x; bv.y = v.position.y; @@ -1681,7 +1737,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size.y; } break; case RS::GLOBAL_VAR_TYPE_UINT: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; uint32_t v = p_value; bv.x = v; bv.y = 0; @@ -1689,7 +1745,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC2: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector2i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1697,7 +1753,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC3: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector3i v = p_value; bv.x = v.x; bv.y = v.y; @@ -1705,7 +1761,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_UVEC4: { - GlobalVariables::ValueUInt &bv = *(GlobalVariables::ValueUInt *)&global_variables.buffer_values[p_index]; + GlobalShaderUniforms::ValueUInt &bv = *(GlobalShaderUniforms::ValueUInt *)&global_shader_uniforms.buffer_values[p_index]; Vector<int32_t> v = p_value; bv.x = v.size() >= 1 ? v[0] : 0; bv.y = v.size() >= 2 ? v[1] : 0; @@ -1713,7 +1769,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size() >= 4 ? v[3] : 0; } break; case RS::GLOBAL_VAR_TYPE_FLOAT: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; float v = p_value; bv.x = v; bv.y = 0; @@ -1721,7 +1777,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Vector2 v = p_value; bv.x = v.x; bv.y = v.y; @@ -1729,7 +1785,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC3: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Vector3 v = p_value; bv.x = v.x; bv.y = v.y; @@ -1737,7 +1793,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = 0; } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Plane v = p_value; bv.x = v.normal.x; bv.y = v.normal.y; @@ -1745,14 +1801,14 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.d; } break; case RS::GLOBAL_VAR_TYPE_COLOR: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Color v = p_value; bv.x = v.r; bv.y = v.g; bv.z = v.b; bv.w = v.a; - GlobalVariables::Value &bv_linear = global_variables.buffer_values[p_index + 1]; + GlobalShaderUniforms::Value &bv_linear = global_shader_uniforms.buffer_values[p_index + 1]; v = v.srgb_to_linear(); bv_linear.x = v.r; bv_linear.y = v.g; @@ -1761,7 +1817,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_RECT2: { - GlobalVariables::Value &bv = global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value &bv = global_shader_uniforms.buffer_values[p_index]; Rect2 v = p_value; bv.x = v.position.x; bv.y = v.position.y; @@ -1769,7 +1825,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob bv.w = v.size.y; } break; case RS::GLOBAL_VAR_TYPE_MAT2: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Vector<float> m2 = p_value; if (m2.size() < 4) { m2.resize(4); @@ -1786,7 +1842,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_MAT3: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Basis v = p_value; bv[0].x = v.rows[0][0]; bv[0].y = v.rows[1][0]; @@ -1805,7 +1861,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_MAT4: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Vector<float> m2 = p_value; if (m2.size() < 16) { @@ -1834,7 +1890,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Transform2D v = p_value; bv[0].x = v.columns[0][0]; bv[0].y = v.columns[0][1]; @@ -1853,7 +1909,7 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { - GlobalVariables::Value *bv = &global_variables.buffer_values[p_index]; + GlobalShaderUniforms::Value *bv = &global_shader_uniforms.buffer_values[p_index]; Transform3D v = p_value; bv[0].x = v.basis.rows[0][0]; bv[0].y = v.basis.rows[1][0]; @@ -1882,15 +1938,15 @@ void MaterialStorage::_global_variable_store_in_buffer(int32_t p_index, RS::Glob } } -void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { +void MaterialStorage::_global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements) { int32_t prev_chunk = -1; for (int32_t i = 0; i < p_elements; i++) { - int32_t chunk = (p_index + i) / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + int32_t chunk = (p_index + i) / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; if (chunk != prev_chunk) { - if (!global_variables.buffer_dirty_regions[chunk]) { - global_variables.buffer_dirty_regions[chunk] = true; - global_variables.buffer_dirty_region_count++; + if (!global_shader_uniforms.buffer_dirty_regions[chunk]) { + global_shader_uniforms.buffer_dirty_regions[chunk] = true; + global_shader_uniforms.buffer_dirty_region_count++; } } @@ -1898,16 +1954,16 @@ void MaterialStorage::_global_variable_mark_buffer_dirty(int32_t p_index, int32_ } } -void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) { - ERR_FAIL_COND(global_variables.variables.has(p_name)); - GlobalVariables::Variable gv; +void MaterialStorage::global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) { + ERR_FAIL_COND(global_shader_uniforms.variables.has(p_name)); + GlobalShaderUniforms::Variable gv; gv.type = p_type; gv.value = p_value; gv.buffer_index = -1; if (p_type >= RS::GLOBAL_VAR_TYPE_SAMPLER2D) { //is texture - global_variables.must_update_texture_materials = true; //normally there are none + global_shader_uniforms.must_update_texture_materials = true; //normally there are none } else { gv.buffer_elements = 1; if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) { @@ -1924,56 +1980,56 @@ void MaterialStorage::global_variable_add(const StringName &p_name, RS::GlobalVa } //is vector, allocate in buffer and update index - gv.buffer_index = _global_variable_allocate(gv.buffer_elements); + gv.buffer_index = _global_shader_uniform_allocate(gv.buffer_elements); ERR_FAIL_COND_MSG(gv.buffer_index < 0, vformat("Failed allocating global variable '%s' out of buffer memory. Consider increasing it in the Project Settings.", String(p_name))); - global_variables.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + global_shader_uniforms.buffer_usage[gv.buffer_index].elements = gv.buffer_elements; + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); - global_variables.must_update_buffer_materials = true; //normally there are none + global_shader_uniforms.must_update_buffer_materials = true; //normally there are none } - global_variables.variables[p_name] = gv; + global_shader_uniforms.variables[p_name] = gv; } -void MaterialStorage::global_variable_remove(const StringName &p_name) { - if (!global_variables.variables.has(p_name)) { +void MaterialStorage::global_shader_uniform_remove(const StringName &p_name) { + if (!global_shader_uniforms.variables.has(p_name)) { return; } - const GlobalVariables::Variable &gv = global_variables.variables[p_name]; + const GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; if (gv.buffer_index >= 0) { - global_variables.buffer_usage[gv.buffer_index].elements = 0; - global_variables.must_update_buffer_materials = true; + global_shader_uniforms.buffer_usage[gv.buffer_index].elements = 0; + global_shader_uniforms.must_update_buffer_materials = true; } else { - global_variables.must_update_texture_materials = true; + global_shader_uniforms.must_update_texture_materials = true; } - global_variables.variables.erase(p_name); + global_shader_uniforms.variables.erase(p_name); } -Vector<StringName> MaterialStorage::global_variable_get_list() const { +Vector<StringName> MaterialStorage::global_shader_uniform_get_list() const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } Vector<StringName> names; - for (const KeyValue<StringName, GlobalVariables::Variable> &E : global_variables.variables) { + for (const KeyValue<StringName, GlobalShaderUniforms::Variable> &E : global_shader_uniforms.variables) { names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); return names; } -void MaterialStorage::global_variable_set(const StringName &p_name, const Variant &p_value) { - ERR_FAIL_COND(!global_variables.variables.has(p_name)); - GlobalVariables::Variable &gv = global_variables.variables[p_name]; +void MaterialStorage::global_shader_uniform_set(const StringName &p_name, const Variant &p_value) { + ERR_FAIL_COND(!global_shader_uniforms.variables.has(p_name)); + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.value = p_value; if (gv.override.get_type() == Variant::NIL) { if (gv.buffer_index >= 0) { //buffer - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -1986,26 +2042,26 @@ void MaterialStorage::global_variable_set(const StringName &p_name, const Varian } } -void MaterialStorage::global_variable_set_override(const StringName &p_name, const Variant &p_value) { - if (!global_variables.variables.has(p_name)) { +void MaterialStorage::global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) { + if (!global_shader_uniforms.variables.has(p_name)) { return; //variable may not exist } ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); - GlobalVariables::Variable &gv = global_variables.variables[p_name]; + GlobalShaderUniforms::Variable &gv = global_shader_uniforms.variables[p_name]; gv.override = p_value; if (gv.buffer_index >= 0) { //buffer if (gv.override.get_type() == Variant::NIL) { - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.value); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.value); } else { - _global_variable_store_in_buffer(gv.buffer_index, gv.type, gv.override); + _global_shader_uniform_store_in_buffer(gv.buffer_index, gv.type, gv.override); } - _global_variable_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); + _global_shader_uniform_mark_buffer_dirty(gv.buffer_index, gv.buffer_elements); } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -2017,35 +2073,35 @@ void MaterialStorage::global_variable_set_override(const StringName &p_name, con } } -Variant MaterialStorage::global_variable_get(const StringName &p_name) const { +Variant MaterialStorage::global_shader_uniform_get(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance."); } - if (!global_variables.variables.has(p_name)) { + if (!global_shader_uniforms.variables.has(p_name)) { return Variant(); } - return global_variables.variables[p_name].value; + return global_shader_uniforms.variables[p_name].value; } -RS::GlobalVariableType MaterialStorage::global_variable_get_type_internal(const StringName &p_name) const { - if (!global_variables.variables.has(p_name)) { +RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type_internal(const StringName &p_name) const { + if (!global_shader_uniforms.variables.has(p_name)) { return RS::GLOBAL_VAR_TYPE_MAX; } - return global_variables.variables[p_name].type; + return global_shader_uniforms.variables[p_name].type; } -RS::GlobalVariableType MaterialStorage::global_variable_get_type(const StringName &p_name) const { +RS::GlobalShaderUniformType MaterialStorage::global_shader_uniform_get_type(const StringName &p_name) const { if (!Engine::get_singleton()->is_editor_hint()) { ERR_FAIL_V_MSG(RS::GLOBAL_VAR_TYPE_MAX, "This function should never be used outside the editor, it can severely damage performance."); } - return global_variable_get_type_internal(p_name); + return global_shader_uniform_get_type_internal(p_name); } -void MaterialStorage::global_variables_load_settings(bool p_load_textures) { +void MaterialStorage::global_shader_uniforms_load_settings(bool p_load_textures) { List<PropertyInfo> settings; ProjectSettings::get_singleton()->get_property_list(&settings); @@ -2090,11 +2146,11 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { "samplerCube", }; - RS::GlobalVariableType gvtype = RS::GLOBAL_VAR_TYPE_MAX; + RS::GlobalShaderUniformType gvtype = RS::GLOBAL_VAR_TYPE_MAX; for (int i = 0; i < RS::GLOBAL_VAR_TYPE_MAX; i++) { if (global_var_type_names[i] == type) { - gvtype = RS::GlobalVariableType(i); + gvtype = RS::GlobalShaderUniformType(i); break; } } @@ -2116,47 +2172,47 @@ void MaterialStorage::global_variables_load_settings(bool p_load_textures) { value = resource; } - if (global_variables.variables.has(name)) { + if (global_shader_uniforms.variables.has(name)) { //has it, update it - global_variable_set(name, value); + global_shader_uniform_set(name, value); } else { - global_variable_add(name, gvtype, value); + global_shader_uniform_add(name, gvtype, value); } } } } -void MaterialStorage::global_variables_clear() { - global_variables.variables.clear(); //not right but for now enough +void MaterialStorage::global_shader_uniforms_clear() { + global_shader_uniforms.variables.clear(); //not right but for now enough } -RID MaterialStorage::global_variables_get_storage_buffer() const { - return global_variables.buffer; +RID MaterialStorage::global_shader_uniforms_get_storage_buffer() const { + return global_shader_uniforms.buffer; } -int32_t MaterialStorage::global_variables_instance_allocate(RID p_instance) { - ERR_FAIL_COND_V(global_variables.instance_buffer_pos.has(p_instance), -1); - int32_t pos = _global_variable_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); - global_variables.instance_buffer_pos[p_instance] = pos; //save anyway +int32_t MaterialStorage::global_shader_uniforms_instance_allocate(RID p_instance) { + ERR_FAIL_COND_V(global_shader_uniforms.instance_buffer_pos.has(p_instance), -1); + int32_t pos = _global_shader_uniform_allocate(ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES); + global_shader_uniforms.instance_buffer_pos[p_instance] = pos; //save anyway ERR_FAIL_COND_V_MSG(pos < 0, -1, "Too many instances using shader instance variables. Increase buffer size in Project Settings."); - global_variables.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; + global_shader_uniforms.buffer_usage[pos].elements = ShaderLanguage::MAX_INSTANCE_UNIFORM_INDICES; return pos; } -void MaterialStorage::global_variables_instance_free(RID p_instance) { - ERR_FAIL_COND(!global_variables.instance_buffer_pos.has(p_instance)); - int32_t pos = global_variables.instance_buffer_pos[p_instance]; +void MaterialStorage::global_shader_uniforms_instance_free(RID p_instance) { + ERR_FAIL_COND(!global_shader_uniforms.instance_buffer_pos.has(p_instance)); + int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos >= 0) { - global_variables.buffer_usage[pos].elements = 0; + global_shader_uniforms.buffer_usage[pos].elements = 0; } - global_variables.instance_buffer_pos.erase(p_instance); + global_shader_uniforms.instance_buffer_pos.erase(p_instance); } -void MaterialStorage::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) { - if (!global_variables.instance_buffer_pos.has(p_instance)) { +void MaterialStorage::global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) { + if (!global_shader_uniforms.instance_buffer_pos.has(p_instance)) { return; //just not allocated, ignore } - int32_t pos = global_variables.instance_buffer_pos[p_instance]; + int32_t pos = global_shader_uniforms.instance_buffer_pos[p_instance]; if (pos < 0) { return; //again, not allocated, ignore @@ -2191,57 +2247,57 @@ void MaterialStorage::global_variables_instance_update(RID p_instance, int p_ind pos += p_index; - _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_variables.buffer_values[pos], true); //instances always use linear color in this renderer - _global_variable_mark_buffer_dirty(pos, 1); + _fill_std140_variant_ubo_value(datatype, 0, p_value, (uint8_t *)&global_shader_uniforms.buffer_values[pos], true); //instances always use linear color in this renderer + _global_shader_uniform_mark_buffer_dirty(pos, 1); } -void MaterialStorage::_update_global_variables() { +void MaterialStorage::_update_global_shader_uniforms() { MaterialStorage *material_storage = MaterialStorage::get_singleton(); - if (global_variables.buffer_dirty_region_count > 0) { - uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE; - if (total_regions / global_variables.buffer_dirty_region_count <= 4) { + if (global_shader_uniforms.buffer_dirty_region_count > 0) { + uint32_t total_regions = global_shader_uniforms.buffer_size / GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; + if (total_regions / global_shader_uniforms.buffer_dirty_region_count <= 4) { // 25% of regions dirty, just update all buffer - RD::get_singleton()->buffer_update(global_variables.buffer, 0, sizeof(GlobalVariables::Value) * global_variables.buffer_size, global_variables.buffer_values); - memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * total_regions); + RD::get_singleton()->buffer_update(global_shader_uniforms.buffer, 0, sizeof(GlobalShaderUniforms::Value) * global_shader_uniforms.buffer_size, global_shader_uniforms.buffer_values); + memset(global_shader_uniforms.buffer_dirty_regions, 0, sizeof(bool) * total_regions); } else { - uint32_t region_byte_size = sizeof(GlobalVariables::Value) * GlobalVariables::BUFFER_DIRTY_REGION_SIZE; + uint32_t region_byte_size = sizeof(GlobalShaderUniforms::Value) * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE; for (uint32_t i = 0; i < total_regions; i++) { - if (global_variables.buffer_dirty_regions[i]) { - RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, &global_variables.buffer_values[i * GlobalVariables::BUFFER_DIRTY_REGION_SIZE]); + if (global_shader_uniforms.buffer_dirty_regions[i]) { + RD::get_singleton()->buffer_update(global_shader_uniforms.buffer, i * region_byte_size, region_byte_size, &global_shader_uniforms.buffer_values[i * GlobalShaderUniforms::BUFFER_DIRTY_REGION_SIZE]); - global_variables.buffer_dirty_regions[i] = false; + global_shader_uniforms.buffer_dirty_regions[i] = false; } } } - global_variables.buffer_dirty_region_count = 0; + global_shader_uniforms.buffer_dirty_region_count = 0; } - if (global_variables.must_update_buffer_materials) { + if (global_shader_uniforms.must_update_buffer_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (const RID &E : global_variables.materials_using_buffer) { + for (const RID &E : global_shader_uniforms.materials_using_buffer) { Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); //wtf material_storage->_material_queue_update(material, true, false); } - global_variables.must_update_buffer_materials = false; + global_shader_uniforms.must_update_buffer_materials = false; } - if (global_variables.must_update_texture_materials) { + if (global_shader_uniforms.must_update_texture_materials) { // only happens in the case of a buffer variable added or removed, // so not often. - for (const RID &E : global_variables.materials_using_texture) { + for (const RID &E : global_shader_uniforms.materials_using_texture) { Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); //wtf material_storage->_material_queue_update(material, false, true); } - global_variables.must_update_texture_materials = false; + global_shader_uniforms.must_update_texture_materials = false; } } @@ -2341,6 +2397,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { } if (shader->data) { + shader->data->set_path_hint(shader->path_hint); shader->data->set_code(p_code); } @@ -2351,6 +2408,16 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { } } +void MaterialStorage::shader_set_path_hint(RID p_shader, const String &p_path) { + Shader *shader = shader_owner.get_or_null(p_shader); + ERR_FAIL_COND(!shader); + + shader->path_hint = p_path; + if (shader->data) { + shader->data->set_path_hint(p_path); + } +} + String MaterialStorage::shader_get_code(RID p_shader) const { Shader *shader = shader_owner.get_or_null(p_shader); ERR_FAIL_COND_V(!shader, String()); diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index e35d5e7669..ad40a86dd0 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -31,7 +31,7 @@ #ifndef MATERIAL_STORAGE_RD_H #define MATERIAL_STORAGE_RD_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" @@ -57,6 +57,7 @@ enum ShaderType { struct ShaderData { virtual void set_code(const String &p_Code) = 0; + virtual void set_path_hint(const String &p_hint) = 0; virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index) = 0; virtual void get_param_list(List<PropertyInfo> *p_param_list) const = 0; @@ -77,6 +78,7 @@ struct Material; struct Shader { ShaderData *data = nullptr; String code; + String path_hint; ShaderType type; HashMap<StringName, HashMap<int, RID>> default_texture_parameter; HashSet<Material *> owners; @@ -133,15 +135,15 @@ struct Material { update_element(this) {} }; -/* Global variable structs */ -struct GlobalVariables { +/* Global shader uniform structs */ +struct GlobalShaderUniforms { enum { BUFFER_DIRTY_REGION_SIZE = 1024 }; struct Variable { HashSet<RID> texture_materials; // materials using this - RS::GlobalVariableType type; + RS::GlobalShaderUniformType type; Variant value; Variant override; int32_t buffer_index; //for vectors @@ -207,13 +209,13 @@ private: RID quad_index_buffer; RID quad_index_array; - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - GlobalVariables global_variables; + GlobalShaderUniforms global_shader_uniforms; - int32_t _global_variable_allocate(uint32_t p_elements); - void _global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value); - void _global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements); + int32_t _global_shader_uniform_allocate(uint32_t p_elements); + void _global_shader_uniform_store_in_buffer(int32_t p_index, RS::GlobalShaderUniformType p_type, const Variant &p_value); + void _global_shader_uniform_mark_buffer_dirty(int32_t p_index, int32_t p_elements); /* SHADER API */ @@ -300,7 +302,7 @@ public: p_array[11] = p_mtx.origin.z; } - static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { + static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { p_array[i * 4 + j] = p_mtx.matrix[i][j]; @@ -331,28 +333,28 @@ public: RID get_quad_index_array() { return quad_index_array; } - /* GLOBAL VARIABLE API */ + /* GLOBAL SHADER UNIFORM API */ - void _update_global_variables(); + void _update_global_shader_uniforms(); - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) override; - virtual void global_variable_remove(const StringName &p_name) override; - virtual Vector<StringName> global_variable_get_list() const override; + virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) override; + virtual void global_shader_uniform_remove(const StringName &p_name) override; + virtual Vector<StringName> global_shader_uniform_get_list() const override; - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) override; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) override; - virtual Variant global_variable_get(const StringName &p_name) const override; - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const override; - RS::GlobalVariableType global_variable_get_type_internal(const StringName &p_name) const; + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) override; + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) override; + virtual Variant global_shader_uniform_get(const StringName &p_name) const override; + virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const override; + RS::GlobalShaderUniformType global_shader_uniform_get_type_internal(const StringName &p_name) const; - virtual void global_variables_load_settings(bool p_load_textures = true) override; - virtual void global_variables_clear() override; + virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) override; + virtual void global_shader_uniforms_clear() override; - virtual int32_t global_variables_instance_allocate(RID p_instance) override; - virtual void global_variables_instance_free(RID p_instance) override; - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) override; + virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) override; + virtual void global_shader_uniforms_instance_free(RID p_instance) override; + virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) override; - RID global_variables_get_storage_buffer() const; + RID global_shader_uniforms_get_storage_buffer() const; /* SHADER API */ @@ -364,6 +366,7 @@ public: virtual void shader_free(RID p_rid) override; virtual void shader_set_code(RID p_shader, const String &p_code) override; + virtual void shader_set_path_hint(RID p_shader, const String &p_path) override; virtual String shader_get_code(RID p_shader) const override; virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const override; @@ -421,4 +424,4 @@ public: } // namespace RendererRD -#endif // !MATERIAL_STORAGE_RD_H +#endif // MATERIAL_STORAGE_RD_H diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index 9cdda6bfca..396fe9b6a6 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -703,4 +703,4 @@ public: } // namespace RendererRD -#endif // !MESH_STORAGE_RD_H +#endif // MESH_STORAGE_RD_H diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 5200e0d318..1e5511eeda 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -112,7 +112,7 @@ ParticlesStorage::ParticlesStorage() { actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; - actions.global_buffer_array_variable = "global_variables.data"; + actions.global_buffer_array_variable = "global_shader_uniforms.data"; particles_shader.compiler.initialize(actions); } @@ -164,7 +164,7 @@ void process() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.append_id(material_storage->global_variables_get_storage_buffer()); + u.append_id(material_storage->global_shader_uniforms_get_storage_buffer()); uniforms.push_back(u); } @@ -1512,6 +1512,9 @@ bool ParticlesStorage::particles_is_inactive(RID p_particles) const { /* Particles SHADER */ +void ParticlesStorage::ParticlesShaderData::set_path_hint(const String &p_path) { + path = p_path; +} void ParticlesStorage::ParticlesShaderData::set_code(const String &p_code) { ParticlesStorage *particles_storage = ParticlesStorage::get_singleton(); //compile @@ -1609,7 +1612,22 @@ void ParticlesStorage::ParticlesShaderData::get_param_list(List<PropertyInfo> *p } } + String last_group; for (const KeyValue<int, StringName> &E : order) { + String group = uniforms[E.value].group; + if (!uniforms[E.value].subgroup.is_empty()) { + group += "::" + uniforms[E.value].subgroup; + } + + if (group != last_group) { + PropertyInfo pi; + pi.usage = PROPERTY_USAGE_GROUP; + pi.name = group; + p_param_list->push_back(pi); + + last_group = group; + } + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); pi.name = E.value; p_param_list->push_back(pi); diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index 70ac6f0349..75f995deeb 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -363,6 +363,7 @@ private: uint32_t userdata_count = 0; virtual void set_code(const String &p_Code); + virtual void set_path_hint(const String &p_hint); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); virtual void get_param_list(List<PropertyInfo> *p_param_list) const; virtual void get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const; @@ -561,4 +562,4 @@ public: } // namespace RendererRD -#endif // !PARTICLES_STORAGE_RD_H +#endif // PARTICLES_STORAGE_RD_H diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index abf364b8b4..6d7ea5184a 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -398,9 +398,8 @@ TextureStorage::TextureStorage() { tformat.format = RD::DATA_FORMAT_R8_UINT; tformat.width = 4; tformat.height = 4; - tformat.array_layers = 1; tformat.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_VRS_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT; - tformat.texture_type = RD::TEXTURE_TYPE_2D_ARRAY; + tformat.texture_type = RD::TEXTURE_TYPE_2D; Vector<uint8_t> pv; pv.resize(4 * 4); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index 8807f78f6e..1eb4a283ca 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -191,8 +191,8 @@ struct Decal { float upper_fade = 0.3; float lower_fade = 0.3; bool distance_fade = false; - float distance_fade_begin = 10; - float distance_fade_length = 1; + float distance_fade_begin = 40.0; + float distance_fade_length = 10.0; float normal_fade = 0.0; Dependency dependency; @@ -576,4 +576,4 @@ public: } // namespace RendererRD -#endif // !_TEXTURE_STORAGE_RD_H +#endif // TEXTURE_STORAGE_RD_H diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp index a1f62c16c7..b4dccfabc7 100644 --- a/servers/rendering/renderer_rd/storage_rd/utilities.cpp +++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp @@ -272,7 +272,7 @@ String Utilities::get_captured_timestamp_name(uint32_t p_index) const { /* MISC */ void Utilities::update_dirty_resources() { - MaterialStorage::get_singleton()->_update_global_variables(); //must do before materials, so it can queue them for update + MaterialStorage::get_singleton()->_update_global_shader_uniforms(); //must do before materials, so it can queue them for update MaterialStorage::get_singleton()->_update_queued_materials(); MeshStorage::get_singleton()->_update_dirty_multimeshes(); MeshStorage::get_singleton()->_update_dirty_skeletons(); diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.h b/servers/rendering/renderer_rd/storage_rd/utilities.h index 979e984546..a80eb8510e 100644 --- a/servers/rendering/renderer_rd/storage_rd/utilities.h +++ b/servers/rendering/renderer_rd/storage_rd/utilities.h @@ -119,4 +119,4 @@ public: } // namespace RendererRD -#endif // !UTILITIES_RD_H +#endif // UTILITIES_RD_H diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.h b/servers/rendering/renderer_rd/uniform_set_cache_rd.h index af22a48716..abf110730b 100644 --- a/servers/rendering/renderer_rd/uniform_set_cache_rd.h +++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef UNIFORM_SET_CACHE_H -#define UNIFORM_SET_CACHE_H +#ifndef UNIFORM_SET_CACHE_RD_H +#define UNIFORM_SET_CACHE_RD_H #include "core/templates/local_vector.h" #include "core/templates/paged_allocator.h" @@ -220,4 +220,4 @@ public: ~UniformSetCacheRD(); }; -#endif // UNIFORMSETCACHE_H +#endif // UNIFORM_SET_CACHE_RD_H diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index d635c7065d..852fe89cd0 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERINGSERVERSCENE_H -#define RENDERINGSERVERSCENE_H +#ifndef RENDERER_SCENE_H +#define RENDERER_SCENE_H #include "servers/rendering_server.h" #include "servers/xr/xr_interface.h" @@ -122,6 +122,7 @@ public: virtual RID environment_allocate() = 0; virtual void environment_initialize(RID p_rid) = 0; + // Background 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; virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0; @@ -131,41 +132,152 @@ public: virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) = 0; - virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0; - 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 RS::EnvironmentBG environment_get_background(RID p_Env) const = 0; + virtual RID environment_get_sky(RID p_env) const = 0; + virtual float environment_get_sky_custom_fov(RID p_env) const = 0; + virtual Basis environment_get_sky_orientation(RID p_env) const = 0; + virtual Color environment_get_bg_color(RID p_env) const = 0; + virtual float environment_get_bg_energy(RID p_env) const = 0; + virtual int environment_get_canvas_max_layer(RID p_env) const = 0; + virtual RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const = 0; + virtual Color environment_get_ambient_light(RID p_env) const = 0; + virtual float environment_get_ambient_light_energy(RID p_env) const = 0; + virtual float environment_get_ambient_sky_contribution(RID p_env) const = 0; + virtual RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const = 0; + + // Tonemap + virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; + + virtual RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const = 0; + virtual float environment_get_exposure(RID p_env) const = 0; + virtual float environment_get_white(RID p_env) const = 0; + virtual bool environment_get_auto_exposure(RID p_env) const = 0; + virtual float environment_get_min_luminance(RID p_env) const = 0; + virtual float environment_get_max_luminance(RID p_env) const = 0; + virtual float environment_get_auto_exp_speed(RID p_env) const = 0; + virtual float environment_get_auto_exp_scale(RID p_env) const = 0; + virtual uint64_t environment_get_auto_exposure_version(RID p_env) const = 0; + + // Fog + 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; + virtual bool environment_get_fog_enabled(RID p_env) const = 0; + virtual Color environment_get_fog_light_color(RID p_env) const = 0; + virtual float environment_get_fog_light_energy(RID p_env) const = 0; + virtual float environment_get_fog_sun_scatter(RID p_env) const = 0; + virtual float environment_get_fog_density(RID p_env) const = 0; + virtual float environment_get_fog_height(RID p_env) const = 0; + virtual float environment_get_fog_height_density(RID p_env) const = 0; + virtual float environment_get_fog_aerial_perspective(RID p_env) const = 0; + + // Volumetric Fog virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) = 0; + virtual bool environment_get_volumetric_fog_enabled(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_density(RID p_env) const = 0; + virtual Color environment_get_volumetric_fog_scattering(RID p_env) const = 0; + virtual Color environment_get_volumetric_fog_emission(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_emission_energy(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_anisotropy(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_length(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_detail_spread(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_gi_inject(RID p_env) const = 0; + virtual bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const = 0; + virtual float environment_get_volumetric_fog_ambient_inject(RID p_env) const = 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; + // Glow + + virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0; + + virtual bool environment_get_glow_enabled(RID p_env) const = 0; + virtual Vector<float> environment_get_glow_levels(RID p_env) const = 0; + virtual float environment_get_glow_intensity(RID p_env) const = 0; + virtual float environment_get_glow_strength(RID p_env) const = 0; + virtual float environment_get_glow_bloom(RID p_env) const = 0; + virtual float environment_get_glow_mix(RID p_env) const = 0; + virtual RS::EnvironmentGlowBlendMode environment_get_glow_blend_mode(RID p_env) const = 0; + virtual float environment_get_glow_hdr_bleed_threshold(RID p_env) const = 0; + virtual float environment_get_glow_hdr_luminance_cap(RID p_env) const = 0; + virtual float environment_get_glow_hdr_bleed_scale(RID p_env) const = 0; + virtual float environment_get_glow_map_strength(RID p_env) const = 0; + virtual RID environment_get_glow_map(RID p_env) const = 0; + + virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; + virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + + // SSR + 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 bool environment_get_ssr_enabled(RID p_env) const = 0; + virtual int environment_get_ssr_max_steps(RID p_env) const = 0; + virtual float environment_get_ssr_fade_in(RID p_env) const = 0; + virtual float environment_get_ssr_fade_out(RID p_env) const = 0; + virtual float environment_get_ssr_depth_tolerance(RID p_env) const = 0; + virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; + // SSAO virtual 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) = 0; + + virtual bool environment_get_ssao_enabled(RID p_env) const = 0; + virtual float environment_get_ssao_radius(RID p_env) const = 0; + virtual float environment_get_ssao_intensity(RID p_env) const = 0; + virtual float environment_get_ssao_power(RID p_env) const = 0; + virtual float environment_get_ssao_detail(RID p_env) const = 0; + virtual float environment_get_ssao_horizon(RID p_env) const = 0; + virtual float environment_get_ssao_sharpness(RID p_env) const = 0; + virtual float environment_get_ssao_direct_light_affect(RID p_env) const = 0; + virtual float environment_get_ssao_ao_channel_affect(RID p_env) const = 0; + 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; + // SSIL + virtual void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) = 0; + + virtual bool environment_get_ssil_enabled(RID p_env) const = 0; + virtual float environment_get_ssil_radius(RID p_env) const = 0; + virtual float environment_get_ssil_intensity(RID p_env) const = 0; + virtual float environment_get_ssil_sharpness(RID p_env) const = 0; + virtual float environment_get_ssil_normal_rejection(RID p_env) const = 0; + virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0; + // SDFGI virtual void environment_set_sdfgi(RID p_env, bool p_enable, int 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 bool environment_get_sdfgi_enabled(RID p_env) const = 0; + virtual int environment_get_sdfgi_cascades(RID p_env) const = 0; + virtual float environment_get_sdfgi_min_cell_size(RID p_env) const = 0; + virtual bool environment_get_sdfgi_use_occlusion(RID p_env) const = 0; + virtual float environment_get_sdfgi_bounce_feedback(RID p_env) const = 0; + virtual bool environment_get_sdfgi_read_sky_light(RID p_env) const = 0; + virtual float environment_get_sdfgi_energy(RID p_env) const = 0; + virtual float environment_get_sdfgi_normal_bias(RID p_env) const = 0; + virtual float environment_get_sdfgi_probe_bias(RID p_env) const = 0; + virtual RS::EnvironmentSDFGIYScale environment_get_sdfgi_y_scale(RID p_env) const = 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; virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0; - virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; - + // Adjustment virtual 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) = 0; - 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; + virtual bool environment_get_adjustments_enabled(RID p_env) const = 0; + virtual float environment_get_adjustments_brightness(RID p_env) const = 0; + virtual float environment_get_adjustments_contrast(RID p_env) const = 0; + virtual float environment_get_adjustments_saturation(RID p_env) const = 0; + virtual bool environment_get_use_1d_color_correction(RID p_env) const = 0; + virtual RID environment_get_color_correction(RID p_env) const = 0; virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; - virtual RS::EnvironmentBG environment_get_background(RID p_Env) const = 0; - virtual int environment_get_canvas_max_layer(RID p_env) const = 0; - virtual bool is_environment(RID p_environment) const = 0; virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; @@ -194,7 +306,7 @@ public: virtual RID render_buffers_create() = 0; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0; virtual void gi_set_use_half_resolution(bool p_enable) = 0; @@ -226,4 +338,4 @@ public: virtual ~RendererScene(); }; -#endif // RENDERINGSERVERSCENE_H +#endif // RENDERER_SCENE_H diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index ebb5849f85..368bbb63f5 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -475,7 +475,7 @@ void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) { } InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); - scene_render->geometry_instance_set_mesh_instance(geom->geometry_instance, p_instance->mesh_instance); + geom->geometry_instance->set_mesh_instance(p_instance->mesh_instance); if (p_instance->scenario && p_instance->array_index >= 0) { InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index]; @@ -637,20 +637,20 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { instance->base_data = geom; geom->geometry_instance = scene_render->geometry_instance_create(p_base); - scene_render->geometry_instance_set_skeleton(geom->geometry_instance, instance->skeleton); - scene_render->geometry_instance_set_material_override(geom->geometry_instance, instance->material_override); - scene_render->geometry_instance_set_material_overlay(geom->geometry_instance, instance->material_overlay); - scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, instance->materials); - scene_render->geometry_instance_set_transform(geom->geometry_instance, instance->transform, instance->aabb, instance->transformed_aabb); - scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, instance->layer_mask); - scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, instance->lod_bias); - scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, instance->baked_light); - scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, instance->dynamic_gi); - scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); - scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index); - scene_render->geometry_instance_set_transparency(geom->geometry_instance, instance->transparency); + geom->geometry_instance->set_skeleton(instance->skeleton); + geom->geometry_instance->set_material_override(instance->material_override); + geom->geometry_instance->set_material_overlay(instance->material_overlay); + geom->geometry_instance->set_surface_materials(instance->materials); + geom->geometry_instance->set_transform(instance->transform, instance->aabb, instance->transformed_aabb); + geom->geometry_instance->set_layer_mask(instance->layer_mask); + geom->geometry_instance->set_lod_bias(instance->lod_bias); + geom->geometry_instance->set_transparency(instance->transparency); + geom->geometry_instance->set_use_baked_light(instance->baked_light); + geom->geometry_instance->set_use_dynamic_gi(instance->dynamic_gi); + geom->geometry_instance->set_use_lightmap(RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index); + geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); if (instance->lightmap_sh.size() == 9) { - scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, instance->lightmap_sh.ptr()); + geom->geometry_instance->set_lightmap_capture(instance->lightmap_sh.ptr()); } for (Instance *E : instance->visibility_dependencies) { @@ -836,7 +836,7 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask) if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, p_mask); + geom->geometry_instance->set_layer_mask(p_mask); } } @@ -848,7 +848,7 @@ void RendererSceneCull::instance_geometry_set_transparency(RID p_instance, float if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_transparency(geom->geometry_instance, p_transparency); + geom->geometry_instance->set_transparency(p_transparency); } } @@ -1009,7 +1009,7 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton) _instance_update_mesh_instance(instance); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_skeleton(geom->geometry_instance, p_skeleton); + geom->geometry_instance->set_skeleton(p_skeleton); } } @@ -1129,7 +1129,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, p_enabled); + geom->geometry_instance->set_use_baked_light(p_enabled); } } break; @@ -1149,7 +1149,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, p_enabled); + geom->geometry_instance->set_use_dynamic_gi(p_enabled); } } break; @@ -1207,7 +1207,7 @@ void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instanc if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); + geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED); } _instance_queue_update(instance, false, true); @@ -1222,7 +1222,7 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance, if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_material_override(geom->geometry_instance, p_material); + geom->geometry_instance->set_material_override(p_material); } } @@ -1235,7 +1235,7 @@ void RendererSceneCull::instance_geometry_set_material_overlay(RID p_instance, R if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_material_overlay(geom->geometry_instance, p_material); + geom->geometry_instance->set_material_overlay(p_material); } } @@ -1358,9 +1358,9 @@ void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_ins bool end_enabled = p_instance->visibility_range_end > 0.0f; float end_min = p_instance->visibility_range_end - p_instance->visibility_range_end_margin; float end_max = p_instance->visibility_range_end + p_instance->visibility_range_end_margin; - scene_render->geometry_instance_set_fade_range(idata.instance_geometry, begin_enabled, begin_min, begin_max, end_enabled, end_min, end_max); + idata.instance_geometry->set_fade_range(begin_enabled, begin_min, begin_max, end_enabled, end_min, end_max); } else { - scene_render->geometry_instance_set_fade_range(idata.instance_geometry, false, 0.0f, 0.0f, false, 0.0f, 0.0f); + idata.instance_geometry->set_fade_range(false, 0.0f, 0.0f, false, 0.0f, 0.0f); } } @@ -1375,7 +1375,7 @@ void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_ins } else { idata.parent_array_index = -1; if (is_geometry_instance) { - scene_render->geometry_instance_set_parent_fade_alpha(idata.instance_geometry, 1.0f); + idata.instance_geometry->set_parent_fade_alpha(1.0f); } } } @@ -1407,7 +1407,7 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index); + geom->geometry_instance->set_use_lightmap(lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index); } } @@ -1419,7 +1419,7 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); - scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, p_lod_bias); + geom->geometry_instance->set_lod_bias(p_lod_bias); } } @@ -1441,7 +1441,7 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c E->value.value = p_value; if (E->value.index >= 0 && instance->instance_allocated_shader_parameters) { //update directly - RSG::material_storage->global_variables_instance_update(p_instance, E->value.index, p_value); + RSG::material_storage->global_shader_uniforms_instance_update(p_instance, E->value.index, p_value); } } } @@ -1587,11 +1587,11 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { if (!p_instance->lightmap_sh.is_empty()) { p_instance->lightmap_sh.clear(); //don't need SH p_instance->lightmap_target_sh.clear(); //don't need SH - scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, nullptr); + geom->geometry_instance->set_lightmap_capture(nullptr); } } - scene_render->geometry_instance_set_transform(geom->geometry_instance, p_instance->transform, p_instance->aabb, p_instance->transformed_aabb); + geom->geometry_instance->set_transform(p_instance->transform, p_instance->aabb, p_instance->transformed_aabb); } // note: we had to remove is equal approx check here, it meant that det == 0.000004 won't work, which is the case for some of our scenes. @@ -1818,10 +1818,10 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { // Clear these now because the InstanceData containing the dirty flags is gone InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); - scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, nullptr, 0); - scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, nullptr, 0); - scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, nullptr, 0); - scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, nullptr, 0); + geom->geometry_instance->pair_light_instances(nullptr, 0); + geom->geometry_instance->pair_reflection_probe_instances(nullptr, 0); + geom->geometry_instance->pair_decal_instances(nullptr, 0); + geom->geometry_instance->pair_voxel_gi_instances(nullptr, 0); } for (Instance *E : p_instance->visibility_dependencies) { @@ -1829,7 +1829,7 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { if (dep_instance->array_index != -1) { dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = -1; if ((1 << dep_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { - scene_render->geometry_instance_set_parent_fade_alpha(dep_instance->scenario->instance_data[dep_instance->array_index].instance_geometry, 1.0f); + dep_instance->scenario->instance_data[dep_instance->array_index].instance_geometry->set_parent_fade_alpha(1.0f); } } } @@ -1990,10 +1990,10 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) } } - scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, p_instance->lightmap_sh.ptr()); + geom->geometry_instance->set_lightmap_capture(p_instance->lightmap_sh.ptr()); } -void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) { +void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); Transform3D light_transform = p_instance->transform; @@ -2045,7 +2045,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in RENDER_TIMESTAMP("Cull DirectionalLight3D, Split " + itos(i)); // setup a camera matrix for that range! - CameraMatrix camera_matrix; + Projection camera_matrix; real_t aspect = p_cam_projection.get_aspect(); @@ -2185,7 +2185,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in z_max = z_vec.dot(center) + radius + pancake_size; { - CameraMatrix ortho_camera; + Projection ortho_camera; real_t half_x = (x_max_cam - x_min_cam) * 0.5; real_t half_y = (y_max_cam - y_min_cam) * 0.5; @@ -2210,7 +2210,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in } } -bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold) { +bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); Transform3D light_transform = p_instance->transform; @@ -2283,7 +2283,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons RSG::mesh_storage->update_mesh_instances(); - scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0); + scene_render->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, i, 0); shadow_data.light = light->instance; shadow_data.pass = i; } @@ -2294,7 +2294,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); - CameraMatrix cm; + Projection cm; cm.set_perspective(90, 1, radius * 0.005f, radius); for (int i = 0; i < 6; i++) { @@ -2366,7 +2366,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } //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, Projection(), light_transform, radius, 0, 0, 0); } } break; @@ -2380,7 +2380,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); real_t angle = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); - CameraMatrix cm; + Projection cm; cm.set_perspective(angle * 2.0, 1.0, 0.005f * radius, radius); Vector<Plane> planes = cm.get_projection_planes(light_transform); @@ -2450,7 +2450,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ if (p_xr_interface.is_null()) { // Normal camera Transform3D transform = camera->transform; - CameraMatrix projection; + Projection projection; bool vaspect = camera->vaspect; bool is_orthogonal = false; @@ -2489,7 +2489,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ // Setup our camera for our XR interface. // We can support multiple views here each with their own camera Transform3D transforms[RendererSceneRender::MAX_RENDER_VIEWS]; - CameraMatrix projections[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection projections[RendererSceneRender::MAX_RENDER_VIEWS]; uint32_t view_count = p_xr_interface->get_view_count(); ERR_FAIL_COND_MSG(view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported"); @@ -2518,14 +2518,14 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ RENDER_TIMESTAMP("Update Occlusion Buffer") // For now just cull on the first camera - RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_orthogonal, RendererThreadPool::singleton->thread_work_pool); + RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_orthogonal); _render_scene(&camera_data, p_render_buffers, environment, camera->effects, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_mesh_lod_threshold, true, r_render_info); #endif } void RendererSceneCull::_visibility_cull_threaded(uint32_t p_thread, VisibilityCullData *cull_data) { - uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count(); uint32_t bin_from = p_thread * cull_data->cull_count / total_threads; uint32_t bin_to = (p_thread + 1 == total_threads) ? cull_data->cull_count : ((p_thread + 1) * cull_data->cull_count / total_threads); @@ -2622,7 +2622,7 @@ bool RendererSceneCull::_visibility_parent_check(const CullData &p_cull_data, co void RendererSceneCull::_scene_cull_threaded(uint32_t p_thread, CullData *cull_data) { uint32_t cull_total = cull_data->scenario->instance_data.size(); - uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + uint32_t total_threads = WorkerThreadPool::get_singleton()->get_thread_count(); uint32_t cull_from = p_thread * cull_total / total_threads; uint32_t cull_to = (p_thread + 1 == total_threads) ? cull_total : ((p_thread + 1) * cull_total / total_threads); @@ -2742,7 +2742,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul const int32_t &parent_idx = cull_data.scenario->instance_data[idata.parent_array_index].visibility_index; fade = cull_data.scenario->instance_visibility[parent_idx].children_fade_alpha; } - scene_render->geometry_instance_set_parent_fade_alpha(idata.instance_geometry, fade); + idata.instance_geometry->set_parent_fade_alpha(fade); } if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) { @@ -2757,14 +2757,14 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } - scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_light_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY); } if (idata.flags & InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); - scene_render->geometry_instance_set_softshadow_projector_pairing(geom->geometry_instance, geom->softshadow_count > 0, geom->projector_count > 0); + geom->geometry_instance->set_softshadow_projector_pairing(geom->softshadow_count > 0, geom->projector_count > 0); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY); } @@ -2781,7 +2781,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } - scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_reflection_probe_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY); } @@ -2797,7 +2797,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul break; } } - scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_decal_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY); } @@ -2813,7 +2813,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul } } - scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx); idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); } @@ -2824,7 +2824,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul for (uint32_t j = 0; j < 9; j++) { sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); } - scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, sh); + geom->geometry_instance->set_lightmap_capture(sh); idata.instance->last_frame_pass = frame_number; } @@ -2919,7 +2919,8 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c } if (visibility_cull_data.cull_count > thread_cull_threshold) { - RendererThreadPool::singleton->thread_work_pool.do_work(RendererThreadPool::singleton->thread_work_pool.get_thread_count(), this, &RendererSceneCull::_visibility_cull_threaded, &visibility_cull_data); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RendererSceneCull::_visibility_cull_threaded, &visibility_cull_data, WorkerThreadPool::get_singleton()->get_thread_count(), -1, true, SNAME("VisibilityCullInstances")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); } else { _visibility_cull(visibility_cull_data, visibility_cull_data.cull_offset, visibility_cull_data.cull_offset + visibility_cull_data.cull_count); } @@ -3024,7 +3025,8 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c scene_cull_result_threads[i].clear(); } - RendererThreadPool::singleton->thread_work_pool.do_work(scene_cull_result_threads.size(), this, &RendererSceneCull::_scene_cull_threaded, &cull_data); + WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &RendererSceneCull::_scene_cull_threaded, &cull_data, scene_cull_result_threads.size(), -1, true, SNAME("RenderCullInstances")); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task); for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) { scene_cull_result.append_from(scene_cull_result_threads[i]); @@ -3243,7 +3245,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c render_sdfgi_data[i].instances.clear(); } - // virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, 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_mesh_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; + // virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, 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_mesh_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) { @@ -3280,9 +3282,9 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RENDER_TIMESTAMP("Render Empty 3D Scene"); RendererSceneRender::CameraData camera_data; - camera_data.set_camera(Transform3D(), CameraMatrix(), true, false); + camera_data.set_camera(Transform3D(), Projection(), true, false); - scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); + scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); #endif } @@ -3329,7 +3331,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int max_distance = MAX(max_distance, distance); //render cubemap side - CameraMatrix cm; + Projection cm; cm.set_perspective(90, 1, 0.01, max_distance); Transform3D local_view; @@ -3586,7 +3588,7 @@ void RendererSceneCull::render_probes() { } } - scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, instance_pair_buffer, idx); + geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx); ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); } @@ -3848,18 +3850,18 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { if (p_instance->instance_allocated_shader_parameters != (p_instance->instance_shader_parameters.size() > 0)) { p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0); if (p_instance->instance_allocated_shader_parameters) { - p_instance->instance_allocated_shader_parameters_offset = RSG::material_storage->global_variables_instance_allocate(p_instance->self); - scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, p_instance->instance_allocated_shader_parameters_offset); + p_instance->instance_allocated_shader_parameters_offset = RSG::material_storage->global_shader_uniforms_instance_allocate(p_instance->self); + geom->geometry_instance->set_instance_shader_parameters_offset(p_instance->instance_allocated_shader_parameters_offset); for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_parameters) { if (E.value.value.get_type() != Variant::NIL) { - RSG::material_storage->global_variables_instance_update(p_instance->self, E.value.index, E.value.value); + RSG::material_storage->global_shader_uniforms_instance_update(p_instance->self, E.value.index, E.value.value); } } } else { - RSG::material_storage->global_variables_instance_free(p_instance->self); + RSG::material_storage->global_shader_uniforms_instance_free(p_instance->self); p_instance->instance_allocated_shader_parameters_offset = -1; - scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, -1); + geom->geometry_instance->set_instance_shader_parameters_offset(-1); } } } @@ -3872,7 +3874,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); - scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, p_instance->materials); + geom->geometry_instance->set_surface_materials(p_instance->materials); } } @@ -3953,7 +3955,7 @@ bool RendererSceneCull::free(RID p_rid) { if (instance->instance_allocated_shader_parameters) { //free the used shader parameters - RSG::material_storage->global_variables_instance_free(instance->self); + RSG::material_storage->global_shader_uniforms_instance_free(instance->self); } update_dirty_instances(); //in case something changed this @@ -4030,14 +4032,14 @@ RendererSceneCull::RendererSceneCull() { } scene_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool); - scene_cull_result_threads.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); + scene_cull_result_threads.resize(WorkerThreadPool::get_singleton()->get_thread_count()); for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) { scene_cull_result_threads[i].init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool); } indexer_update_iterations = GLOBAL_GET("rendering/limits/spatial_indexer/update_iterations_per_frame"); thread_cull_threshold = GLOBAL_GET("rendering/limits/spatial_indexer/threaded_cull_minimum_instances"); - thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)RendererThreadPool::singleton->thread_work_pool.get_thread_count()); //make sure there is at least one thread per CPU + thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)WorkerThreadPool::get_singleton()->get_thread_count()); //make sure there is at least one thread per CPU taa_jitter_array.resize(TAA_JITTER_COUNT); for (int i = 0; i < TAA_JITTER_COUNT; i++) { diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 8c722360ae..3a2b0a0fdf 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERING_SERVER_SCENE_CULL_H -#define RENDERING_SERVER_SCENE_CULL_H +#ifndef RENDERER_SCENE_CULL_H +#define RENDERER_SCENE_CULL_H #include "core/math/dynamic_bvh.h" #include "core/templates/bin_sorted_array.h" @@ -272,7 +272,7 @@ public: RID base_rid; union { uint64_t instance_data_rid; - RendererSceneRender::GeometryInstance *instance_geometry; + RenderGeometryInstance *instance_geometry; InstanceVisibilityNotifierData *visibility_notifier = nullptr; }; Instance *instance = nullptr; @@ -578,7 +578,7 @@ public: void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false); struct InstanceGeometryData : public InstanceBaseData { - RendererSceneRender::GeometryInstance *geometry_instance = nullptr; + RenderGeometryInstance *geometry_instance = nullptr; HashSet<Instance *> lights; bool can_cast_shadows; bool material_is_animated; @@ -782,14 +782,14 @@ public: HashSet<Instance *> heightfield_particle_colliders_update_list; PagedArrayPool<Instance *> instance_cull_page_pool; - PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool; + PagedArrayPool<RenderGeometryInstance *> geometry_instance_cull_page_pool; PagedArrayPool<RID> rid_cull_page_pool; PagedArray<Instance *> instance_cull_result; PagedArray<Instance *> instance_shadow_cull_result; struct InstanceCullResult { - PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances; + PagedArray<RenderGeometryInstance *> geometry_instances; PagedArray<Instance *> lights; PagedArray<RID> light_instances; PagedArray<RID> lightmaps; @@ -800,10 +800,10 @@ public: PagedArray<RID> fog_volumes; struct DirectionalShadow { - PagedArray<RendererSceneRender::GeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; + PagedArray<RenderGeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; } directional_shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS]; - PagedArray<RendererSceneRender::GeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; + PagedArray<RenderGeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES]; void clear() { @@ -882,7 +882,7 @@ public: } } - void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RendererSceneRender::GeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) { + void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RenderGeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) { geometry_instances.set_page_pool(p_geometry_instance_pool); light_instances.set_page_pool(p_rid_pool); lights.set_page_pool(p_instance_pool); @@ -980,9 +980,9 @@ public: _FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance); void _unpair_instance(Instance *p_instance); - void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect); + void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect); - _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold); + _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold); RID _render_get_environment(RID p_camera, RID p_scenario); @@ -992,7 +992,7 @@ public: struct Cascade { Frustum frustum; - CameraMatrix projection; + Projection projection; Transform3D transform; real_t zfar; real_t split; @@ -1045,7 +1045,7 @@ public: uint32_t visible_layers; Instance *render_reflection_probe = nullptr; const RendererSceneOcclusionCull::HZBuffer *occlusion_buffer; - const CameraMatrix *camera_matrix; + const Projection *camera_matrix; uint64_t visibility_viewport_mask; }; @@ -1093,6 +1093,7 @@ public: PASS1RC(bool, is_environment, RID) + // Background PASS2(environment_set_background, RID, RS::EnvironmentBG) PASS2(environment_set_sky, RID, RID) PASS2(environment_set_sky_custom_fov, RID, float) @@ -1102,36 +1103,146 @@ public: PASS2(environment_set_canvas_max_layer, RID, int) PASS6(environment_set_ambient_light, RID, const Color &, RS::EnvironmentAmbientSource, float, float, RS::EnvironmentReflectionSource) + PASS1RC(RS::EnvironmentBG, environment_get_background, RID) + PASS1RC(RID, environment_get_sky, RID) + PASS1RC(float, environment_get_sky_custom_fov, RID) + PASS1RC(Basis, environment_get_sky_orientation, RID) + PASS1RC(Color, environment_get_bg_color, RID) + PASS1RC(float, environment_get_bg_energy, RID) + PASS1RC(int, environment_get_canvas_max_layer, RID) + PASS1RC(RS::EnvironmentAmbientSource, environment_get_ambient_source, RID) + PASS1RC(Color, environment_get_ambient_light, RID) + PASS1RC(float, environment_get_ambient_light_energy, RID) + PASS1RC(float, environment_get_ambient_sky_contribution, RID) + PASS1RC(RS::EnvironmentReflectionSource, environment_get_reflection_source, RID) + + // Tonemap + PASS9(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float, bool, float, float, float, float) + PASS1RC(RS::EnvironmentToneMapper, environment_get_tone_mapper, RID) + PASS1RC(float, environment_get_exposure, RID) + PASS1RC(float, environment_get_white, RID) + PASS1RC(bool, environment_get_auto_exposure, RID) + PASS1RC(float, environment_get_min_luminance, RID) + PASS1RC(float, environment_get_max_luminance, RID) + PASS1RC(float, environment_get_auto_exp_speed, RID) + PASS1RC(float, environment_get_auto_exp_scale, RID) + PASS1RC(uint64_t, environment_get_auto_exposure_version, RID) + + // Fog + PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) + + PASS1RC(bool, environment_get_fog_enabled, RID) + PASS1RC(Color, environment_get_fog_light_color, RID) + PASS1RC(float, environment_get_fog_light_energy, RID) + PASS1RC(float, environment_get_fog_sun_scatter, RID) + PASS1RC(float, environment_get_fog_density, RID) + PASS1RC(float, environment_get_fog_height, RID) + PASS1RC(float, environment_get_fog_height_density, RID) + PASS1RC(float, environment_get_fog_aerial_perspective, RID) + + PASS2(environment_set_volumetric_fog_volume_size, int, int) + PASS1(environment_set_volumetric_fog_filter_active, bool) + + // Volumentric Fog + PASS13(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float) + + PASS1RC(bool, environment_get_volumetric_fog_enabled, RID) + PASS1RC(float, environment_get_volumetric_fog_density, RID) + PASS1RC(Color, environment_get_volumetric_fog_scattering, RID) + PASS1RC(Color, environment_get_volumetric_fog_emission, RID) + PASS1RC(float, environment_get_volumetric_fog_emission_energy, RID) + PASS1RC(float, environment_get_volumetric_fog_anisotropy, RID) + PASS1RC(float, environment_get_volumetric_fog_length, RID) + PASS1RC(float, environment_get_volumetric_fog_detail_spread, RID) + PASS1RC(float, environment_get_volumetric_fog_gi_inject, RID) + PASS1RC(bool, environment_get_volumetric_fog_temporal_reprojection, RID) + PASS1RC(float, environment_get_volumetric_fog_temporal_reprojection_amount, RID) + PASS1RC(float, environment_get_volumetric_fog_ambient_inject, RID) + + // Glow + PASS13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float, float, RID) + + PASS1RC(bool, environment_get_glow_enabled, RID) + PASS1RC(Vector<float>, environment_get_glow_levels, RID) + PASS1RC(float, environment_get_glow_intensity, RID) + PASS1RC(float, environment_get_glow_strength, RID) + PASS1RC(float, environment_get_glow_bloom, RID) + PASS1RC(float, environment_get_glow_mix, RID) + PASS1RC(RS::EnvironmentGlowBlendMode, environment_get_glow_blend_mode, RID) + PASS1RC(float, environment_get_glow_hdr_bleed_threshold, RID) + PASS1RC(float, environment_get_glow_hdr_luminance_cap, RID) + PASS1RC(float, environment_get_glow_hdr_bleed_scale, RID) + PASS1RC(float, environment_get_glow_map_strength, RID) + PASS1RC(RID, environment_get_glow_map, RID) + + PASS1(environment_glow_set_use_bicubic_upscale, bool) + PASS1(environment_glow_set_use_high_quality, bool) + + // SSR PASS6(environment_set_ssr, RID, bool, int, float, float, float) + + PASS1RC(bool, environment_get_ssr_enabled, RID) + PASS1RC(int, environment_get_ssr_max_steps, RID) + PASS1RC(float, environment_get_ssr_fade_in, RID) + PASS1RC(float, environment_get_ssr_fade_out, RID) + PASS1RC(float, environment_get_ssr_depth_tolerance, RID) + PASS1(environment_set_ssr_roughness_quality, RS::EnvironmentSSRRoughnessQuality) + // SSAO PASS10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float) + + PASS1RC(bool, environment_get_ssao_enabled, RID) + PASS1RC(float, environment_get_ssao_radius, RID) + PASS1RC(float, environment_get_ssao_intensity, RID) + PASS1RC(float, environment_get_ssao_power, RID) + PASS1RC(float, environment_get_ssao_detail, RID) + PASS1RC(float, environment_get_ssao_horizon, RID) + PASS1RC(float, environment_get_ssao_sharpness, RID) + PASS1RC(float, environment_get_ssao_direct_light_affect, RID) + PASS1RC(float, environment_get_ssao_ao_channel_affect, RID) + PASS6(environment_set_ssao_quality, RS::EnvironmentSSAOQuality, bool, float, int, float, float) + // SSIL PASS6(environment_set_ssil, RID, bool, float, float, float, float) - PASS6(environment_set_ssil_quality, RS::EnvironmentSSILQuality, bool, float, int, float, float) - PASS13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float, float, RID) - PASS1(environment_glow_set_use_bicubic_upscale, bool) - PASS1(environment_glow_set_use_high_quality, bool) + PASS1RC(bool, environment_get_ssil_enabled, RID) + PASS1RC(float, environment_get_ssil_radius, RID) + PASS1RC(float, environment_get_ssil_intensity, RID) + PASS1RC(float, environment_get_ssil_sharpness, RID) + PASS1RC(float, environment_get_ssil_normal_rejection, RID) - PASS9(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float, bool, float, float, float, float) + PASS6(environment_set_ssil_quality, RS::EnvironmentSSILQuality, bool, float, int, float, float) - PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) + // SDFGI - PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float) - PASS13(environment_set_volumetric_fog, RID, bool, float, const Color &, const Color &, float, float, float, float, float, bool, float, float) + PASS11(environment_set_sdfgi, RID, bool, int, float, RS::EnvironmentSDFGIYScale, bool, float, bool, float, float, float) - PASS2(environment_set_volumetric_fog_volume_size, int, int) - PASS1(environment_set_volumetric_fog_filter_active, bool) + PASS1RC(bool, environment_get_sdfgi_enabled, RID) + PASS1RC(int, environment_get_sdfgi_cascades, RID) + PASS1RC(float, environment_get_sdfgi_min_cell_size, RID) + PASS1RC(bool, environment_get_sdfgi_use_occlusion, RID) + PASS1RC(float, environment_get_sdfgi_bounce_feedback, RID) + PASS1RC(bool, environment_get_sdfgi_read_sky_light, RID) + PASS1RC(float, environment_get_sdfgi_energy, RID) + PASS1RC(float, environment_get_sdfgi_normal_bias, RID) + PASS1RC(float, environment_get_sdfgi_probe_bias, RID) + PASS1RC(RS::EnvironmentSDFGIYScale, environment_get_sdfgi_y_scale, RID) - PASS11(environment_set_sdfgi, RID, bool, int, 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) - PASS1RC(RS::EnvironmentBG, environment_get_background, RID) - PASS1RC(int, environment_get_canvas_max_layer, RID) + // Adjustment + PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID) + + PASS1RC(bool, environment_get_adjustments_enabled, RID) + PASS1RC(float, environment_get_adjustments_brightness, RID) + PASS1RC(float, environment_get_adjustments_contrast, RID) + PASS1RC(float, environment_get_adjustments_saturation, RID) + PASS1RC(bool, environment_get_use_1d_color_correction, RID) + PASS1RC(RID, environment_get_color_correction, RID) PASS3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &) @@ -1183,4 +1294,4 @@ public: virtual ~RendererSceneCull(); }; -#endif // RENDERING_SERVER_SCENE_CULL_H +#endif // RENDERER_SCENE_CULL_H diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h index 7198379ade..0d466e8a32 100644 --- a/servers/rendering/renderer_scene_occlusion_cull.h +++ b/servers/rendering/renderer_scene_occlusion_cull.h @@ -31,7 +31,7 @@ #ifndef RENDERER_SCENE_OCCLUSION_CULL_H #define RENDERER_SCENE_OCCLUSION_CULL_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/local_vector.h" #include "servers/rendering_server.h" @@ -60,7 +60,7 @@ public: void update_mips(); - _FORCE_INLINE_ bool is_occluded(const real_t p_bounds[6], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const CameraMatrix &p_cam_projection, real_t p_near) const { + _FORCE_INLINE_ bool is_occluded(const real_t p_bounds[6], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const Projection &p_cam_projection, real_t p_near) const { if (is_empty()) { return false; } @@ -183,7 +183,8 @@ public: } virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) { _print_warning(); } virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) { _print_warning(); } - virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) {} + virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) {} + virtual RID buffer_get_debug_texture(RID p_buffer) { _print_warning(); return RID(); @@ -200,4 +201,4 @@ public: }; }; -#endif //RENDERER_SCENE_OCCLUSION_CULL_H +#endif // RENDERER_SCENE_OCCLUSION_CULL_H diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index 600908cf16..e024e59ec3 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -30,7 +30,10 @@ #include "renderer_scene_render.h" -void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const CameraMatrix p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) { +///////////////////////////////////////////////////////////////////////////// +// CameraData + +void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) { view_count = 1; is_orthogonal = p_is_orthogonal; vaspect = p_vaspect; @@ -43,7 +46,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, taa_jitter = p_taa_jitter; } -void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const CameraMatrix *p_projections, bool p_is_orthogonal, bool p_vaspect) { +void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect) { ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view"); view_count = p_view_count; @@ -60,8 +63,8 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count } // 2. average and normalize plane normals to obtain z vector, cross them to obtain y vector, and from there the x vector for combined camera basis. - Vector3 n0 = planes[0][CameraMatrix::PLANE_LEFT].normal; - Vector3 n1 = planes[1][CameraMatrix::PLANE_RIGHT].normal; + Vector3 n0 = planes[0][Projection::PLANE_LEFT].normal; + Vector3 n1 = planes[1][Projection::PLANE_RIGHT].normal; Vector3 z = (n0 + n1).normalized(); Vector3 y = n0.cross(n1).normalized(); Vector3 x = y.cross(z).normalized(); @@ -73,13 +76,13 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 4. Intersect horizon, left and right to obtain the combined camera origin. ERR_FAIL_COND_MSG( - !horizon.intersect_3(planes[0][CameraMatrix::PLANE_LEFT], planes[1][CameraMatrix::PLANE_RIGHT], &main_transform.origin), "Can't determine camera origin"); + !horizon.intersect_3(planes[0][Projection::PLANE_LEFT], planes[1][Projection::PLANE_RIGHT], &main_transform.origin), "Can't determine camera origin"); // handy to have the inverse of the transform we just build Transform3D main_transform_inv = main_transform.inverse(); // 5. figure out far plane, this could use some improvement, we may have our far plane too close like this, not sure if this matters - Vector3 far_center = (planes[0][CameraMatrix::PLANE_FAR].center() + planes[1][CameraMatrix::PLANE_FAR].center()) * 0.5; + Vector3 far_center = (planes[0][Projection::PLANE_FAR].center() + planes[1][Projection::PLANE_FAR].center()) * 0.5; Plane far(-z, far_center); ///////////////////////////////////////////////////////////////////////////// @@ -88,9 +91,9 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 6. Intersect far and left planes with top planes from both eyes, save the point with highest y as top_left. Vector3 top_left, other; ERR_FAIL_COND_MSG( - !far.intersect_3(planes[0][CameraMatrix::PLANE_LEFT], planes[0][CameraMatrix::PLANE_TOP], &top_left), "Can't determine left camera far/left/top vector"); + !far.intersect_3(planes[0][Projection::PLANE_LEFT], planes[0][Projection::PLANE_TOP], &top_left), "Can't determine left camera far/left/top vector"); ERR_FAIL_COND_MSG( - !far.intersect_3(planes[1][CameraMatrix::PLANE_LEFT], planes[1][CameraMatrix::PLANE_TOP], &other), "Can't determine right camera far/left/top vector"); + !far.intersect_3(planes[1][Projection::PLANE_LEFT], planes[1][Projection::PLANE_TOP], &other), "Can't determine right camera far/left/top vector"); if (y.dot(top_left) < y.dot(other)) { top_left = other; } @@ -98,9 +101,9 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 7. Intersect far and left planes with bottom planes from both eyes, save the point with lowest y as bottom_left. Vector3 bottom_left; ERR_FAIL_COND_MSG( - !far.intersect_3(planes[0][CameraMatrix::PLANE_LEFT], planes[0][CameraMatrix::PLANE_BOTTOM], &bottom_left), "Can't determine left camera far/left/bottom vector"); + !far.intersect_3(planes[0][Projection::PLANE_LEFT], planes[0][Projection::PLANE_BOTTOM], &bottom_left), "Can't determine left camera far/left/bottom vector"); ERR_FAIL_COND_MSG( - !far.intersect_3(planes[1][CameraMatrix::PLANE_LEFT], planes[1][CameraMatrix::PLANE_BOTTOM], &other), "Can't determine right camera far/left/bottom vector"); + !far.intersect_3(planes[1][Projection::PLANE_LEFT], planes[1][Projection::PLANE_BOTTOM], &other), "Can't determine right camera far/left/bottom vector"); if (y.dot(other) < y.dot(bottom_left)) { bottom_left = other; } @@ -108,9 +111,9 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 8. Intersect far and right planes with top planes from both eyes, save the point with highest y as top_right. Vector3 top_right; ERR_FAIL_COND_MSG( - !far.intersect_3(planes[0][CameraMatrix::PLANE_RIGHT], planes[0][CameraMatrix::PLANE_TOP], &top_right), "Can't determine left camera far/right/top vector"); + !far.intersect_3(planes[0][Projection::PLANE_RIGHT], planes[0][Projection::PLANE_TOP], &top_right), "Can't determine left camera far/right/top vector"); ERR_FAIL_COND_MSG( - !far.intersect_3(planes[1][CameraMatrix::PLANE_RIGHT], planes[1][CameraMatrix::PLANE_TOP], &other), "Can't determine right camera far/right/top vector"); + !far.intersect_3(planes[1][Projection::PLANE_RIGHT], planes[1][Projection::PLANE_TOP], &other), "Can't determine right camera far/right/top vector"); if (y.dot(top_right) < y.dot(other)) { top_right = other; } @@ -118,9 +121,9 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 9. Intersect far and right planes with bottom planes from both eyes, save the point with lowest y as bottom_right. Vector3 bottom_right; ERR_FAIL_COND_MSG( - !far.intersect_3(planes[0][CameraMatrix::PLANE_RIGHT], planes[0][CameraMatrix::PLANE_BOTTOM], &bottom_right), "Can't determine left camera far/right/bottom vector"); + !far.intersect_3(planes[0][Projection::PLANE_RIGHT], planes[0][Projection::PLANE_BOTTOM], &bottom_right), "Can't determine left camera far/right/bottom vector"); ERR_FAIL_COND_MSG( - !far.intersect_3(planes[1][CameraMatrix::PLANE_RIGHT], planes[1][CameraMatrix::PLANE_BOTTOM], &other), "Can't determine right camera far/right/bottom vector"); + !far.intersect_3(planes[1][Projection::PLANE_RIGHT], planes[1][Projection::PLANE_BOTTOM], &other), "Can't determine right camera far/right/bottom vector"); if (y.dot(other) < y.dot(bottom_right)) { bottom_right = other; } @@ -146,18 +149,18 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 13. Intersect near plane with bottm/left planes, to obtain min_vec then top/right to obtain max_vec Vector3 min_vec; ERR_FAIL_COND_MSG( - !near.intersect_3(bottom, planes[0][CameraMatrix::PLANE_LEFT], &min_vec), "Can't determine left camera near/left/bottom vector"); + !near.intersect_3(bottom, planes[0][Projection::PLANE_LEFT], &min_vec), "Can't determine left camera near/left/bottom vector"); ERR_FAIL_COND_MSG( - !near.intersect_3(bottom, planes[1][CameraMatrix::PLANE_LEFT], &other), "Can't determine right camera near/left/bottom vector"); + !near.intersect_3(bottom, planes[1][Projection::PLANE_LEFT], &other), "Can't determine right camera near/left/bottom vector"); if (x.dot(other) < x.dot(min_vec)) { min_vec = other; } Vector3 max_vec; ERR_FAIL_COND_MSG( - !near.intersect_3(top, planes[0][CameraMatrix::PLANE_RIGHT], &max_vec), "Can't determine left camera near/right/top vector"); + !near.intersect_3(top, planes[0][Projection::PLANE_RIGHT], &max_vec), "Can't determine left camera near/right/top vector"); ERR_FAIL_COND_MSG( - !near.intersect_3(top, planes[1][CameraMatrix::PLANE_RIGHT], &other), "Can't determine right camera near/right/top vector"); + !near.intersect_3(top, planes[1][Projection::PLANE_RIGHT], &other), "Can't determine right camera near/right/top vector"); if (x.dot(max_vec) < x.dot(other)) { max_vec = other; } @@ -177,6 +180,464 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 3. Copy our view data for (uint32_t v = 0; v < view_count; v++) { view_offset[v] = main_transform_inv * p_transforms[v]; - view_projection[v] = p_projections[v] * CameraMatrix(view_offset[v].inverse()); + view_projection[v] = p_projections[v] * Projection(view_offset[v].inverse()); } } + +/* Environment API */ + +RID RendererSceneRender::environment_allocate() { + return environment_storage.environment_allocate(); +} + +void RendererSceneRender::environment_initialize(RID p_rid) { + environment_storage.environment_initialize(p_rid); +} + +void RendererSceneRender::environment_free(RID p_rid) { + environment_storage.environment_free(p_rid); +} + +bool RendererSceneRender::is_environment(RID p_rid) const { + return environment_storage.is_environment(p_rid); +} + +// background + +void RendererSceneRender::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { + environment_storage.environment_set_background(p_env, p_bg); +} + +void RendererSceneRender::environment_set_sky(RID p_env, RID p_sky) { + environment_storage.environment_set_sky(p_env, p_sky); +} + +void RendererSceneRender::environment_set_sky_custom_fov(RID p_env, float p_scale) { + environment_storage.environment_set_sky_custom_fov(p_env, p_scale); +} + +void RendererSceneRender::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { + environment_storage.environment_set_sky_orientation(p_env, p_orientation); +} + +void RendererSceneRender::environment_set_bg_color(RID p_env, const Color &p_color) { + environment_storage.environment_set_bg_color(p_env, p_color); +} + +void RendererSceneRender::environment_set_bg_energy(RID p_env, float p_energy) { + environment_storage.environment_set_bg_energy(p_env, p_energy); +} + +void RendererSceneRender::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { + environment_storage.environment_set_canvas_max_layer(p_env, p_max_layer); +} + +void RendererSceneRender::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { + environment_storage.environment_set_ambient_light(p_env, p_color, p_ambient, p_energy, p_sky_contribution, p_reflection_source); +} + +RS::EnvironmentBG RendererSceneRender::environment_get_background(RID p_env) const { + return environment_storage.environment_get_background(p_env); +} + +RID RendererSceneRender::environment_get_sky(RID p_env) const { + return environment_storage.environment_get_sky(p_env); +} + +float RendererSceneRender::environment_get_sky_custom_fov(RID p_env) const { + return environment_storage.environment_get_sky_custom_fov(p_env); +} + +Basis RendererSceneRender::environment_get_sky_orientation(RID p_env) const { + return environment_storage.environment_get_sky_orientation(p_env); +} + +Color RendererSceneRender::environment_get_bg_color(RID p_env) const { + return environment_storage.environment_get_bg_color(p_env); +} + +float RendererSceneRender::environment_get_bg_energy(RID p_env) const { + return environment_storage.environment_get_bg_energy(p_env); +} + +int RendererSceneRender::environment_get_canvas_max_layer(RID p_env) const { + return environment_storage.environment_get_canvas_max_layer(p_env); +} + +RS::EnvironmentAmbientSource RendererSceneRender::environment_get_ambient_source(RID p_env) const { + return environment_storage.environment_get_ambient_source(p_env); +} + +Color RendererSceneRender::environment_get_ambient_light(RID p_env) const { + return environment_storage.environment_get_ambient_light(p_env); +} + +float RendererSceneRender::environment_get_ambient_light_energy(RID p_env) const { + return environment_storage.environment_get_ambient_light_energy(p_env); +} + +float RendererSceneRender::environment_get_ambient_sky_contribution(RID p_env) const { + return environment_storage.environment_get_ambient_sky_contribution(p_env); +} + +RS::EnvironmentReflectionSource RendererSceneRender::environment_get_reflection_source(RID p_env) const { + return environment_storage.environment_get_reflection_source(p_env); +} + +// Tonemap + +void RendererSceneRender::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { + environment_storage.environment_set_tonemap(p_env, p_tone_mapper, p_exposure, p_white, p_auto_exposure, p_min_luminance, p_max_luminance, p_auto_exp_speed, p_auto_exp_scale); +} + +RS::EnvironmentToneMapper RendererSceneRender::environment_get_tone_mapper(RID p_env) const { + return environment_storage.environment_get_tone_mapper(p_env); +} + +float RendererSceneRender::environment_get_exposure(RID p_env) const { + return environment_storage.environment_get_exposure(p_env); +} + +float RendererSceneRender::environment_get_white(RID p_env) const { + return environment_storage.environment_get_white(p_env); +} + +bool RendererSceneRender::environment_get_auto_exposure(RID p_env) const { + return environment_storage.environment_get_auto_exposure(p_env); +} + +float RendererSceneRender::environment_get_min_luminance(RID p_env) const { + return environment_storage.environment_get_min_luminance(p_env); +} + +float RendererSceneRender::environment_get_max_luminance(RID p_env) const { + return environment_storage.environment_get_max_luminance(p_env); +} + +float RendererSceneRender::environment_get_auto_exp_speed(RID p_env) const { + return environment_storage.environment_get_auto_exp_speed(p_env); +} + +float RendererSceneRender::environment_get_auto_exp_scale(RID p_env) const { + return environment_storage.environment_get_auto_exp_scale(p_env); +} + +uint64_t RendererSceneRender::environment_get_auto_exposure_version(RID p_env) const { + return environment_storage.environment_get_auto_exposure_version(p_env); +} + +// Fog + +void RendererSceneRender::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) { + environment_storage.environment_set_fog(p_env, p_enable, p_light_color, p_light_energy, p_sun_scatter, p_density, p_height, p_height_density, p_aerial_perspective); +} + +bool RendererSceneRender::environment_get_fog_enabled(RID p_env) const { + return environment_storage.environment_get_fog_enabled(p_env); +} + +Color RendererSceneRender::environment_get_fog_light_color(RID p_env) const { + return environment_storage.environment_get_fog_light_color(p_env); +} + +float RendererSceneRender::environment_get_fog_light_energy(RID p_env) const { + return environment_storage.environment_get_fog_light_energy(p_env); +} + +float RendererSceneRender::environment_get_fog_sun_scatter(RID p_env) const { + return environment_storage.environment_get_fog_sun_scatter(p_env); +} + +float RendererSceneRender::environment_get_fog_density(RID p_env) const { + return environment_storage.environment_get_fog_density(p_env); +} + +float RendererSceneRender::environment_get_fog_height(RID p_env) const { + return environment_storage.environment_get_fog_height(p_env); +} + +float RendererSceneRender::environment_get_fog_height_density(RID p_env) const { + return environment_storage.environment_get_fog_height_density(p_env); +} + +float RendererSceneRender::environment_get_fog_aerial_perspective(RID p_env) const { + return environment_storage.environment_get_fog_aerial_perspective(p_env); +} + +// Volumetric Fog + +void RendererSceneRender::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { + environment_storage.environment_set_volumetric_fog(p_env, p_enable, p_density, p_albedo, p_emission, p_emission_energy, p_anisotropy, p_length, p_detail_spread, p_gi_inject, p_temporal_reprojection, p_temporal_reprojection_amount, p_ambient_inject); +} + +bool RendererSceneRender::environment_get_volumetric_fog_enabled(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_enabled(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_density(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_density(p_env); +} + +Color RendererSceneRender::environment_get_volumetric_fog_scattering(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_scattering(p_env); +} + +Color RendererSceneRender::environment_get_volumetric_fog_emission(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_emission(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_emission_energy(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_emission_energy(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_anisotropy(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_anisotropy(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_length(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_length(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_detail_spread(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_detail_spread(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_gi_inject(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_gi_inject(p_env); +} + +bool RendererSceneRender::environment_get_volumetric_fog_temporal_reprojection(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_temporal_reprojection(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_temporal_reprojection_amount(p_env); +} + +float RendererSceneRender::environment_get_volumetric_fog_ambient_inject(RID p_env) const { + return environment_storage.environment_get_volumetric_fog_ambient_inject(p_env); +} + +// GLOW + +void RendererSceneRender::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { + environment_storage.environment_set_glow(p_env, p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap, p_glow_map_strength, p_glow_map); +} + +bool RendererSceneRender::environment_get_glow_enabled(RID p_env) const { + return environment_storage.environment_get_glow_enabled(p_env); +} + +Vector<float> RendererSceneRender::environment_get_glow_levels(RID p_env) const { + return environment_storage.environment_get_glow_levels(p_env); +} + +float RendererSceneRender::environment_get_glow_intensity(RID p_env) const { + return environment_storage.environment_get_glow_intensity(p_env); +} + +float RendererSceneRender::environment_get_glow_strength(RID p_env) const { + return environment_storage.environment_get_glow_strength(p_env); +} + +float RendererSceneRender::environment_get_glow_bloom(RID p_env) const { + return environment_storage.environment_get_glow_bloom(p_env); +} + +float RendererSceneRender::environment_get_glow_mix(RID p_env) const { + return environment_storage.environment_get_glow_mix(p_env); +} + +RS::EnvironmentGlowBlendMode RendererSceneRender::environment_get_glow_blend_mode(RID p_env) const { + return environment_storage.environment_get_glow_blend_mode(p_env); +} + +float RendererSceneRender::environment_get_glow_hdr_bleed_threshold(RID p_env) const { + return environment_storage.environment_get_glow_hdr_bleed_threshold(p_env); +} + +float RendererSceneRender::environment_get_glow_hdr_luminance_cap(RID p_env) const { + return environment_storage.environment_get_glow_hdr_luminance_cap(p_env); +} + +float RendererSceneRender::environment_get_glow_hdr_bleed_scale(RID p_env) const { + return environment_storage.environment_get_glow_hdr_bleed_scale(p_env); +} + +float RendererSceneRender::environment_get_glow_map_strength(RID p_env) const { + return environment_storage.environment_get_glow_map_strength(p_env); +} + +RID RendererSceneRender::environment_get_glow_map(RID p_env) const { + return environment_storage.environment_get_glow_map(p_env); +} + +// SSR + +void RendererSceneRender::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) { + environment_storage.environment_set_ssr(p_env, p_enable, p_max_steps, p_fade_int, p_fade_out, p_depth_tolerance); +} + +bool RendererSceneRender::environment_get_ssr_enabled(RID p_env) const { + return environment_storage.environment_get_ssr_enabled(p_env); +} + +int RendererSceneRender::environment_get_ssr_max_steps(RID p_env) const { + return environment_storage.environment_get_ssr_max_steps(p_env); +} + +float RendererSceneRender::environment_get_ssr_fade_in(RID p_env) const { + return environment_storage.environment_get_ssr_fade_in(p_env); +} + +float RendererSceneRender::environment_get_ssr_fade_out(RID p_env) const { + return environment_storage.environment_get_ssr_fade_out(p_env); +} + +float RendererSceneRender::environment_get_ssr_depth_tolerance(RID p_env) const { + return environment_storage.environment_get_ssr_depth_tolerance(p_env); +} + +// SSAO + +void RendererSceneRender::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) { + environment_storage.environment_set_ssao(p_env, p_enable, p_radius, p_intensity, p_power, p_detail, p_horizon, p_sharpness, p_light_affect, p_ao_channel_affect); +} + +bool RendererSceneRender::environment_get_ssao_enabled(RID p_env) const { + return environment_storage.environment_get_ssao_enabled(p_env); +} + +float RendererSceneRender::environment_get_ssao_radius(RID p_env) const { + return environment_storage.environment_get_ssao_radius(p_env); +} + +float RendererSceneRender::environment_get_ssao_intensity(RID p_env) const { + return environment_storage.environment_get_ssao_intensity(p_env); +} + +float RendererSceneRender::environment_get_ssao_power(RID p_env) const { + return environment_storage.environment_get_ssao_power(p_env); +} + +float RendererSceneRender::environment_get_ssao_detail(RID p_env) const { + return environment_storage.environment_get_ssao_detail(p_env); +} + +float RendererSceneRender::environment_get_ssao_horizon(RID p_env) const { + return environment_storage.environment_get_ssao_horizon(p_env); +} + +float RendererSceneRender::environment_get_ssao_sharpness(RID p_env) const { + return environment_storage.environment_get_ssao_sharpness(p_env); +} + +float RendererSceneRender::environment_get_ssao_direct_light_affect(RID p_env) const { + return environment_storage.environment_get_ssao_direct_light_affect(p_env); +} + +float RendererSceneRender::environment_get_ssao_ao_channel_affect(RID p_env) const { + return environment_storage.environment_get_ssao_ao_channel_affect(p_env); +} + +// SSIL + +void RendererSceneRender::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) { + environment_storage.environment_set_ssil(p_env, p_enable, p_radius, p_intensity, p_sharpness, p_normal_rejection); +} + +bool RendererSceneRender::environment_get_ssil_enabled(RID p_env) const { + return environment_storage.environment_get_ssil_enabled(p_env); +} + +float RendererSceneRender::environment_get_ssil_radius(RID p_env) const { + return environment_storage.environment_get_ssil_radius(p_env); +} + +float RendererSceneRender::environment_get_ssil_intensity(RID p_env) const { + return environment_storage.environment_get_ssil_intensity(p_env); +} + +float RendererSceneRender::environment_get_ssil_sharpness(RID p_env) const { + return environment_storage.environment_get_ssil_sharpness(p_env); +} + +float RendererSceneRender::environment_get_ssil_normal_rejection(RID p_env) const { + return environment_storage.environment_get_ssil_normal_rejection(p_env); +} + +// SDFGI + +void RendererSceneRender::environment_set_sdfgi(RID p_env, bool p_enable, int 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_storage.environment_set_sdfgi(p_env, p_enable, p_cascades, p_min_cell_size, p_y_scale, p_use_occlusion, p_bounce_feedback, p_read_sky, p_energy, p_normal_bias, p_probe_bias); +} + +bool RendererSceneRender::environment_get_sdfgi_enabled(RID p_env) const { + return environment_storage.environment_get_sdfgi_enabled(p_env); +} + +int RendererSceneRender::environment_get_sdfgi_cascades(RID p_env) const { + return environment_storage.environment_get_sdfgi_cascades(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_min_cell_size(RID p_env) const { + return environment_storage.environment_get_sdfgi_min_cell_size(p_env); +} + +bool RendererSceneRender::environment_get_sdfgi_use_occlusion(RID p_env) const { + return environment_storage.environment_get_sdfgi_use_occlusion(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_bounce_feedback(RID p_env) const { + return environment_storage.environment_get_sdfgi_bounce_feedback(p_env); +} + +bool RendererSceneRender::environment_get_sdfgi_read_sky_light(RID p_env) const { + return environment_storage.environment_get_sdfgi_read_sky_light(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_energy(RID p_env) const { + return environment_storage.environment_get_sdfgi_energy(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_normal_bias(RID p_env) const { + return environment_storage.environment_get_sdfgi_normal_bias(p_env); +} + +float RendererSceneRender::environment_get_sdfgi_probe_bias(RID p_env) const { + return environment_storage.environment_get_sdfgi_probe_bias(p_env); +} + +RS::EnvironmentSDFGIYScale RendererSceneRender::environment_get_sdfgi_y_scale(RID p_env) const { + return environment_storage.environment_get_sdfgi_y_scale(p_env); +} + +// Adjustments + +void RendererSceneRender::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) { + environment_storage.environment_set_adjustment(p_env, p_enable, p_brightness, p_contrast, p_saturation, p_use_1d_color_correction, p_color_correction); +} + +bool RendererSceneRender::environment_get_adjustments_enabled(RID p_env) const { + return environment_storage.environment_get_adjustments_enabled(p_env); +} + +float RendererSceneRender::environment_get_adjustments_brightness(RID p_env) const { + return environment_storage.environment_get_adjustments_brightness(p_env); +} + +float RendererSceneRender::environment_get_adjustments_contrast(RID p_env) const { + return environment_storage.environment_get_adjustments_contrast(p_env); +} + +float RendererSceneRender::environment_get_adjustments_saturation(RID p_env) const { + return environment_storage.environment_get_adjustments_saturation(p_env); +} + +bool RendererSceneRender::environment_get_use_1d_color_correction(RID p_env) const { + return environment_storage.environment_get_use_1d_color_correction(p_env); +} + +RID RendererSceneRender::environment_get_color_correction(RID p_env) const { + return environment_storage.environment_get_color_correction(p_env); +} diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 74c7d55a57..7f70f4b939 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -28,14 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RENDERINGSERVERSCENERENDER_H -#define RENDERINGSERVERSCENERENDER_H +#ifndef RENDERER_SCENE_RENDER_H +#define RENDERER_SCENE_RENDER_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/paged_array.h" +#include "servers/rendering/renderer_geometry_instance.h" #include "servers/rendering/renderer_scene.h" +#include "servers/rendering/storage/environment_storage.h" +#include "storage/utilities.h" class RendererSceneRender { +private: + RendererEnvironmentStorage environment_storage; + public: enum { MAX_DIRECTIONAL_LIGHTS = 8, @@ -43,38 +49,11 @@ public: MAX_RENDER_VIEWS = 2 }; - struct GeometryInstance { - virtual ~GeometryInstance() {} - }; - - virtual GeometryInstance *geometry_instance_create(RID p_base) = 0; - virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) = 0; - virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0; - virtual void geometry_instance_set_material_overlay(GeometryInstance *p_geometry_instance, RID p_override) = 0; - virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0; - virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0; - virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0; - virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0; - virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0; - virtual void geometry_instance_set_transparency(GeometryInstance *p_geometry_instance, float p_transparency) = 0; - virtual void geometry_instance_set_fade_range(GeometryInstance *p_geometry_instance, bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) = 0; - virtual void geometry_instance_set_parent_fade_alpha(GeometryInstance *p_geometry_instance, float p_alpha) = 0; - virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0; - virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) = 0; - virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0; - virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) = 0; - virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) = 0; - virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) = 0; + /* Geometry Instance */ + virtual RenderGeometryInstance *geometry_instance_create(RID p_base) = 0; + virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) = 0; virtual uint32_t geometry_instance_get_pair_mask() = 0; - virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) = 0; - virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0; - virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0; - virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) = 0; - - virtual void geometry_instance_set_softshadow_projector_pairing(GeometryInstance *p_geometry_instance, bool p_softshadow, bool p_projector) = 0; - - virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0; /* SHADOW ATLAS API */ @@ -106,57 +85,160 @@ public: /* ENVIRONMENT API */ - 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; - virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) = 0; - virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) = 0; - virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0; - virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0; - virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0; - virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) = 0; + RID environment_allocate(); + void environment_initialize(RID p_rid); + void environment_free(RID p_rid); + + bool is_environment(RID p_env) const; + + // Background + void environment_set_background(RID p_env, RS::EnvironmentBG p_bg); + void environment_set_sky(RID p_env, RID p_sky); + void environment_set_sky_custom_fov(RID p_env, float p_scale); + void environment_set_sky_orientation(RID p_env, const Basis &p_orientation); + void environment_set_bg_color(RID p_env, const Color &p_color); + void environment_set_bg_energy(RID p_env, float p_energy); + void environment_set_canvas_max_layer(RID p_env, int p_max_layer); + void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG); // FIXME: Disabled during Vulkan refactoring, should be ported. #if 0 - virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0; + void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id); #endif - virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0; - virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; - virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + RS::EnvironmentBG environment_get_background(RID p_env) const; + RID environment_get_sky(RID p_env) const; + float environment_get_sky_custom_fov(RID p_env) const; + Basis environment_get_sky_orientation(RID p_env) const; + Color environment_get_bg_color(RID p_env) const; + float environment_get_bg_energy(RID p_env) const; + int environment_get_canvas_max_layer(RID p_env) const; + RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const; + Color environment_get_ambient_light(RID p_env) const; + float environment_get_ambient_light_energy(RID p_env) const; + float environment_get_ambient_sky_contribution(RID p_env) const; + RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const; + + // Tonemap + void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); + RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const; + float environment_get_exposure(RID p_env) const; + float environment_get_white(RID p_env) const; + bool environment_get_auto_exposure(RID p_env) const; + float environment_get_min_luminance(RID p_env) const; + float environment_get_max_luminance(RID p_env) const; + float environment_get_auto_exp_speed(RID p_env) const; + float environment_get_auto_exp_scale(RID p_env) const; + uint64_t environment_get_auto_exposure_version(RID p_env) const; + + // Fog + 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); + bool environment_get_fog_enabled(RID p_env) const; + Color environment_get_fog_light_color(RID p_env) const; + float environment_get_fog_light_energy(RID p_env) const; + float environment_get_fog_sun_scatter(RID p_env) const; + float environment_get_fog_density(RID p_env) const; + float environment_get_fog_height(RID p_env) const; + float environment_get_fog_height_density(RID p_env) const; + float environment_get_fog_aerial_perspective(RID p_env) const; + + // Volumetric Fog + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject); + bool environment_get_volumetric_fog_enabled(RID p_env) const; + float environment_get_volumetric_fog_density(RID p_env) const; + Color environment_get_volumetric_fog_scattering(RID p_env) const; + Color environment_get_volumetric_fog_emission(RID p_env) const; + float environment_get_volumetric_fog_emission_energy(RID p_env) const; + float environment_get_volumetric_fog_anisotropy(RID p_env) const; + float environment_get_volumetric_fog_length(RID p_env) const; + float environment_get_volumetric_fog_detail_spread(RID p_env) const; + float environment_get_volumetric_fog_gi_inject(RID p_env) const; + bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const; + float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const; + float environment_get_volumetric_fog_ambient_inject(RID p_env) const; - virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) = 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_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0; + // GLOW + void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map); + bool environment_get_glow_enabled(RID p_env) const; + Vector<float> environment_get_glow_levels(RID p_env) const; + float environment_get_glow_intensity(RID p_env) const; + float environment_get_glow_strength(RID p_env) const; + float environment_get_glow_bloom(RID p_env) const; + float environment_get_glow_mix(RID p_env) const; + RS::EnvironmentGlowBlendMode environment_get_glow_blend_mode(RID p_env) const; + float environment_get_glow_hdr_bleed_threshold(RID p_env) const; + float environment_get_glow_hdr_luminance_cap(RID p_env) const; + float environment_get_glow_hdr_bleed_scale(RID p_env) const; + float environment_get_glow_map_strength(RID p_env) const; + RID environment_get_glow_map(RID p_env) const; + + virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0; + virtual void environment_glow_set_use_high_quality(bool p_enable) = 0; + + // SSR + 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); + bool environment_get_ssr_enabled(RID p_env) const; + int environment_get_ssr_max_steps(RID p_env) const; + float environment_get_ssr_fade_in(RID p_env) const; + float environment_get_ssr_fade_out(RID p_env) const; + float environment_get_ssr_depth_tolerance(RID p_env) const; + virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0; - virtual 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) = 0; + // SSAO + 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); + bool environment_get_ssao_enabled(RID p_env) const; + float environment_get_ssao_radius(RID p_env) const; + float environment_get_ssao_intensity(RID p_env) const; + float environment_get_ssao_power(RID p_env) const; + float environment_get_ssao_detail(RID p_env) const; + float environment_get_ssao_horizon(RID p_env) const; + float environment_get_ssao_sharpness(RID p_env) const; + float environment_get_ssao_direct_light_affect(RID p_env) const; + float environment_get_ssao_ao_channel_affect(RID p_env) const; + 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_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) = 0; + // SSIL + void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection); + bool environment_get_ssil_enabled(RID p_env) const; + float environment_get_ssil_radius(RID p_env) const; + float environment_get_ssil_intensity(RID p_env) const; + float environment_get_ssil_sharpness(RID p_env) const; + float environment_get_ssil_normal_rejection(RID p_env) const; + virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality 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, int 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; + // SDFGI + void environment_set_sdfgi(RID p_env, bool p_enable, int 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); + bool environment_get_sdfgi_enabled(RID p_env) const; + int environment_get_sdfgi_cascades(RID p_env) const; + float environment_get_sdfgi_min_cell_size(RID p_env) const; + bool environment_get_sdfgi_use_occlusion(RID p_env) const; + float environment_get_sdfgi_bounce_feedback(RID p_env) const; + bool environment_get_sdfgi_read_sky_light(RID p_env) const; + float environment_get_sdfgi_energy(RID p_env) const; + float environment_get_sdfgi_normal_bias(RID p_env) const; + float environment_get_sdfgi_probe_bias(RID p_env) const; + RS::EnvironmentSDFGIYScale environment_get_sdfgi_y_scale(RID p_env) const; 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; virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0; - virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0; - - virtual 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) = 0; - - 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; + // Adjustment + 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); + bool environment_get_adjustments_enabled(RID p_env) const; + float environment_get_adjustments_brightness(RID p_env) const; + float environment_get_adjustments_contrast(RID p_env) const; + float environment_get_adjustments_saturation(RID p_env) const; + bool environment_get_use_1d_color_correction(RID p_env) const; + RID environment_get_color_correction(RID p_env) const; virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0; - virtual bool is_environment(RID p_env) const = 0; - 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_allocate() = 0; virtual void camera_effects_initialize(RID p_rid) = 0; @@ -172,7 +254,7 @@ public: virtual RID light_instance_create(RID p_light) = 0; virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) = 0; virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0; - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; + virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; virtual void light_instance_mark_visible(RID p_light_instance) = 0; virtual bool light_instances_can_render_shadow_cube() const { return true; @@ -205,19 +287,19 @@ public: virtual RID voxel_gi_instance_create(RID p_voxel_gi) = 0; virtual void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) = 0; virtual bool voxel_gi_needs_update(RID p_probe) const = 0; - virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0; + virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) = 0; virtual void voxel_gi_set_quality(RS::VoxelGIQuality) = 0; struct RenderShadowData { RID light; int pass = 0; - PagedArray<GeometryInstance *> instances; + PagedArray<RenderGeometryInstance *> instances; }; struct RenderSDFGIData { int region = 0; - PagedArray<GeometryInstance *> instances; + PagedArray<RenderGeometryInstance *> instances; }; struct RenderSDFGIUpdateData { @@ -239,27 +321,27 @@ public: // Main/center projection Transform3D main_transform; - CameraMatrix main_projection; + Projection main_projection; Transform3D view_offset[RendererSceneRender::MAX_RENDER_VIEWS]; - CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; Vector2 taa_jitter; - void set_camera(const Transform3D p_transform, const CameraMatrix p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2()); - void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const CameraMatrix *p_projections, bool p_is_orthogonal, bool p_vaspect); + void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2()); + void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect); }; - virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info = nullptr) = 0; + virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_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, RendererScene::RenderInfo *r_render_info = nullptr) = 0; - virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; - virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0; + virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) = 0; virtual void set_scene_pass(uint64_t p_pass) = 0; virtual void set_time(double p_time, double p_step) = 0; virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0; virtual RID render_buffers_create() = 0; - virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0; + virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0; virtual void gi_set_use_half_resolution(bool p_enable) = 0; virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0; @@ -281,4 +363,4 @@ public: virtual ~RendererSceneRender() {} }; -#endif // RENDERINGSERVERSCENERENDER_H +#endif // RENDERER_SCENE_RENDER_H diff --git a/servers/rendering/renderer_thread_pool.cpp b/servers/rendering/renderer_thread_pool.cpp deleted file mode 100644 index ddf1d1bd00..0000000000 --- a/servers/rendering/renderer_thread_pool.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************/ -/* renderer_thread_pool.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 "renderer_thread_pool.h" - -RendererThreadPool *RendererThreadPool::singleton = nullptr; - -RendererThreadPool::RendererThreadPool() { - singleton = this; - thread_work_pool.init(); -} - -RendererThreadPool::~RendererThreadPool() { - thread_work_pool.finish(); -} diff --git a/servers/rendering/renderer_thread_pool.h b/servers/rendering/renderer_thread_pool.h deleted file mode 100644 index 4626490d32..0000000000 --- a/servers/rendering/renderer_thread_pool.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************/ -/* renderer_thread_pool.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 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 RENDERERTHREADPOOL_H -#define RENDERERTHREADPOOL_H - -#include "core/templates/thread_work_pool.h" - -class RendererThreadPool { -public: - ThreadWorkPool thread_work_pool; - - static RendererThreadPool *singleton; - RendererThreadPool(); - ~RendererThreadPool(); -}; - -#endif // RENDERERTHREADPOOL_H diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 7c9b2567d6..118bf532b3 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -138,7 +138,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) { p_viewport->internal_size = Size2(render_width, render_height); - RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, render_width, render_height, width, height, p_viewport->fsr_sharpness, p_viewport->fsr_mipmap_bias, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->get_view_count()); + RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, render_width, render_height, width, height, p_viewport->fsr_sharpness, p_viewport->texture_mipmap_bias, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->get_view_count()); } } } @@ -154,7 +154,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) { if (p_viewport->use_occlusion_culling) { if (p_viewport->occlusion_buffer_dirty) { float aspect = p_viewport->size.aspect(); - int max_size = occlusion_rays_per_thread * RendererThreadPool::singleton->thread_work_pool.get_thread_count(); + int max_size = occlusion_rays_per_thread * WorkerThreadPool::get_singleton()->get_thread_count(); int viewport_size = p_viewport->size.width * p_viewport->size.height; max_size = CLAMP(max_size, viewport_size / (32 * 32), viewport_size / (2 * 2)); // At least one depth pixel for every 16x16 region. At most one depth pixel for every 2x2 region. @@ -746,11 +746,11 @@ void RendererViewport::viewport_set_fsr_sharpness(RID p_viewport, float p_sharpn _configure_3d_render_buffers(viewport); } -void RendererViewport::viewport_set_fsr_mipmap_bias(RID p_viewport, float p_mipmap_bias) { +void RendererViewport::viewport_set_texture_mipmap_bias(RID p_viewport, float p_mipmap_bias) { Viewport *viewport = viewport_owner.get_or_null(p_viewport); ERR_FAIL_COND(!viewport); - viewport->fsr_mipmap_bias = p_mipmap_bias; + viewport->texture_mipmap_bias = p_mipmap_bias; _configure_3d_render_buffers(viewport); } diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index 027f2dfad6..5e37c96336 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -48,33 +48,34 @@ public: RID self; RID parent; - bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */ + // use xr interface to override camera positioning and projection matrices and control output + bool use_xr = false; Size2i internal_size; Size2i size; RID camera; RID scenario; - RS::ViewportScaling3DMode scaling_3d_mode; + RS::ViewportScaling3DMode scaling_3d_mode = RenderingServer::VIEWPORT_SCALING_3D_MODE_BILINEAR; float scaling_3d_scale = 1.0; float fsr_sharpness = 0.2f; - float fsr_mipmap_bias = 0.0f; - bool fsr_enabled; - RS::ViewportUpdateMode update_mode; + float texture_mipmap_bias = 0.0f; + bool fsr_enabled = false; + RS::ViewportUpdateMode update_mode = RenderingServer::VIEWPORT_UPDATE_WHEN_VISIBLE; RID render_target; RID render_target_texture; RID render_buffers; - RS::ViewportMSAA msaa; - RS::ViewportScreenSpaceAA screen_space_aa; - bool use_taa; - bool use_debanding; + RS::ViewportMSAA msaa = RenderingServer::VIEWPORT_MSAA_DISABLED; + RS::ViewportScreenSpaceAA screen_space_aa = RenderingServer::VIEWPORT_SCREEN_SPACE_AA_DISABLED; + bool use_taa = false; + bool use_debanding = false; RendererSceneRender::CameraData prev_camera_data; uint64_t prev_camera_data_frame = 0; - bool use_occlusion_culling; - bool occlusion_buffer_dirty; + bool use_occlusion_culling = false; + bool occlusion_buffer_dirty = false; DisplayServer::WindowID viewport_to_screen; Rect2 viewport_to_screen_rect; @@ -83,10 +84,10 @@ public: bool disable_2d = false; bool disable_environment = false; bool disable_3d = false; - bool measure_render_time; + bool measure_render_time = false; - bool snap_2d_transforms_to_pixel; - bool snap_2d_vertices_to_pixel; + bool snap_2d_transforms_to_pixel = false; + bool snap_2d_vertices_to_pixel = false; uint64_t time_cpu_begin; uint64_t time_cpu_end; @@ -95,23 +96,23 @@ public: uint64_t time_gpu_end; RID shadow_atlas; - int shadow_atlas_size; + int shadow_atlas_size = 2048; bool shadow_atlas_16_bits = true; - bool sdf_active; + bool sdf_active = false; float mesh_lod_threshold = 1.0; uint64_t last_pass = 0; - RS::ViewportDebugDraw debug_draw; + RS::ViewportDebugDraw debug_draw = RenderingServer::VIEWPORT_DEBUG_DRAW_DISABLED; - RS::ViewportClearMode clear_mode; + RS::ViewportClearMode clear_mode = RenderingServer::VIEWPORT_CLEAR_ALWAYS; RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; - bool transparent_bg; + bool transparent_bg = false; struct CanvasKey { int64_t stacking; @@ -228,7 +229,7 @@ public: void viewport_set_scaling_3d_mode(RID p_viewport, RS::ViewportScaling3DMode p_mode); void viewport_set_scaling_3d_scale(RID p_viewport, float p_scaling_3d_scale); void viewport_set_fsr_sharpness(RID p_viewport, float p_sharpness); - void viewport_set_fsr_mipmap_bias(RID p_viewport, float p_mipmap_bias); + void viewport_set_texture_mipmap_bias(RID p_viewport, float p_mipmap_bias); void viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode); void viewport_set_vflip(RID p_viewport, bool p_enable); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 429b8a06e2..21a94b88f2 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -224,6 +224,7 @@ public: FUNCRIDSPLIT(shader) FUNC2(shader_set_code, RID, const String &) + FUNC2(shader_set_path_hint, RID, const String &) FUNC1RC(String, shader_get_code, RID) FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *) @@ -590,7 +591,7 @@ public: FUNC2(viewport_set_scaling_3d_mode, RID, ViewportScaling3DMode) FUNC2(viewport_set_scaling_3d_scale, RID, float) FUNC2(viewport_set_fsr_sharpness, RID, float) - FUNC2(viewport_set_fsr_mipmap_bias, RID, float) + FUNC2(viewport_set_texture_mipmap_bias, RID, float) FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode) @@ -899,7 +900,7 @@ public: FUNC1(canvas_set_shadow_texture_size, int) - /* GLOBAL VARIABLES */ + /* GLOBAL SHADER UNIFORMS */ #undef server_name #undef ServerName @@ -907,16 +908,16 @@ public: #define ServerName RendererMaterialStorage #define server_name RSG::material_storage - 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 &) + FUNC3(global_shader_uniform_add, const StringName &, GlobalShaderUniformType, const Variant &) + FUNC1(global_shader_uniform_remove, const StringName &) + FUNC0RC(Vector<StringName>, global_shader_uniform_get_list) + FUNC2(global_shader_uniform_set, const StringName &, const Variant &) + FUNC2(global_shader_uniform_set_override, const StringName &, const Variant &) + FUNC1RC(GlobalShaderUniformType, global_shader_uniform_get_type, const StringName &) + FUNC1RC(Variant, global_shader_uniform_get, const StringName &) - FUNC1(global_variables_load_settings, bool) - FUNC0(global_variables_clear) + FUNC1(global_shader_uniforms_load_settings, bool) + FUNC0(global_shader_uniforms_clear) #undef server_name #undef ServerName @@ -980,4 +981,4 @@ public: ~RenderingServerDefault(); }; -#endif +#endif // RENDERING_SERVER_DEFAULT_H diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 463b67033d..7637eae4a6 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -370,7 +370,7 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str } } -static String _get_global_variable_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) { +static String _get_global_shader_uniform_from_type_and_index(const String &p_buffer, const String &p_index, ShaderLanguage::DataType p_type) { switch (p_type) { case ShaderLanguage::TYPE_BOOL: { return "(" + p_buffer + "[" + p_index + "].x != 0.0)"; @@ -903,11 +903,11 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { code = actions.base_uniform_string + _mkid(vnode->name); //texture, use as is //global variable, this means the code points to an index to the global table - code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + code = _get_global_shader_uniform_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); } else if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { //instance variable, index it as such code = "(" + p_default_actions.instance_uniform_index_variable + "+" + itos(u.instance_index) + ")"; - code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + code = _get_global_shader_uniform_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); } else { //regular uniform, index from UBO code = actions.base_uniform_string + _mkid(vnode->name); @@ -1003,11 +1003,11 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL) { code = actions.base_uniform_string + _mkid(anode->name); //texture, use as is //global variable, this means the code points to an index to the global table - code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + code = _get_global_shader_uniform_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); } else if (u.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { //instance variable, index it as such code = "(" + p_default_actions.instance_uniform_index_variable + "+" + itos(u.instance_index) + ")"; - code = _get_global_variable_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); + code = _get_global_shader_uniform_from_type_and_index(p_default_actions.global_buffer_array_variable, code, u.type); } else { //regular uniform, index from UBO code = actions.base_uniform_string + _mkid(anode->name); @@ -1309,8 +1309,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } ShaderLanguage::DataType ShaderCompiler::_get_variable_type(const StringName &p_type) { - RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_type); - return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt); + RS::GlobalShaderUniformType gvt = RS::get_singleton()->global_shader_uniform_get_type(p_type); + return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt); } Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) { @@ -1318,23 +1318,81 @@ Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, Ident info.functions = ShaderTypes::get_singleton()->get_functions(p_mode); info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode); info.shader_types = ShaderTypes::get_singleton()->get_types(); - info.global_variable_type_func = _get_variable_type; + info.global_shader_uniform_type_func = _get_variable_type; Error err = parser.compile(p_code, info); if (err != OK) { + Vector<ShaderLanguage::FilePosition> include_positions = parser.get_include_positions(); + + String current; + HashMap<String, Vector<String>> includes; + includes[""] = Vector<String>(); + Vector<String> include_stack; Vector<String> shader = p_code.split("\n"); + + // Reconstruct the files. for (int i = 0; i < shader.size(); i++) { - if (i + 1 == parser.get_error_line()) { - // Mark the error line to be visible without having to look at - // the trace at the end. - print_line(vformat("E%4d-> %s", i + 1, shader[i])); + String l = shader[i]; + if (l.begins_with("@@>")) { + String inc_path = l.replace_first("@@>", ""); + + l = "#include \"" + inc_path + "\""; + includes[current].append("#include \"" + inc_path + "\""); // Restore the include directive + include_stack.push_back(current); + current = inc_path; + includes[inc_path] = Vector<String>(); + + } else if (l.begins_with("@@<")) { + if (include_stack.size()) { + current = include_stack[include_stack.size() - 1]; + include_stack.resize(include_stack.size() - 1); + } + } else { + includes[current].push_back(l); + } + } + + // Print the files. + for (const KeyValue<String, Vector<String>> &E : includes) { + if (E.key.is_empty()) { + if (p_path == "") { + print_line("--Main Shader--"); + } else { + print_line("--" + p_path + "--"); + } } else { - print_line(vformat("%5d | %s", i + 1, shader[i])); + print_line("--" + E.key + "--"); } + int err_line = -1; + for (int i = 0; i < include_positions.size(); i++) { + if (include_positions[i].file == E.key) { + err_line = include_positions[i].line; + } + } + const Vector<String> &V = E.value; + for (int i = 0; i < V.size(); i++) { + if (i == err_line - 1) { + // Mark the error line to be visible without having to look at + // the trace at the end. + print_line(vformat("E%4d-> %s", i + 1, V[i])); + } else { + print_line(vformat("%5d | %s", i + 1, V[i])); + } + } + } + + String file; + int line; + if (include_positions.size() > 1) { + file = include_positions[include_positions.size() - 1].file; + line = include_positions[include_positions.size() - 1].line; + } else { + file = p_path; + line = parser.get_error_line(); } - _err_print_error(nullptr, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), false, ERR_HANDLER_SHADER); + _err_print_error(nullptr, file.utf8().get_data(), line, parser.get_error_text().utf8().get_data(), false, ERR_HANDLER_SHADER); return err; } diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index ad9b51ac0c..2dd0f7006b 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -32,7 +32,9 @@ #include "core/os/os.h" #include "core/string/print_string.h" +#include "core/templates/local_vector.h" #include "servers/rendering_server.h" +#include "shader_types.h" #define HAS_WARNING(flag) (warning_flags & flag) @@ -308,6 +310,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = { // global space keywords { TK_UNIFORM, "uniform", CF_GLOBAL_SPACE | CF_UNIFORM_KEYWORD, {}, {} }, + { TK_UNIFORM_GROUP, "group_uniforms", CF_GLOBAL_SPACE, {}, {} }, { TK_VARYING, "varying", CF_GLOBAL_SPACE, { "particles", "sky", "fog" }, {} }, { TK_CONST, "const", CF_BLOCK | CF_GLOBAL_SPACE | CF_CONST_KEYWORD, {}, {} }, { TK_STRUCT, "struct", CF_GLOBAL_SPACE, {}, {} }, @@ -574,6 +577,37 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { return _make_token(TK_OP_MOD); } break; + case '@': { + if (GETCHAR(0) == '@' && GETCHAR(1) == '>') { + char_idx += 2; + + LocalVector<char32_t> incp; + while (GETCHAR(0) != '\n') { + incp.push_back(GETCHAR(0)); + char_idx++; + } + incp.push_back(0); // Zero end it. + String include_path(incp.ptr()); + include_positions.write[include_positions.size() - 1].line = tk_line; + FilePosition fp; + fp.file = include_path; + fp.line = 0; + tk_line = 0; + include_positions.push_back(fp); + + } else if (GETCHAR(0) == '@' && GETCHAR(1) == '<') { + if (include_positions.size() == 1) { + return _make_token(TK_ERROR, "Invalid include exit hint @@< without matching enter hint."); + } + char_idx += 2; + + include_positions.resize(include_positions.size() - 1); // Pop back. + tk_line = include_positions[include_positions.size() - 1].line; // Restore line. + + } else { + return _make_token(TK_ERROR, "Invalid include enter/exit hint token (@@> and @@<)"); + } + } break; default: { char_idx--; //go back one, since we have no idea what this is @@ -1113,6 +1147,8 @@ void ShaderLanguage::clear() { current_function = StringName(); last_name = StringName(); last_type = IDENTIFIER_MAX; + current_uniform_group_name = ""; + current_uniform_subgroup_name = ""; completion_type = COMPLETION_NONE; completion_block = nullptr; @@ -1122,6 +1158,9 @@ void ShaderLanguage::clear() { completion_base = TYPE_VOID; completion_base_array = false; + include_positions.clear(); + include_positions.push_back(FilePosition()); + #ifdef DEBUG_ENABLED keyword_completion_context = CF_GLOBAL_SPACE; used_constants.clear(); @@ -1183,17 +1222,36 @@ void ShaderLanguage::_parse_used_identifier(const StringName &p_identifier, Iden #endif // DEBUG_ENABLED bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name, ConstantNode::Value *r_constant_value) { - if (p_function_info.built_ins.has(p_identifier)) { - if (r_data_type) { - *r_data_type = p_function_info.built_ins[p_identifier].type; - } - if (r_is_const) { - *r_is_const = p_function_info.built_ins[p_identifier].constant; + if (is_shader_inc) { + for (int i = 0; i < RenderingServer::SHADER_MAX; i++) { + for (const KeyValue<StringName, FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) { + if ((current_function == E.key || E.key == "global") && E.value.built_ins.has(p_identifier)) { + if (r_data_type) { + *r_data_type = E.value.built_ins[p_identifier].type; + } + if (r_is_const) { + *r_is_const = E.value.built_ins[p_identifier].constant; + } + if (r_type) { + *r_type = IDENTIFIER_BUILTIN_VAR; + } + return true; + } + } } - if (r_type) { - *r_type = IDENTIFIER_BUILTIN_VAR; + } else { + if (p_function_info.built_ins.has(p_identifier)) { + if (r_data_type) { + *r_data_type = p_function_info.built_ins[p_identifier].type; + } + if (r_is_const) { + *r_is_const = p_function_info.built_ins[p_identifier].constant; + } + if (r_type) { + *r_type = IDENTIFIER_BUILTIN_VAR; + } + return true; } - return true; } if (p_function_info.stage_functions.has(p_identifier)) { @@ -3798,18 +3856,11 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C } value = Variant(array); } else { - Basis p; - p[0][0] = p_value[0].real; - p[0][1] = p_value[1].real; - p[0][2] = p_value[2].real; - p[1][0] = p_value[4].real; - p[1][1] = p_value[5].real; - p[1][2] = p_value[6].real; - p[2][0] = p_value[8].real; - p[2][1] = p_value[9].real; - p[2][2] = p_value[10].real; - Transform3D t = Transform3D(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real)); - value = Variant(t); + Projection p = Projection(Vector4(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real), + Vector4(p_value[4].real, p_value[5].real, p_value[6].real, p_value[7].real), + Vector4(p_value[8].real, p_value[9].real, p_value[10].real, p_value[11].real), + Vector4(p_value[12].real, p_value[13].real, p_value[14].real, p_value[15].real)); + value = Variant(p); } break; } @@ -3891,13 +3942,29 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform } } } break; - case ShaderLanguage::TYPE_IVEC2: - case ShaderLanguage::TYPE_IVEC3: - case ShaderLanguage::TYPE_IVEC4: case ShaderLanguage::TYPE_UVEC2: + case ShaderLanguage::TYPE_IVEC2: { + if (p_uniform.array_size > 0) { + pi.type = Variant::PACKED_INT32_ARRAY; + } else { + pi.type = Variant::VECTOR2I; + } + } break; case ShaderLanguage::TYPE_UVEC3: - case ShaderLanguage::TYPE_UVEC4: { - pi.type = Variant::PACKED_INT32_ARRAY; + case ShaderLanguage::TYPE_IVEC3: { + if (p_uniform.array_size > 0) { + pi.type = Variant::PACKED_INT32_ARRAY; + } else { + pi.type = Variant::VECTOR3I; + } + } break; + case ShaderLanguage::TYPE_UVEC4: + case ShaderLanguage::TYPE_IVEC4: { + if (p_uniform.array_size > 0) { + pi.type = Variant::PACKED_INT32_ARRAY; + } else { + pi.type = Variant::VECTOR4I; + } } break; case ShaderLanguage::TYPE_FLOAT: { if (p_uniform.array_size > 0) { @@ -3945,7 +4012,7 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) { pi.type = Variant::COLOR; } else { - pi.type = Variant::QUATERNION; + pi.type = Variant::VECTOR4; } } } break; @@ -3967,7 +4034,7 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform if (p_uniform.array_size > 0) { pi.type = Variant::PACKED_FLOAT32_ARRAY; } else { - pi.type = Variant::TRANSFORM3D; + pi.type = Variant::PROJECTION; } break; case ShaderLanguage::TYPE_SAMPLER2D: @@ -7678,34 +7745,38 @@ Error ShaderLanguage::_validate_precision(DataType p_type, DataPrecision p_preci } Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const HashSet<String> &p_shader_types) { - Token tk = _get_token(); + Token tk; TkPos prev_pos; Token next; - if (tk.type != TK_SHADER_TYPE) { - _set_error(vformat(RTR("Expected '%s' at the beginning of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types))); - return ERR_PARSE_ERROR; - } + if (!is_shader_inc) { + tk = _get_token(); + + if (tk.type != TK_SHADER_TYPE) { + _set_error(vformat(RTR("Expected '%s' at the beginning of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types))); + return ERR_PARSE_ERROR; + } #ifdef DEBUG_ENABLED - keyword_completion_context = CF_UNSPECIFIED; + keyword_completion_context = CF_UNSPECIFIED; #endif // DEBUG_ENABLED - _get_completable_identifier(nullptr, COMPLETION_SHADER_TYPE, shader_type_identifier); - if (shader_type_identifier == StringName()) { - _set_error(vformat(RTR("Expected an identifier after '%s', indicating the type of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types))); - return ERR_PARSE_ERROR; - } - if (!p_shader_types.has(shader_type_identifier)) { - _set_error(vformat(RTR("Invalid shader type. Valid types are: %s"), _get_shader_type_list(p_shader_types))); - return ERR_PARSE_ERROR; - } - prev_pos = _get_tkpos(); - tk = _get_token(); + _get_completable_identifier(nullptr, COMPLETION_SHADER_TYPE, shader_type_identifier); + if (shader_type_identifier == StringName()) { + _set_error(vformat(RTR("Expected an identifier after '%s', indicating the type of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types))); + return ERR_PARSE_ERROR; + } + if (!p_shader_types.has(shader_type_identifier)) { + _set_error(vformat(RTR("Invalid shader type. Valid types are: %s"), _get_shader_type_list(p_shader_types))); + return ERR_PARSE_ERROR; + } + prev_pos = _get_tkpos(); + tk = _get_token(); - if (tk.type != TK_SEMICOLON) { - _set_tkpos(prev_pos); - _set_expected_after_error(";", "shader_type " + String(shader_type_identifier)); - return ERR_PARSE_ERROR; + if (tk.type != TK_SEMICOLON) { + _set_tkpos(prev_pos); + _set_expected_after_error(";", "shader_type " + String(shader_type_identifier)); + return ERR_PARSE_ERROR; + } } #ifdef DEBUG_ENABLED @@ -7760,25 +7831,54 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f bool found = false; - for (int i = 0; i < p_render_modes.size(); i++) { - const ModeInfo &info = p_render_modes[i]; - const String name = String(info.name); + if (is_shader_inc) { + for (int i = 0; i < RenderingServer::SHADER_MAX; i++) { + const Vector<ModeInfo> modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i)); - if (smode.begins_with(name)) { - if (!info.options.is_empty()) { - if (info.options.has(smode.substr(name.length() + 1))) { - found = true; + for (int j = 0; j < modes.size(); j++) { + const ModeInfo &info = modes[j]; + const String name = String(info.name); - if (defined_modes.has(name)) { - _set_error(vformat(RTR("Redefinition of render mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, defined_modes[name])); - return ERR_PARSE_ERROR; + if (smode.begins_with(name)) { + if (!info.options.is_empty()) { + if (info.options.has(smode.substr(name.length() + 1))) { + found = true; + + if (defined_modes.has(name)) { + _set_error(vformat(RTR("Redefinition of render mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, defined_modes[name])); + return ERR_PARSE_ERROR; + } + defined_modes.insert(name, smode); + break; + } + } else { + found = true; + break; } - defined_modes.insert(name, smode); + } + } + } + } else { + for (int i = 0; i < p_render_modes.size(); i++) { + const ModeInfo &info = p_render_modes[i]; + const String name = String(info.name); + + if (smode.begins_with(name)) { + if (!info.options.is_empty()) { + if (info.options.has(smode.substr(name.length() + 1))) { + found = true; + + if (defined_modes.has(name)) { + _set_error(vformat(RTR("Redefinition of render mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, defined_modes[name])); + return ERR_PARSE_ERROR; + } + defined_modes.insert(name, smode); + break; + } + } else { + found = true; break; } - } else { - found = true; - break; } } } @@ -8177,7 +8277,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f if (is_uniform) { if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL && Engine::get_singleton()->is_editor_hint()) { // Type checking for global uniforms is not allowed outside the editor. //validate global uniform - DataType gvtype = global_var_get_type_func(name); + DataType gvtype = global_shader_uniform_get_type_func(name); if (gvtype == TYPE_MAX) { _set_error(vformat(RTR("Global uniform '%s' does not exist. Create it in Project Settings."), String(name))); return ERR_PARSE_ERROR; @@ -8194,6 +8294,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f uniform.scope = uniform_scope; uniform.precision = precision; uniform.array_size = array_size; + uniform.group = current_uniform_group_name; + uniform.subgroup = current_uniform_subgroup_name; tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { @@ -8620,6 +8722,45 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f } } break; + case TK_UNIFORM_GROUP: { + tk = _get_token(); + if (tk.type == TK_IDENTIFIER) { + current_uniform_group_name = tk.text; + tk = _get_token(); + if (tk.type == TK_PERIOD) { + tk = _get_token(); + if (tk.type == TK_IDENTIFIER) { + current_uniform_subgroup_name = tk.text; + tk = _get_token(); + if (tk.type != TK_SEMICOLON) { + _set_expected_error(";"); + return ERR_PARSE_ERROR; + } + } else { + _set_error(RTR("Expected an uniform subgroup identifier.")); + return ERR_PARSE_ERROR; + } + } else if (tk.type != TK_SEMICOLON) { + _set_expected_error(";", "."); + return ERR_PARSE_ERROR; + } + } else { + if (tk.type != TK_SEMICOLON) { + if (current_uniform_group_name.is_empty()) { + _set_error(RTR("Expected an uniform group identifier.")); + } else { + _set_error(RTR("Expected an uniform group identifier or `;`.")); + } + return ERR_PARSE_ERROR; + } else if (tk.type == TK_SEMICOLON && current_uniform_group_name.is_empty()) { + _set_error(RTR("Group needs to be opened before.")); + return ERR_PARSE_ERROR; + } else { + current_uniform_group_name = ""; + current_uniform_subgroup_name = ""; + } + } + } break; case TK_SHADER_TYPE: { _set_error(RTR("Shader type is already defined.")); return ERR_PARSE_ERROR; @@ -9508,9 +9649,11 @@ uint32_t ShaderLanguage::get_warning_flags() const { Error ShaderLanguage::compile(const String &p_code, const ShaderCompileInfo &p_info) { clear(); + is_shader_inc = p_info.is_include; code = p_code; - global_var_get_type_func = p_info.global_variable_type_func; + global_shader_uniform_get_type_func = p_info.global_shader_uniform_type_func; + varying_function_names = p_info.varying_function_names; nodes = nullptr; @@ -9532,12 +9675,13 @@ Error ShaderLanguage::compile(const String &p_code, const ShaderCompileInfo &p_i Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_info, List<ScriptLanguage::CodeCompletionOption> *r_options, String &r_call_hint) { clear(); + is_shader_inc = p_info.is_include; code = p_code; varying_function_names = p_info.varying_function_names; nodes = nullptr; - global_var_get_type_func = p_info.global_variable_type_func; + global_shader_uniform_get_type_func = p_info.global_shader_uniform_type_func; shader = alloc_node<ShaderNode>(); _parse_shader(p_info.functions, p_info.render_modes, p_info.shader_types); @@ -9577,30 +9721,64 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ return OK; } break; case COMPLETION_RENDER_MODE: { - for (int i = 0; i < p_info.render_modes.size(); i++) { - const ModeInfo &info = p_info.render_modes[i]; + if (is_shader_inc) { + for (int i = 0; i < RenderingServer::SHADER_MAX; i++) { + const Vector<ModeInfo> modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i)); - if (!info.options.is_empty()) { - bool found = false; + for (int j = 0; j < modes.size(); j++) { + const ModeInfo &info = modes[j]; - for (int j = 0; j < info.options.size(); j++) { - if (shader->render_modes.has(String(info.name) + "_" + String(info.options[j]))) { - found = true; + if (!info.options.is_empty()) { + bool found = false; + + for (int k = 0; k < info.options.size(); k++) { + if (shader->render_modes.has(String(info.name) + "_" + String(info.options[k]))) { + found = true; + } + } + + if (!found) { + for (int k = 0; k < info.options.size(); k++) { + ScriptLanguage::CodeCompletionOption option(String(info.name) + "_" + String(info.options[k]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); + r_options->push_back(option); + } + } + } else { + const String name = String(info.name); + + if (!shader->render_modes.has(name)) { + ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); + r_options->push_back(option); + } } } + } + } else { + for (int i = 0; i < p_info.render_modes.size(); i++) { + const ModeInfo &info = p_info.render_modes[i]; + + if (!info.options.is_empty()) { + bool found = false; - if (!found) { for (int j = 0; j < info.options.size(); j++) { - ScriptLanguage::CodeCompletionOption option(String(info.name) + "_" + String(info.options[j]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); - r_options->push_back(option); + if (shader->render_modes.has(String(info.name) + "_" + String(info.options[j]))) { + found = true; + } } - } - } else { - const String name = String(info.name); - if (!shader->render_modes.has(name)) { - ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); - r_options->push_back(option); + if (!found) { + for (int j = 0; j < info.options.size(); j++) { + ScriptLanguage::CodeCompletionOption option(String(info.name) + "_" + String(info.options[j]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); + r_options->push_back(option); + } + } + } else { + const String name = String(info.name); + + if (!shader->render_modes.has(name)) { + ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); + r_options->push_back(option); + } } } } @@ -9668,33 +9846,69 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ } if (comp_ident) { - if (p_info.functions.has("global")) { - for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["global"].built_ins) { - ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; - if (E.value.constant) { - kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + if (is_shader_inc) { + for (int i = 0; i < RenderingServer::SHADER_MAX; i++) { + const HashMap<StringName, ShaderLanguage::FunctionInfo> info = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i)); + + if (info.has("global")) { + for (const KeyValue<StringName, BuiltInInfo> &E : info["global"].built_ins) { + ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; + if (E.value.constant) { + kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + } + matches.insert(E.key, kind); + } + } + + if (info.has("constants")) { + for (const KeyValue<StringName, BuiltInInfo> &E : info["constants"].built_ins) { + ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; + if (E.value.constant) { + kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + } + matches.insert(E.key, kind); + } + } + + if (skip_function != StringName() && info.has(skip_function)) { + for (const KeyValue<StringName, BuiltInInfo> &E : info[skip_function].built_ins) { + ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; + if (E.value.constant) { + kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + } + matches.insert(E.key, kind); + } + } + } + } else { + if (p_info.functions.has("global")) { + for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["global"].built_ins) { + ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; + if (E.value.constant) { + kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + } + matches.insert(E.key, kind); } - matches.insert(E.key, kind); } - } - if (p_info.functions.has("constants")) { - for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["constants"].built_ins) { - ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; - if (E.value.constant) { - kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + if (p_info.functions.has("constants")) { + for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["constants"].built_ins) { + ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; + if (E.value.constant) { + kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + } + matches.insert(E.key, kind); } - matches.insert(E.key, kind); } - } - if (skip_function != StringName() && p_info.functions.has(skip_function)) { - for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions[skip_function].built_ins) { - ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; - if (E.value.constant) { - kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + if (skip_function != StringName() && p_info.functions.has(skip_function)) { + for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions[skip_function].built_ins) { + ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER; + if (E.value.constant) { + kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT; + } + matches.insert(E.key, kind); } - matches.insert(E.key, kind); } } @@ -10066,6 +10280,10 @@ String ShaderLanguage::get_error_text() { return error_str; } +Vector<ShaderLanguage::FilePosition> ShaderLanguage::get_include_positions() { + return include_positions; +} + int ShaderLanguage::get_error_line() { return error_line; } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 2b147fbeb1..09160e2949 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -38,6 +38,7 @@ #include "core/templates/rb_map.h" #include "core/typedefs.h" #include "core/variant/variant.h" +#include "scene/resources/shader_include.h" #ifdef DEBUG_ENABLED #include "shader_warnings.h" @@ -153,6 +154,7 @@ public: TK_SEMICOLON, TK_PERIOD, TK_UNIFORM, + TK_UNIFORM_GROUP, TK_INSTANCE, TK_GLOBAL, TK_VARYING, @@ -686,6 +688,8 @@ public: TextureRepeat repeat = REPEAT_DEFAULT; float hint_range[3]; int instance_index = 0; + String group; + String subgroup; Uniform() { hint_range[0] = 0.0f; @@ -865,7 +869,12 @@ public: }; static bool has_builtin(const HashMap<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name); - typedef DataType (*GlobalVariableGetTypeFunc)(const StringName &p_name); + typedef DataType (*GlobalShaderUniformGetTypeFunc)(const StringName &p_name); + + struct FilePosition { + String file; + int line = 0; + }; private: struct KeyWord { @@ -878,12 +887,14 @@ private: static const KeyWord keyword_list[]; - GlobalVariableGetTypeFunc global_var_get_type_func = nullptr; + GlobalShaderUniformGetTypeFunc global_shader_uniform_get_type_func = nullptr; bool error_set = false; String error_str; int error_line = 0; + Vector<FilePosition> include_positions; + #ifdef DEBUG_ENABLED struct Usage { int decl_line; @@ -928,6 +939,10 @@ private: StringName current_function; bool last_const = false; StringName last_name; + bool is_shader_inc = false; + + String current_uniform_group_name; + String current_uniform_subgroup_name; VaryingFunctionNames varying_function_names; @@ -951,6 +966,7 @@ private: error_line = tk_line; error_set = true; error_str = p_str; + include_positions.write[include_positions.size() - 1].line = tk_line; } void _set_expected_error(const String &p_what) { @@ -1097,13 +1113,15 @@ public: Vector<ModeInfo> render_modes; VaryingFunctionNames varying_function_names = VaryingFunctionNames(); HashSet<String> shader_types; - GlobalVariableGetTypeFunc global_variable_type_func = nullptr; + GlobalShaderUniformGetTypeFunc global_shader_uniform_type_func = nullptr; + bool is_include = false; }; Error compile(const String &p_code, const ShaderCompileInfo &p_info); Error complete(const String &p_code, const ShaderCompileInfo &p_info, List<ScriptLanguage::CodeCompletionOption> *r_options, String &r_call_hint); String get_error_text(); + Vector<FilePosition> get_include_positions(); int get_error_line(); ShaderNode *get_shader(); diff --git a/servers/rendering/shader_preprocessor.cpp b/servers/rendering/shader_preprocessor.cpp new file mode 100644 index 0000000000..a7b274b3e2 --- /dev/null +++ b/servers/rendering/shader_preprocessor.cpp @@ -0,0 +1,1048 @@ +/*************************************************************************/ +/* shader_preprocessor.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "shader_preprocessor.h" +#include "core/math/expression.h" + +const char32_t CURSOR = 0xFFFF; + +// Tokenizer + +void ShaderPreprocessor::Tokenizer::add_generated(const ShaderPreprocessor::Token &p_t) { + generated.push_back(p_t); +} + +char32_t ShaderPreprocessor::Tokenizer::next() { + if (index < size) { + return code[index++]; + } + return 0; +} + +int ShaderPreprocessor::Tokenizer::get_line() const { + return line; +} + +int ShaderPreprocessor::Tokenizer::get_index() const { + return index; +} + +void ShaderPreprocessor::Tokenizer::get_and_clear_generated(Vector<ShaderPreprocessor::Token> *r_out) { + for (int i = 0; i < generated.size(); i++) { + r_out->push_back(generated[i]); + } + generated.clear(); +} + +void ShaderPreprocessor::Tokenizer::backtrack(char32_t p_what) { + while (index >= 0) { + char32_t c = code[index]; + if (c == p_what) { + break; + } + index--; + } +} + +char32_t ShaderPreprocessor::Tokenizer::peek() { + if (index < size) { + return code[index]; + } + return 0; +} + +LocalVector<ShaderPreprocessor::Token> ShaderPreprocessor::Tokenizer::advance(char32_t p_what) { + LocalVector<ShaderPreprocessor::Token> tokens; + + while (index < size) { + char32_t c = code[index++]; + + tokens.push_back(ShaderPreprocessor::Token(c, line)); + + if (c == '\n') { + add_generated(ShaderPreprocessor::Token('\n', line)); + line++; + } + + if (c == p_what || c == 0) { + return tokens; + } + } + return LocalVector<ShaderPreprocessor::Token>(); +} + +void ShaderPreprocessor::Tokenizer::skip_whitespace() { + while (is_char_space(peek())) { + next(); + } +} + +String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_started) { + if (r_is_cursor != nullptr) { + *r_is_cursor = false; + } + + LocalVector<char32_t> text; + + while (true) { + char32_t c = peek(); + if (is_char_end(c) || c == '(' || c == ')' || c == ',' || c == ';') { + break; + } + + if (is_whitespace(c) && p_started) { + break; + } + if (!is_whitespace(c)) { + p_started = true; + } + + char32_t n = next(); + if (n == CURSOR) { + if (r_is_cursor != nullptr) { + *r_is_cursor = true; + } + } else { + if (p_started) { + text.push_back(n); + } + } + } + + String id = vector_to_string(text); + if (!id.is_valid_identifier()) { + return ""; + } + + return id; +} + +String ShaderPreprocessor::Tokenizer::peek_identifier() { + const int original = index; + String id = get_identifier(); + index = original; + return id; +} + +ShaderPreprocessor::Token ShaderPreprocessor::Tokenizer::get_token() { + while (index < size) { + const char32_t c = code[index++]; + const Token t = ShaderPreprocessor::Token(c, line); + + switch (c) { + case ' ': + case '\t': + skip_whitespace(); + return ShaderPreprocessor::Token(' ', line); + case '\n': + line++; + return t; + default: + return t; + } + } + return ShaderPreprocessor::Token(char32_t(0), line); +} + +ShaderPreprocessor::Tokenizer::Tokenizer(const String &p_code) { + code = p_code; + line = 0; + index = 0; + size = code.size(); +} + +// ShaderPreprocessor::CommentRemover + +String ShaderPreprocessor::CommentRemover::get_error() const { + if (comments_open != 0) { + return "Block comment mismatch"; + } + return ""; +} + +int ShaderPreprocessor::CommentRemover::get_error_line() const { + if (comments_open != 0) { + return comment_line_open; + } + return -1; +} + +char32_t ShaderPreprocessor::CommentRemover::peek() const { + if (index < code.size()) { + return code[index]; + } + return 0; +} + +bool ShaderPreprocessor::CommentRemover::advance(char32_t p_what) { + while (index < code.size()) { + char32_t c = code[index++]; + + if (c == '\n') { + line++; + stripped.push_back('\n'); + } + + if (c == p_what) { + return true; + } + } + return false; +} + +String ShaderPreprocessor::CommentRemover::strip() { + stripped.clear(); + index = 0; + line = 0; + comment_line_open = 0; + comments_open = 0; + strings_open = 0; + + while (index < code.size()) { + char32_t c = code[index++]; + + if (c == CURSOR) { + // Cursor. Maintain. + stripped.push_back(c); + } else if (c == '"') { + if (strings_open <= 0) { + strings_open++; + } else { + strings_open--; + } + stripped.push_back(c); + } else if (c == '/' && strings_open == 0) { + char32_t p = peek(); + if (p == '/') { // Single line comment. + advance('\n'); + } else if (p == '*') { // Start of a block comment. + index++; + comment_line_open = line; + comments_open++; + while (advance('*')) { + if (peek() == '/') { // End of a block comment. + comments_open--; + index++; + break; + } + } + } else { + stripped.push_back(c); + } + } else if (c == '*' && strings_open == 0) { + if (peek() == '/') { // Unmatched end of a block comment. + comment_line_open = line; + comments_open--; + } else { + stripped.push_back(c); + } + } else if (c == '\n') { + line++; + stripped.push_back(c); + } else { + stripped.push_back(c); + } + } + return vector_to_string(stripped); +} + +ShaderPreprocessor::CommentRemover::CommentRemover(const String &p_code) { + code = p_code; + index = 0; + line = 0; + comment_line_open = 0; + comments_open = 0; + strings_open = 0; +} + +// ShaderPreprocessor::Token + +ShaderPreprocessor::Token::Token() { + text = 0; + line = -1; +} + +ShaderPreprocessor::Token::Token(char32_t p_text, int p_line) { + text = p_text; + line = p_line; +} + +// ShaderPreprocessor + +bool ShaderPreprocessor::is_char_word(char32_t p_char) { + if ((p_char >= '0' && p_char <= '9') || + (p_char >= 'a' && p_char <= 'z') || + (p_char >= 'A' && p_char <= 'Z') || + p_char == '_') { + return true; + } + + return false; +} + +bool ShaderPreprocessor::is_char_space(char32_t p_char) { + return p_char == ' ' || p_char == '\t'; +} + +bool ShaderPreprocessor::is_char_end(char32_t p_char) { + return p_char == '\n' || p_char == 0; +} + +String ShaderPreprocessor::vector_to_string(const LocalVector<char32_t> &p_v, int p_start, int p_end) { + const int stop = (p_end == -1) ? p_v.size() : p_end; + const int count = stop - p_start; + + String result; + result.resize(count + 1); + for (int i = 0; i < count; i++) { + result[i] = p_v[p_start + i]; + } + result[count] = 0; // Ensure string is null terminated for length() to work. + return result; +} + +String ShaderPreprocessor::tokens_to_string(const LocalVector<Token> &p_tokens) { + LocalVector<char32_t> result; + for (uint32_t i = 0; i < p_tokens.size(); i++) { + result.push_back(p_tokens[i].text); + } + return vector_to_string(result); +} + +void ShaderPreprocessor::process_directive(Tokenizer *p_tokenizer) { + bool is_cursor; + String directive = p_tokenizer->get_identifier(&is_cursor, true); + if (is_cursor) { + state->completion_type = COMPLETION_TYPE_DIRECTIVE; + } + + if (directive == "if") { + process_if(p_tokenizer); + } else if (directive == "ifdef") { + process_ifdef(p_tokenizer); + } else if (directive == "ifndef") { + process_ifndef(p_tokenizer); + } else if (directive == "else") { + process_else(p_tokenizer); + } else if (directive == "endif") { + process_endif(p_tokenizer); + } else if (directive == "define") { + process_define(p_tokenizer); + } else if (directive == "undef") { + process_undef(p_tokenizer); + } else if (directive == "include") { + process_include(p_tokenizer); + } else if (directive == "pragma") { + process_pragma(p_tokenizer); + } else { + set_error(RTR("Unknown directive."), p_tokenizer->get_line()); + } +} + +void ShaderPreprocessor::process_define(Tokenizer *p_tokenizer) { + const int line = p_tokenizer->get_line(); + + String label = p_tokenizer->get_identifier(); + if (label.is_empty()) { + set_error(RTR("Invalid macro name."), line); + return; + } + + if (state->defines.has(label)) { + set_error(RTR("Macro redefinition."), line); + return; + } + + if (p_tokenizer->peek() == '(') { + // Macro has arguments. + p_tokenizer->get_token(); + + Vector<String> args; + while (true) { + String name = p_tokenizer->get_identifier(); + if (name.is_empty()) { + set_error(RTR("Invalid argument name."), line); + return; + } + args.push_back(name); + + p_tokenizer->skip_whitespace(); + char32_t next = p_tokenizer->get_token().text; + if (next == ')') { + break; + } else if (next != ',') { + set_error(RTR("Expected a comma in the macro argument list."), line); + return; + } + } + + Define *define = memnew(Define); + define->arguments = args; + define->body = tokens_to_string(p_tokenizer->advance('\n')).strip_edges(); + state->defines[label] = define; + } else { + // Simple substitution macro. + Define *define = memnew(Define); + define->body = tokens_to_string(p_tokenizer->advance('\n')).strip_edges(); + state->defines[label] = define; + } +} + +void ShaderPreprocessor::process_else(Tokenizer *p_tokenizer) { + if (state->skip_stack_else.is_empty()) { + set_error(RTR("Unmatched else."), p_tokenizer->get_line()); + return; + } + p_tokenizer->advance('\n'); + + bool skip = state->skip_stack_else[state->skip_stack_else.size() - 1]; + state->skip_stack_else.remove_at(state->skip_stack_else.size() - 1); + + Vector<SkippedCondition *> vec = state->skipped_conditions[state->current_include]; + int index = vec.size() - 1; + if (index >= 0) { + SkippedCondition *cond = vec[index]; + if (cond->end_line == -1) { + cond->end_line = p_tokenizer->get_line(); + } + } + + if (skip) { + Vector<String> ends; + ends.push_back("endif"); + next_directive(p_tokenizer, ends); + } +} + +void ShaderPreprocessor::process_endif(Tokenizer *p_tokenizer) { + state->condition_depth--; + if (state->condition_depth < 0) { + set_error(RTR("Unmatched endif."), p_tokenizer->get_line()); + return; + } + + Vector<SkippedCondition *> vec = state->skipped_conditions[state->current_include]; + int index = vec.size() - 1; + if (index >= 0) { + SkippedCondition *cond = vec[index]; + if (cond->end_line == -1) { + cond->end_line = p_tokenizer->get_line(); + } + } + + p_tokenizer->advance('\n'); +} + +void ShaderPreprocessor::process_if(Tokenizer *p_tokenizer) { + int line = p_tokenizer->get_line(); + + String body = tokens_to_string(p_tokenizer->advance('\n')).strip_edges(); + if (body.is_empty()) { + set_error(RTR("Missing condition."), line); + return; + } + + Error error = expand_macros(body, line, body); + if (error != OK) { + return; + } + + Expression expression; + Vector<String> names; + error = expression.parse(body, names); + if (error != OK) { + set_error(expression.get_error_text(), line); + return; + } + + Variant v = expression.execute(Array(), nullptr, false); + if (v.get_type() == Variant::NIL) { + set_error(RTR("Condition evaluation error."), line); + return; + } + + bool success = v.booleanize(); + start_branch_condition(p_tokenizer, success); +} + +void ShaderPreprocessor::process_ifdef(Tokenizer *p_tokenizer) { + const int line = p_tokenizer->get_line(); + + String label = p_tokenizer->get_identifier(); + if (label.is_empty()) { + set_error(RTR("Invalid macro name."), line); + return; + } + + p_tokenizer->skip_whitespace(); + if (!is_char_end(p_tokenizer->peek())) { + set_error(RTR("Invalid ifdef."), line); + return; + } + p_tokenizer->advance('\n'); + + bool success = state->defines.has(label); + start_branch_condition(p_tokenizer, success); +} + +void ShaderPreprocessor::process_ifndef(Tokenizer *p_tokenizer) { + const int line = p_tokenizer->get_line(); + + String label = p_tokenizer->get_identifier(); + if (label.is_empty()) { + set_error(RTR("Invalid macro name."), line); + return; + } + + p_tokenizer->skip_whitespace(); + if (!is_char_end(p_tokenizer->peek())) { + set_error(RTR("Invalid ifndef."), line); + return; + } + p_tokenizer->advance('\n'); + + bool success = !state->defines.has(label); + start_branch_condition(p_tokenizer, success); +} + +void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) { + const int line = p_tokenizer->get_line(); + + p_tokenizer->advance('"'); + String path = tokens_to_string(p_tokenizer->advance('"')); + for (int i = 0; i < path.length(); i++) { + if (path[i] == '\n') { + break; //stop parsing + } + if (path[i] == CURSOR) { + state->completion_type = COMPLETION_TYPE_INCLUDE_PATH; + break; + } + } + path = path.substr(0, path.length() - 1); + p_tokenizer->skip_whitespace(); + + if (path.is_empty() || !is_char_end(p_tokenizer->peek())) { + set_error(RTR("Invalid path."), line); + return; + } + + Ref<Resource> res = ResourceLoader::load(path); + if (res.is_null()) { + set_error(RTR("Shader include load failed. Does the shader include exist? Is there a cyclic dependency?"), line); + return; + } + + Ref<ShaderInclude> shader_inc = res; + if (shader_inc.is_null()) { + set_error(RTR("Shader include resource type is wrong."), line); + return; + } + + String included = shader_inc->get_code(); + if (!included.is_empty()) { + uint64_t code_hash = included.hash64(); + if (state->cyclic_include_hashes.find(code_hash)) { + set_error(RTR("Cyclic include found."), line); + return; + } + } + + state->shader_includes.insert(shader_inc); + + const String real_path = shader_inc->get_path(); + if (state->includes.has(real_path)) { + // Already included, skip. + // This is a valid check because 2 separate include paths could use some + // of the same shared functions from a common shader include. + return; + } + + // Mark as included. + state->includes.insert(real_path); + + state->include_depth++; + if (state->include_depth > 25) { + set_error(RTR("Shader max include depth exceeded."), line); + return; + } + + String old_include = state->current_include; + state->current_include = real_path; + ShaderPreprocessor processor; + + int prev_condition_depth = state->condition_depth; + state->condition_depth = 0; + + FilePosition fp; + fp.file = state->current_include; + fp.line = line; + state->include_positions.push_back(fp); + + String result; + processor.preprocess(state, included, result); + add_to_output("@@>" + real_path + "\n"); // Add token for enter include path + add_to_output(result); + add_to_output("\n@@<\n"); // Add token for exit include path + + // Reset to last include if there are no errors. We want to use this as context. + if (state->error.is_empty()) { + state->current_include = old_include; + state->include_positions.pop_back(); + } else { + return; + } + + state->include_depth--; + state->condition_depth = prev_condition_depth; +} + +void ShaderPreprocessor::process_pragma(Tokenizer *p_tokenizer) { + const int line = p_tokenizer->get_line(); + + bool is_cursor; + const String label = p_tokenizer->get_identifier(&is_cursor); + if (is_cursor) { + state->completion_type = COMPLETION_TYPE_PRAGMA; + } + + if (label.is_empty()) { + set_error(RTR("Invalid pragma directive."), line); + return; + } + + // Rxplicitly handle pragma values here. + // If more pragma options are created, then refactor into a more defined structure. + if (label == "disable_preprocessor") { + state->disabled = true; + } else { + set_error(RTR("Invalid pragma directive."), line); + return; + } + + p_tokenizer->advance('\n'); +} + +void ShaderPreprocessor::process_undef(Tokenizer *p_tokenizer) { + const int line = p_tokenizer->get_line(); + const String label = p_tokenizer->get_identifier(); + if (label.is_empty() || !state->defines.has(label)) { + set_error(RTR("Invalid name."), line); + return; + } + + p_tokenizer->skip_whitespace(); + if (!is_char_end(p_tokenizer->peek())) { + set_error(RTR("Invalid undef."), line); + return; + } + + memdelete(state->defines[label]); + state->defines.erase(label); +} + +void ShaderPreprocessor::start_branch_condition(Tokenizer *p_tokenizer, bool p_success) { + state->condition_depth++; + + if (p_success) { + state->skip_stack_else.push_back(true); + } else { + SkippedCondition *cond = memnew(SkippedCondition()); + cond->start_line = p_tokenizer->get_line(); + state->skipped_conditions[state->current_include].push_back(cond); + + Vector<String> ends; + ends.push_back("else"); + ends.push_back("endif"); + if (next_directive(p_tokenizer, ends) == "else") { + state->skip_stack_else.push_back(false); + } else { + state->skip_stack_else.push_back(true); + } + } +} + +void ShaderPreprocessor::expand_output_macros(int p_start, int p_line_number) { + String line = vector_to_string(output, p_start, output.size()); + + Error error = expand_macros(line, p_line_number - 1, line); // We are already on next line, so -1. + if (error != OK) { + return; + } + + output.resize(p_start); + + add_to_output(line); +} + +Error ShaderPreprocessor::expand_macros(const String &p_string, int p_line, String &r_expanded) { + Vector<Pair<String, Define *>> active_defines; + active_defines.resize(state->defines.size()); + int index = 0; + for (const RBMap<String, Define *>::Element *E = state->defines.front(); E; E = E->next()) { + active_defines.set(index++, Pair<String, Define *>(E->key(), E->get())); + } + + return expand_macros(p_string, p_line, active_defines, r_expanded); +} + +Error ShaderPreprocessor::expand_macros(const String &p_string, int p_line, Vector<Pair<String, Define *>> p_defines, String &r_expanded) { + r_expanded = p_string; + // When expanding macros we must only evaluate them once. + // Later we continue expanding but with the already + // evaluated macros removed. + for (int i = 0; i < p_defines.size(); i++) { + Pair<String, Define *> define_pair = p_defines[i]; + + Error error = expand_macros_once(r_expanded, p_line, define_pair, r_expanded); + if (error != OK) { + return error; + } + + // Remove expanded macro and recursively replace remaining. + p_defines.remove_at(i); + return expand_macros(r_expanded, p_line, p_defines, r_expanded); + } + + return OK; +} + +Error ShaderPreprocessor::expand_macros_once(const String &p_line, int p_line_number, Pair<String, Define *> p_define_pair, String &r_expanded) { + String result = p_line; + + const String &key = p_define_pair.first; + const Define *define = p_define_pair.second; + + int index_start = 0; + int index = 0; + while (find_match(result, key, index, index_start)) { + String body = define->body; + if (define->arguments.size() > 0) { + // Complex macro with arguments. + int args_start = index + key.length(); + int args_end = p_line.find(")", args_start); + if (args_start == -1 || args_end == -1) { + set_error(RTR("Missing macro argument parenthesis."), p_line_number); + return FAILED; + } + + String values = result.substr(args_start + 1, args_end - (args_start + 1)); + Vector<String> args = values.split(","); + if (args.size() != define->arguments.size()) { + set_error(RTR("Invalid macro argument count."), p_line_number); + return FAILED; + } + + // Insert macro arguments into the body. + for (int i = 0; i < args.size(); i++) { + String arg_name = define->arguments[i]; + int arg_index_start = 0; + int arg_index = 0; + while (find_match(body, arg_name, arg_index, arg_index_start)) { + body = body.substr(0, arg_index) + args[i] + body.substr(arg_index + arg_name.length(), body.length() - (arg_index + arg_name.length())); + // Manually reset arg_index_start to where the arg value of the define finishes. + // This ensures we don't skip the other args of this macro in the string. + arg_index_start = arg_index + args[i].length() + 1; + } + } + + result = result.substr(0, index) + " " + body + " " + result.substr(args_end + 1, result.length()); + } else { + result = result.substr(0, index) + body + result.substr(index + key.length(), result.length() - (index + key.length())); + // Manually reset index_start to where the body value of the define finishes. + // This ensures we don't skip another instance of this macro in the string. + index_start = index + body.length() + 1; + break; + } + } + r_expanded = result; + return OK; +} + +bool ShaderPreprocessor::find_match(const String &p_string, const String &p_value, int &r_index, int &r_index_start) { + // Looks for value in string and then determines if the boundaries + // are non-word characters. This method semi-emulates \b in regex. + r_index = p_string.find(p_value, r_index_start); + while (r_index > -1) { + if (r_index > 0) { + if (is_char_word(p_string[r_index - 1])) { + r_index_start = r_index + 1; + r_index = p_string.find(p_value, r_index_start); + continue; + } + } + + if (r_index + p_value.length() < p_string.length()) { + if (is_char_word(p_string[r_index + p_value.length()])) { + r_index_start = r_index + p_value.length() + 1; + r_index = p_string.find(p_value, r_index_start); + continue; + } + } + + // Return and shift index start automatically for next call. + r_index_start = r_index + p_value.length() + 1; + return true; + } + + return false; +} + +String ShaderPreprocessor::next_directive(Tokenizer *p_tokenizer, const Vector<String> &p_directives) { + const int line = p_tokenizer->get_line(); + int nesting = 0; + + while (true) { + p_tokenizer->advance('#'); + + String id = p_tokenizer->peek_identifier(); + if (id.is_empty()) { + break; + } + + if (nesting == 0) { + for (int i = 0; i < p_directives.size(); i++) { + if (p_directives[i] == id) { + p_tokenizer->backtrack('#'); + return id; + } + } + } + + if (id == "ifdef" || id == "ifndef" || id == "if") { + nesting++; + } else if (id == "endif") { + nesting--; + } + } + + set_error(RTR("Can't find matching branch directive."), line); + return ""; +} + +void ShaderPreprocessor::add_to_output(const String &p_str) { + for (int i = 0; i < p_str.length(); i++) { + output.push_back(p_str[i]); + } +} + +void ShaderPreprocessor::set_error(const String &p_error, int p_line) { + if (state->error.is_empty()) { + state->error = p_error; + FilePosition fp; + fp.line = p_line + 1; + state->include_positions.push_back(fp); + } +} + +ShaderPreprocessor::Define *ShaderPreprocessor::create_define(const String &p_body) { + ShaderPreprocessor::Define *define = memnew(Define); + define->body = p_body; + return define; +} + +void ShaderPreprocessor::clear() { + if (state_owner && state != nullptr) { + for (const RBMap<String, Define *>::Element *E = state->defines.front(); E; E = E->next()) { + memdelete(E->get()); + } + + for (const RBMap<String, Vector<SkippedCondition *>>::Element *E = state->skipped_conditions.front(); E; E = E->next()) { + for (SkippedCondition *condition : E->get()) { + memdelete(condition); + } + } + + memdelete(state); + } + state_owner = false; + state = nullptr; +} + +Error ShaderPreprocessor::preprocess(State *p_state, const String &p_code, String &r_result) { + clear(); + + output.clear(); + + state = p_state; + + CommentRemover remover(p_code); + String stripped = remover.strip(); + String error = remover.get_error(); + if (!error.is_empty()) { + set_error(error, remover.get_error_line()); + return FAILED; + } + + // Track code hashes to prevent cyclic include. + uint64_t code_hash = p_code.hash64(); + state->cyclic_include_hashes.push_back(code_hash); + + Tokenizer p_tokenizer(stripped); + int last_size = 0; + bool has_symbols_before_directive = false; + + while (true) { + const Token &t = p_tokenizer.get_token(); + + if (t.text == 0) { + break; + } + + if (state->disabled) { + // Preprocessor was disabled. + // Read the rest of the file into the output. + output.push_back(t.text); + continue; + } else { + // Add autogenerated tokens. + Vector<Token> generated; + p_tokenizer.get_and_clear_generated(&generated); + for (int i = 0; i < generated.size(); i++) { + output.push_back(generated[i].text); + } + } + + if (t.text == '#') { + if (has_symbols_before_directive) { + set_error(RTR("Invalid symbols placed before directive."), p_tokenizer.get_line()); + state->cyclic_include_hashes.erase(code_hash); // Remove this hash. + return FAILED; + } + process_directive(&p_tokenizer); + } else { + if (is_char_end(t.text)) { + expand_output_macros(last_size, p_tokenizer.get_line()); + last_size = output.size(); + has_symbols_before_directive = false; + } else if (!is_char_space(t.text)) { + has_symbols_before_directive = true; + } + output.push_back(t.text); + } + + if (!state->error.is_empty()) { + state->cyclic_include_hashes.erase(code_hash); // Remove this hash. + return FAILED; + } + } + state->cyclic_include_hashes.erase(code_hash); // Remove this hash. + + if (!state->disabled) { + if (state->condition_depth != 0) { + set_error(RTR("Unmatched conditional statement."), p_tokenizer.line); + return FAILED; + } + + expand_output_macros(last_size, p_tokenizer.get_line()); + } + + r_result = vector_to_string(output); + + return OK; +} + +Error ShaderPreprocessor::preprocess(const String &p_code, String &r_result, String *r_error_text, List<FilePosition> *r_error_position, HashSet<Ref<ShaderInclude>> *r_includes, List<ScriptLanguage::CodeCompletionOption> *r_completion_options, IncludeCompletionFunction p_include_completion_func) { + State pp_state; + Error err = preprocess(&pp_state, p_code, r_result); + if (err != OK) { + if (r_error_text) { + *r_error_text = pp_state.error; + } + if (r_error_position) { + *r_error_position = pp_state.include_positions; + } + } + if (r_includes) { + *r_includes = pp_state.shader_includes; + } + + if (r_completion_options) { + switch (pp_state.completion_type) { + case COMPLETION_TYPE_DIRECTIVE: { + List<String> options; + get_keyword_list(&options, true); + + for (const String &E : options) { + ScriptLanguage::CodeCompletionOption option(E, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); + r_completion_options->push_back(option); + } + + } break; + case COMPLETION_TYPE_PRAGMA: { + List<String> options; + + ShaderPreprocessor::get_pragma_list(&options); + + for (const String &E : options) { + ScriptLanguage::CodeCompletionOption option(E, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); + r_completion_options->push_back(option); + } + + } break; + case COMPLETION_TYPE_INCLUDE_PATH: { + if (p_include_completion_func && r_completion_options) { + p_include_completion_func(r_completion_options); + } + + } break; + default: { + } + } + } + return err; +} + +void ShaderPreprocessor::get_keyword_list(List<String> *r_keywords, bool p_include_shader_keywords) { + r_keywords->push_back("define"); + if (p_include_shader_keywords) { + r_keywords->push_back("else"); + } + r_keywords->push_back("endif"); + if (p_include_shader_keywords) { + r_keywords->push_back("if"); + } + r_keywords->push_back("ifdef"); + r_keywords->push_back("ifndef"); + r_keywords->push_back("include"); + r_keywords->push_back("pragma"); + r_keywords->push_back("undef"); +} + +void ShaderPreprocessor::get_pragma_list(List<String> *r_pragmas) { + r_pragmas->push_back("disable_preprocessor"); +} + +ShaderPreprocessor::ShaderPreprocessor() { +} + +ShaderPreprocessor::~ShaderPreprocessor() { + clear(); +} diff --git a/servers/rendering/shader_preprocessor.h b/servers/rendering/shader_preprocessor.h new file mode 100644 index 0000000000..a93fb680dd --- /dev/null +++ b/servers/rendering/shader_preprocessor.h @@ -0,0 +1,200 @@ +/*************************************************************************/ +/* shader_preprocessor.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 SHADER_PREPROCESSOR_H +#define SHADER_PREPROCESSOR_H + +#include "core/string/ustring.h" +#include "core/templates/list.h" +#include "core/templates/local_vector.h" +#include "core/templates/rb_map.h" +#include "core/templates/rb_set.h" +#include "core/typedefs.h" + +#include "core/io/resource_loader.h" +#include "core/os/os.h" +#include "scene/resources/shader.h" +#include "scene/resources/shader_include.h" + +class ShaderPreprocessor { +public: + enum CompletionType { + COMPLETION_TYPE_NONE, + COMPLETION_TYPE_DIRECTIVE, + COMPLETION_TYPE_PRAGMA_DIRECTIVE, + COMPLETION_TYPE_PRAGMA, + COMPLETION_TYPE_INCLUDE_PATH, + }; + + struct FilePosition { + String file; + int line = 0; + }; + +private: + struct Token { + char32_t text; + int line; + + Token(); + Token(char32_t p_text, int p_line); + }; + + // The real preprocessor that understands basic shader and preprocessor language syntax. + class Tokenizer { + public: + String code; + int line; + int index; + int size; + Vector<Token> generated; + + private: + void add_generated(const Token &p_t); + char32_t next(); + + public: + int get_line() const; + int get_index() const; + char32_t peek(); + + void get_and_clear_generated(Vector<Token> *r_out); + void backtrack(char32_t p_what); + LocalVector<Token> advance(char32_t p_what); + void skip_whitespace(); + String get_identifier(bool *r_is_cursor = nullptr, bool p_started = false); + String peek_identifier(); + Token get_token(); + + Tokenizer(const String &p_code); + }; + + class CommentRemover { + private: + LocalVector<char32_t> stripped; + String code; + int index; + int line; + int comment_line_open; + int comments_open; + int strings_open; + + public: + String get_error() const; + int get_error_line() const; + char32_t peek() const; + + bool advance(char32_t p_what); + String strip(); + + CommentRemover(const String &p_code); + }; + + struct Define { + Vector<String> arguments; + String body; + }; + + struct SkippedCondition { + int start_line = -1; + int end_line = -1; + }; + + struct State { + RBMap<String, Define *> defines; + Vector<bool> skip_stack_else; + int condition_depth = 0; + RBSet<String> includes; + List<uint64_t> cyclic_include_hashes; // Holds code hash of includes. + int include_depth = 0; + String current_include; + String current_shader_type; + String error; + List<FilePosition> include_positions; + RBMap<String, Vector<SkippedCondition *>> skipped_conditions; + bool disabled = false; + CompletionType completion_type = COMPLETION_TYPE_NONE; + HashSet<Ref<ShaderInclude>> shader_includes; + }; + +private: + LocalVector<char32_t> output; + State *state = nullptr; + bool state_owner = false; + +private: + static bool is_char_word(char32_t p_char); + static bool is_char_space(char32_t p_char); + static bool is_char_end(char32_t p_char); + static String vector_to_string(const LocalVector<char32_t> &p_v, int p_start = 0, int p_end = -1); + static String tokens_to_string(const LocalVector<Token> &p_tokens); + + void process_directive(Tokenizer *p_tokenizer); + void process_define(Tokenizer *p_tokenizer); + void process_else(Tokenizer *p_tokenizer); + void process_endif(Tokenizer *p_tokenizer); + void process_if(Tokenizer *p_tokenizer); + void process_ifdef(Tokenizer *p_tokenizer); + void process_ifndef(Tokenizer *p_tokenizer); + void process_include(Tokenizer *p_tokenizer); + void process_pragma(Tokenizer *p_tokenizer); + void process_undef(Tokenizer *p_tokenizer); + + void start_branch_condition(Tokenizer *p_tokenizer, bool p_success); + + void expand_output_macros(int p_start, int p_line); + Error expand_macros(const String &p_string, int p_line, String &r_result); + Error expand_macros(const String &p_string, int p_line, Vector<Pair<String, Define *>> p_defines, String &r_result); + Error expand_macros_once(const String &p_line, int p_line_number, Pair<String, Define *> p_define_pair, String &r_expanded); + bool find_match(const String &p_string, const String &p_value, int &r_index, int &r_index_start); + + String next_directive(Tokenizer *p_tokenizer, const Vector<String> &p_directives); + void add_to_output(const String &p_str); + void set_error(const String &p_error, int p_line); + + static Define *create_define(const String &p_body); + + void clear(); + + Error preprocess(State *p_state, const String &p_code, String &r_result); + +public: + typedef void (*IncludeCompletionFunction)(List<ScriptLanguage::CodeCompletionOption> *); + + Error preprocess(const String &p_code, String &r_result, String *r_error_text = nullptr, List<FilePosition> *r_error_position = nullptr, HashSet<Ref<ShaderInclude>> *r_includes = nullptr, List<ScriptLanguage::CodeCompletionOption> *r_completion_options = nullptr, IncludeCompletionFunction p_include_completion_func = nullptr); + + static void get_keyword_list(List<String> *r_keywords, bool p_include_shader_keywords); + static void get_pragma_list(List<String> *r_pragmas); + + ShaderPreprocessor(); + ~ShaderPreprocessor(); +}; + +#endif // SHADER_PREPROCESSOR_H diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h index 107525cd15..dfec3a7111 100644 --- a/servers/rendering/shader_types.h +++ b/servers/rendering/shader_types.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHADERTYPES_H -#define SHADERTYPES_H +#ifndef SHADER_TYPES_H +#define SHADER_TYPES_H #include "core/templates/rb_map.h" #include "servers/rendering_server.h" @@ -59,4 +59,4 @@ public: ShaderTypes(); }; -#endif // SHADERTYPES_H +#endif // SHADER_TYPES_H diff --git a/servers/rendering/shader_warnings.h b/servers/rendering/shader_warnings.h index 8edf85842f..d5c6a4b1a6 100644 --- a/servers/rendering/shader_warnings.h +++ b/servers/rendering/shader_warnings.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SHADER_WARNINGS -#define SHADER_WARNINGS +#ifndef SHADER_WARNINGS_H +#define SHADER_WARNINGS_H #ifdef DEBUG_ENABLED @@ -90,4 +90,4 @@ public: #endif // DEBUG_ENABLED -#endif // SHADER_WARNINGS +#endif // SHADER_WARNINGS_H diff --git a/servers/rendering/storage/environment_storage.cpp b/servers/rendering/storage/environment_storage.cpp new file mode 100644 index 0000000000..1d4dc55e98 --- /dev/null +++ b/servers/rendering/storage/environment_storage.cpp @@ -0,0 +1,769 @@ +/*************************************************************************/ +/* environment_storage.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 "environment_storage.h" + +uint64_t RendererEnvironmentStorage::auto_exposure_counter = 2; + +RID RendererEnvironmentStorage::environment_allocate() { + return environment_owner.allocate_rid(); +} + +void RendererEnvironmentStorage::environment_initialize(RID p_rid) { + environment_owner.initialize_rid(p_rid, Environment()); +} + +void RendererEnvironmentStorage::environment_free(RID p_rid) { + environment_owner.free(p_rid); +} + +// Background + +void RendererEnvironmentStorage::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->background = p_bg; +} + +void RendererEnvironmentStorage::environment_set_sky(RID p_env, RID p_sky) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->sky = p_sky; +} + +void RendererEnvironmentStorage::environment_set_sky_custom_fov(RID p_env, float p_scale) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->sky_custom_fov = p_scale; +} + +void RendererEnvironmentStorage::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->sky_orientation = p_orientation; +} + +void RendererEnvironmentStorage::environment_set_bg_color(RID p_env, const Color &p_color) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->bg_color = p_color; +} + +void RendererEnvironmentStorage::environment_set_bg_energy(RID p_env, float p_energy) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->bg_energy = p_energy; +} + +void RendererEnvironmentStorage::environment_set_canvas_max_layer(RID p_env, int p_max_layer) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->canvas_max_layer = p_max_layer; +} + +void RendererEnvironmentStorage::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->ambient_light = p_color; + env->ambient_source = p_ambient; + env->ambient_light_energy = p_energy; + env->ambient_sky_contribution = p_sky_contribution; + env->reflection_source = p_reflection_source; +} + +RS::EnvironmentBG RendererEnvironmentStorage::environment_get_background(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_BG_CLEAR_COLOR); + return env->background; +} + +RID RendererEnvironmentStorage::environment_get_sky(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RID()); + return env->sky; +} + +float RendererEnvironmentStorage::environment_get_sky_custom_fov(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->sky_custom_fov; +} + +Basis RendererEnvironmentStorage::environment_get_sky_orientation(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Basis()); + return env->sky_orientation; +} + +Color RendererEnvironmentStorage::environment_get_bg_color(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color()); + return env->bg_color; +} + +float RendererEnvironmentStorage::environment_get_bg_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->bg_energy; +} + +int RendererEnvironmentStorage::environment_get_canvas_max_layer(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0); + return env->canvas_max_layer; +} + +RS::EnvironmentAmbientSource RendererEnvironmentStorage::environment_get_ambient_source(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG); + return env->ambient_source; +} + +Color RendererEnvironmentStorage::environment_get_ambient_light(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color()); + return env->ambient_light; +} + +float RendererEnvironmentStorage::environment_get_ambient_light_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ambient_light_energy; +} + +float RendererEnvironmentStorage::environment_get_ambient_sky_contribution(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ambient_sky_contribution; +} + +RS::EnvironmentReflectionSource RendererEnvironmentStorage::environment_get_reflection_source(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_BG); + return env->reflection_source; +} + +// Tonemap + +void RendererEnvironmentStorage::environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->exposure = p_exposure; + env->tone_mapper = p_tone_mapper; + if (!env->auto_exposure && p_auto_exposure) { + env->auto_exposure_version = ++auto_exposure_counter; + } + env->auto_exposure = p_auto_exposure; + env->white = p_white; + env->min_luminance = p_min_luminance; + env->max_luminance = p_max_luminance; + env->auto_exp_speed = p_auto_exp_speed; + env->auto_exp_scale = p_auto_exp_scale; +} + +RS::EnvironmentToneMapper RendererEnvironmentStorage::environment_get_tone_mapper(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_TONE_MAPPER_LINEAR); + return env->tone_mapper; +} + +float RendererEnvironmentStorage::environment_get_exposure(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->exposure; +} + +float RendererEnvironmentStorage::environment_get_white(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->white; +} + +bool RendererEnvironmentStorage::environment_get_auto_exposure(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->auto_exposure; +} + +float RendererEnvironmentStorage::environment_get_min_luminance(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->min_luminance; +} + +float RendererEnvironmentStorage::environment_get_max_luminance(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 8.0); + return env->max_luminance; +} + +float RendererEnvironmentStorage::environment_get_auto_exp_speed(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->auto_exp_speed; +} + +float RendererEnvironmentStorage::environment_get_auto_exp_scale(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.5); + return env->auto_exp_scale; +} + +uint64_t RendererEnvironmentStorage::environment_get_auto_exposure_version(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0); + return env->auto_exposure_version; +} + +// Fog + +void RendererEnvironmentStorage::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->fog_enabled = p_enable; + env->fog_light_color = p_light_color; + env->fog_light_energy = p_light_energy; + env->fog_sun_scatter = p_sun_scatter; + env->fog_density = p_density; + env->fog_height = p_height; + env->fog_height_density = p_height_density; + env->fog_aerial_perspective = p_fog_aerial_perspective; +} + +bool RendererEnvironmentStorage::environment_get_fog_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->fog_enabled; +} + +Color RendererEnvironmentStorage::environment_get_fog_light_color(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color(0.5, 0.6, 0.7)); + return env->fog_light_color; +} + +float RendererEnvironmentStorage::environment_get_fog_light_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->fog_light_energy; +} + +float RendererEnvironmentStorage::environment_get_fog_sun_scatter(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_sun_scatter; +} + +float RendererEnvironmentStorage::environment_get_fog_density(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.001); + return env->fog_density; +} + +float RendererEnvironmentStorage::environment_get_fog_height(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_height; +} + +float RendererEnvironmentStorage::environment_get_fog_height_density(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_height_density; +} + +float RendererEnvironmentStorage::environment_get_fog_aerial_perspective(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->fog_aerial_perspective; +} + +// Volumetric Fog + +void RendererEnvironmentStorage::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->volumetric_fog_enabled = p_enable; + env->volumetric_fog_density = p_density; + env->volumetric_fog_scattering = p_albedo; + env->volumetric_fog_emission = p_emission; + env->volumetric_fog_emission_energy = p_emission_energy; + env->volumetric_fog_anisotropy = p_anisotropy, + env->volumetric_fog_length = p_length; + env->volumetric_fog_detail_spread = p_detail_spread; + 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; + env->volumetric_fog_ambient_inject = p_ambient_inject; +} + +bool RendererEnvironmentStorage::environment_get_volumetric_fog_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->volumetric_fog_enabled; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_density(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.01); + return env->volumetric_fog_density; +} + +Color RendererEnvironmentStorage::environment_get_volumetric_fog_scattering(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color(1, 1, 1)); + return env->volumetric_fog_scattering; +} + +Color RendererEnvironmentStorage::environment_get_volumetric_fog_emission(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Color(0, 0, 0)); + return env->volumetric_fog_emission; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_emission_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->volumetric_fog_emission_energy; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_anisotropy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->volumetric_fog_anisotropy; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_length(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 64.0); + return env->volumetric_fog_length; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_detail_spread(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 2.0); + return env->volumetric_fog_detail_spread; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_gi_inject(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->volumetric_fog_gi_inject; +} + +bool RendererEnvironmentStorage::environment_get_volumetric_fog_temporal_reprojection(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, true); + return env->volumetric_fog_temporal_reprojection; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.9); + return env->volumetric_fog_temporal_reprojection_amount; +} + +float RendererEnvironmentStorage::environment_get_volumetric_fog_ambient_inject(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->volumetric_fog_ambient_inject; +} + +// GLOW + +void RendererEnvironmentStorage::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7"); + env->glow_enabled = p_enable; + env->glow_levels = p_levels; + env->glow_intensity = p_intensity; + env->glow_strength = p_strength; + env->glow_mix = p_mix; + env->glow_bloom = p_bloom_threshold; + env->glow_blend_mode = p_blend_mode; + env->glow_hdr_bleed_threshold = p_hdr_bleed_threshold; + env->glow_hdr_bleed_scale = p_hdr_bleed_scale; + env->glow_hdr_luminance_cap = p_hdr_luminance_cap; + env->glow_map_strength = p_glow_map_strength; + env->glow_map = p_glow_map; +} + +bool RendererEnvironmentStorage::environment_get_glow_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->glow_enabled; +} + +Vector<float> RendererEnvironmentStorage::environment_get_glow_levels(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, Vector<float>()); + return env->glow_levels; +} + +float RendererEnvironmentStorage::environment_get_glow_intensity(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.8); + return env->glow_intensity; +} + +float RendererEnvironmentStorage::environment_get_glow_strength(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->glow_strength; +} + +float RendererEnvironmentStorage::environment_get_glow_bloom(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->glow_bloom; +} + +float RendererEnvironmentStorage::environment_get_glow_mix(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.01); + return env->glow_mix; +} + +RS::EnvironmentGlowBlendMode RendererEnvironmentStorage::environment_get_glow_blend_mode(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT); + return env->glow_blend_mode; +} + +float RendererEnvironmentStorage::environment_get_glow_hdr_bleed_threshold(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->glow_hdr_bleed_threshold; +} + +float RendererEnvironmentStorage::environment_get_glow_hdr_luminance_cap(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 12.0); + return env->glow_hdr_luminance_cap; +} + +float RendererEnvironmentStorage::environment_get_glow_hdr_bleed_scale(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 2.0); + return env->glow_hdr_bleed_scale; +} + +float RendererEnvironmentStorage::environment_get_glow_map_strength(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->glow_map_strength; +} + +RID RendererEnvironmentStorage::environment_get_glow_map(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RID()); + return env->glow_map; +} + +// SSR + +void RendererEnvironmentStorage::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) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->ssr_enabled = p_enable; + env->ssr_max_steps = p_max_steps; + env->ssr_fade_in = p_fade_int; + env->ssr_fade_out = p_fade_out; + env->ssr_depth_tolerance = p_depth_tolerance; +} + +bool RendererEnvironmentStorage::environment_get_ssr_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->ssr_enabled; +} + +int RendererEnvironmentStorage::environment_get_ssr_max_steps(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 64); + return env->ssr_max_steps; +} + +float RendererEnvironmentStorage::environment_get_ssr_fade_in(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.15); + return env->ssr_fade_in; +} + +float RendererEnvironmentStorage::environment_get_ssr_fade_out(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 2.0); + return env->ssr_fade_out; +} + +float RendererEnvironmentStorage::environment_get_ssr_depth_tolerance(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->ssr_depth_tolerance; +} + +// SSAO + +void RendererEnvironmentStorage::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) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->ssao_enabled = p_enable; + env->ssao_radius = p_radius; + env->ssao_intensity = p_intensity; + env->ssao_power = p_power; + env->ssao_detail = p_detail; + env->ssao_horizon = p_horizon; + env->ssao_sharpness = p_sharpness; + env->ssao_direct_light_affect = p_light_affect; + env->ssao_ao_channel_affect = p_ao_channel_affect; +} + +bool RendererEnvironmentStorage::environment_get_ssao_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->ssao_enabled; +} + +float RendererEnvironmentStorage::environment_get_ssao_radius(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ssao_radius; +} + +float RendererEnvironmentStorage::environment_get_ssao_intensity(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 2.0); + return env->ssao_intensity; +} + +float RendererEnvironmentStorage::environment_get_ssao_power(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.5); + return env->ssao_power; +} + +float RendererEnvironmentStorage::environment_get_ssao_detail(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.5); + return env->ssao_detail; +} + +float RendererEnvironmentStorage::environment_get_ssao_horizon(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.06); + return env->ssao_horizon; +} + +float RendererEnvironmentStorage::environment_get_ssao_sharpness(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.98); + return env->ssao_sharpness; +} + +float RendererEnvironmentStorage::environment_get_ssao_direct_light_affect(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->ssao_direct_light_affect; +} + +float RendererEnvironmentStorage::environment_get_ssao_ao_channel_affect(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.0); + return env->ssao_ao_channel_affect; +} + +// SSIL + +void RendererEnvironmentStorage::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->ssil_enabled = p_enable; + env->ssil_radius = p_radius; + env->ssil_intensity = p_intensity; + env->ssil_sharpness = p_sharpness; + env->ssil_normal_rejection = p_normal_rejection; +} + +bool RendererEnvironmentStorage::environment_get_ssil_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->ssil_enabled; +} + +float RendererEnvironmentStorage::environment_get_ssil_radius(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 5.0); + return env->ssil_radius; +} + +float RendererEnvironmentStorage::environment_get_ssil_intensity(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ssil_intensity; +} + +float RendererEnvironmentStorage::environment_get_ssil_sharpness(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.98); + return env->ssil_sharpness; +} + +float RendererEnvironmentStorage::environment_get_ssil_normal_rejection(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->ssil_normal_rejection; +} + +// SDFGI + +void RendererEnvironmentStorage::environment_set_sdfgi(RID p_env, bool p_enable, int 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.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->sdfgi_enabled = p_enable; + env->sdfgi_cascades = p_cascades; + env->sdfgi_min_cell_size = p_min_cell_size; + env->sdfgi_use_occlusion = p_use_occlusion; + 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; + env->sdfgi_probe_bias = p_probe_bias; + env->sdfgi_y_scale = p_y_scale; +} + +bool RendererEnvironmentStorage::environment_get_sdfgi_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->sdfgi_enabled; +} + +int RendererEnvironmentStorage::environment_get_sdfgi_cascades(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 4); + return env->sdfgi_cascades; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_min_cell_size(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.2); + return env->sdfgi_min_cell_size; +} + +bool RendererEnvironmentStorage::environment_get_sdfgi_use_occlusion(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->sdfgi_use_occlusion; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_bounce_feedback(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 0.5); + return env->sdfgi_bounce_feedback; +} + +bool RendererEnvironmentStorage::environment_get_sdfgi_read_sky_light(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, true); + return env->sdfgi_read_sky_light; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_energy(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->sdfgi_energy; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_normal_bias(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.1); + return env->sdfgi_normal_bias; +} + +float RendererEnvironmentStorage::environment_get_sdfgi_probe_bias(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.1); + return env->sdfgi_probe_bias; +} + +RS::EnvironmentSDFGIYScale RendererEnvironmentStorage::environment_get_sdfgi_y_scale(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RS::ENV_SDFGI_Y_SCALE_75_PERCENT); + return env->sdfgi_y_scale; +} + +// Adjustments + +void RendererEnvironmentStorage::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) { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND(!env); + env->adjustments_enabled = p_enable; + env->adjustments_brightness = p_brightness; + env->adjustments_contrast = p_contrast; + env->adjustments_saturation = p_saturation; + env->use_1d_color_correction = p_use_1d_color_correction; + env->color_correction = p_color_correction; +} + +bool RendererEnvironmentStorage::environment_get_adjustments_enabled(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->adjustments_enabled; +} + +float RendererEnvironmentStorage::environment_get_adjustments_brightness(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->adjustments_brightness; +} + +float RendererEnvironmentStorage::environment_get_adjustments_contrast(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->adjustments_contrast; +} + +float RendererEnvironmentStorage::environment_get_adjustments_saturation(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, 1.0); + return env->adjustments_saturation; +} + +bool RendererEnvironmentStorage::environment_get_use_1d_color_correction(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, false); + return env->use_1d_color_correction; +} + +RID RendererEnvironmentStorage::environment_get_color_correction(RID p_env) const { + Environment *env = environment_owner.get_or_null(p_env); + ERR_FAIL_COND_V(!env, RID()); + return env->color_correction; +} diff --git a/servers/rendering/storage/environment_storage.h b/servers/rendering/storage/environment_storage.h new file mode 100644 index 0000000000..bd1c17deec --- /dev/null +++ b/servers/rendering/storage/environment_storage.h @@ -0,0 +1,296 @@ +/*************************************************************************/ +/* environment_storage.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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 ENVIRONMENT_STORAGE_H +#define ENVIRONMENT_STORAGE_H + +#include "core/templates/rid_owner.h" +#include "servers/rendering_server.h" + +class RendererEnvironmentStorage { +private: + struct Environment { + // Note, we capture and store all environment parameters received from Godot here. + // Not all renderers support all effects and should just ignore the bits they don't support. + + // Background + RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR; + RID sky; + float sky_custom_fov = 0.0; + Basis sky_orientation; + Color bg_color; + float bg_energy = 1.0; + int canvas_max_layer = 0; + RS::EnvironmentAmbientSource ambient_source = RS::ENV_AMBIENT_SOURCE_BG; + Color ambient_light; + float ambient_light_energy = 1.0; + float ambient_sky_contribution = 1.0; + RS::EnvironmentReflectionSource reflection_source = RS::ENV_REFLECTION_SOURCE_BG; + + // Tonemap + RS::EnvironmentToneMapper tone_mapper; + float exposure = 1.0; + float white = 1.0; + bool auto_exposure = false; + float min_luminance = 0.2; + float max_luminance = 8.0; + float auto_exp_speed = 0.2; + float auto_exp_scale = 0.5; + uint64_t auto_exposure_version = 0; + + // Fog + bool fog_enabled = false; + Color fog_light_color = Color(0.5, 0.6, 0.7); + float fog_light_energy = 1.0; + float fog_sun_scatter = 0.0; + float fog_density = 0.001; + float fog_height = 0.0; + float fog_height_density = 0.0; //can be negative to invert effect + float fog_aerial_perspective = 0.0; + + // Volumetric Fog + bool volumetric_fog_enabled = false; + float volumetric_fog_density = 0.01; + Color volumetric_fog_scattering = Color(1, 1, 1); + Color volumetric_fog_emission = Color(0, 0, 0); + float volumetric_fog_emission_energy = 0.0; + float volumetric_fog_anisotropy = 0.2; + float volumetric_fog_length = 64.0; + float volumetric_fog_detail_spread = 2.0; + float volumetric_fog_gi_inject = 0.0; + bool volumetric_fog_temporal_reprojection = true; + float volumetric_fog_temporal_reprojection_amount = 0.9; + float volumetric_fog_ambient_inject = 0.0; + + // Glow + bool glow_enabled = false; + Vector<float> glow_levels; + float glow_intensity = 0.8; + float glow_strength = 1.0; + float glow_bloom = 0.0; + float glow_mix = 0.01; + RS::EnvironmentGlowBlendMode glow_blend_mode = RS::ENV_GLOW_BLEND_MODE_SOFTLIGHT; + float glow_hdr_bleed_threshold = 1.0; + float glow_hdr_luminance_cap = 12.0; + float glow_hdr_bleed_scale = 2.0; + float glow_map_strength = 0.0f; // 1.0f in GLES3 ?? + RID glow_map = RID(); + + // SSR + bool ssr_enabled = false; + int ssr_max_steps = 64; + float ssr_fade_in = 0.15; + float ssr_fade_out = 2.0; + float ssr_depth_tolerance = 0.2; + + // SSAO + bool ssao_enabled = false; + float ssao_radius = 1.0; + float ssao_intensity = 2.0; + float ssao_power = 1.5; + float ssao_detail = 0.5; + float ssao_horizon = 0.06; + float ssao_sharpness = 0.98; + float ssao_direct_light_affect = 0.0; + float ssao_ao_channel_affect = 0.0; + + // SSIL + bool ssil_enabled = false; + float ssil_radius = 5.0; + float ssil_intensity = 1.0; + float ssil_sharpness = 0.98; + float ssil_normal_rejection = 1.0; + + // SDFGI + bool sdfgi_enabled = false; + int sdfgi_cascades = 4; + float sdfgi_min_cell_size = 0.2; + bool sdfgi_use_occlusion = false; + float sdfgi_bounce_feedback = 0.5; + bool sdfgi_read_sky_light = true; + float sdfgi_energy = 1.0; + float sdfgi_normal_bias = 1.1; + float sdfgi_probe_bias = 1.1; + RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_75_PERCENT; + + // Adjustments + bool adjustments_enabled = false; + float adjustments_brightness = 1.0f; + float adjustments_contrast = 1.0f; + float adjustments_saturation = 1.0f; + bool use_1d_color_correction = false; + RID color_correction = RID(); + }; + + static uint64_t auto_exposure_counter; + + mutable RID_Owner<Environment, true> environment_owner; + +public: + RID environment_allocate(); + void environment_initialize(RID p_rid); + void environment_free(RID p_rid); + + bool is_environment(RID p_environment) const { + return environment_owner.owns(p_environment); + } + + // Background + void environment_set_background(RID p_env, RS::EnvironmentBG p_bg); + void environment_set_sky(RID p_env, RID p_sky); + void environment_set_sky_custom_fov(RID p_env, float p_scale); + void environment_set_sky_orientation(RID p_env, const Basis &p_orientation); + void environment_set_bg_color(RID p_env, const Color &p_color); + void environment_set_bg_energy(RID p_env, float p_energy); + void environment_set_canvas_max_layer(RID p_env, int p_max_layer); + void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG); +// FIXME: Disabled during Vulkan refactoring, should be ported. +#if 0 + void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id); +#endif + + RS::EnvironmentBG environment_get_background(RID p_env) const; + RID environment_get_sky(RID p_env) const; + float environment_get_sky_custom_fov(RID p_env) const; + Basis environment_get_sky_orientation(RID p_env) const; + Color environment_get_bg_color(RID p_env) const; + float environment_get_bg_energy(RID p_env) const; + int environment_get_canvas_max_layer(RID p_env) const; + RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const; + Color environment_get_ambient_light(RID p_env) const; + float environment_get_ambient_light_energy(RID p_env) const; + float environment_get_ambient_sky_contribution(RID p_env) const; + RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const; + + // Tonemap + void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale); + RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const; + float environment_get_exposure(RID p_env) const; + float environment_get_white(RID p_env) const; + bool environment_get_auto_exposure(RID p_env) const; + float environment_get_min_luminance(RID p_env) const; + float environment_get_max_luminance(RID p_env) const; + float environment_get_auto_exp_speed(RID p_env) const; + float environment_get_auto_exp_scale(RID p_env) const; + uint64_t environment_get_auto_exposure_version(RID p_env) const; + + // Fog + 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); + bool environment_get_fog_enabled(RID p_env) const; + Color environment_get_fog_light_color(RID p_env) const; + float environment_get_fog_light_energy(RID p_env) const; + float environment_get_fog_sun_scatter(RID p_env) const; + float environment_get_fog_density(RID p_env) const; + float environment_get_fog_height(RID p_env) const; + float environment_get_fog_height_density(RID p_env) const; + float environment_get_fog_aerial_perspective(RID p_env) const; + + // Volumetric Fog + void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_albedo, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject); + bool environment_get_volumetric_fog_enabled(RID p_env) const; + float environment_get_volumetric_fog_density(RID p_env) const; + Color environment_get_volumetric_fog_scattering(RID p_env) const; + Color environment_get_volumetric_fog_emission(RID p_env) const; + float environment_get_volumetric_fog_emission_energy(RID p_env) const; + float environment_get_volumetric_fog_anisotropy(RID p_env) const; + float environment_get_volumetric_fog_length(RID p_env) const; + float environment_get_volumetric_fog_detail_spread(RID p_env) const; + float environment_get_volumetric_fog_gi_inject(RID p_env) const; + bool environment_get_volumetric_fog_temporal_reprojection(RID p_env) const; + float environment_get_volumetric_fog_temporal_reprojection_amount(RID p_env) const; + float environment_get_volumetric_fog_ambient_inject(RID p_env) const; + + // GLOW + void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map); + bool environment_get_glow_enabled(RID p_env) const; + Vector<float> environment_get_glow_levels(RID p_env) const; + float environment_get_glow_intensity(RID p_env) const; + float environment_get_glow_strength(RID p_env) const; + float environment_get_glow_bloom(RID p_env) const; + float environment_get_glow_mix(RID p_env) const; + RS::EnvironmentGlowBlendMode environment_get_glow_blend_mode(RID p_env) const; + float environment_get_glow_hdr_bleed_threshold(RID p_env) const; + float environment_get_glow_hdr_luminance_cap(RID p_env) const; + float environment_get_glow_hdr_bleed_scale(RID p_env) const; + float environment_get_glow_map_strength(RID p_env) const; + RID environment_get_glow_map(RID p_env) const; + + // SSR + 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); + bool environment_get_ssr_enabled(RID p_env) const; + int environment_get_ssr_max_steps(RID p_env) const; + float environment_get_ssr_fade_in(RID p_env) const; + float environment_get_ssr_fade_out(RID p_env) const; + float environment_get_ssr_depth_tolerance(RID p_env) const; + + // SSAO + 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); + bool environment_get_ssao_enabled(RID p_env) const; + float environment_get_ssao_radius(RID p_env) const; + float environment_get_ssao_intensity(RID p_env) const; + float environment_get_ssao_power(RID p_env) const; + float environment_get_ssao_detail(RID p_env) const; + float environment_get_ssao_horizon(RID p_env) const; + float environment_get_ssao_sharpness(RID p_env) const; + float environment_get_ssao_direct_light_affect(RID p_env) const; + float environment_get_ssao_ao_channel_affect(RID p_env) const; + + // SSIL + void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection); + bool environment_get_ssil_enabled(RID p_env) const; + float environment_get_ssil_radius(RID p_env) const; + float environment_get_ssil_intensity(RID p_env) const; + float environment_get_ssil_sharpness(RID p_env) const; + float environment_get_ssil_normal_rejection(RID p_env) const; + + // SDFGI + void environment_set_sdfgi(RID p_env, bool p_enable, int 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); + bool environment_get_sdfgi_enabled(RID p_env) const; + int environment_get_sdfgi_cascades(RID p_env) const; + float environment_get_sdfgi_min_cell_size(RID p_env) const; + bool environment_get_sdfgi_use_occlusion(RID p_env) const; + float environment_get_sdfgi_bounce_feedback(RID p_env) const; + bool environment_get_sdfgi_read_sky_light(RID p_env) const; + float environment_get_sdfgi_energy(RID p_env) const; + float environment_get_sdfgi_normal_bias(RID p_env) const; + float environment_get_sdfgi_probe_bias(RID p_env) const; + RS::EnvironmentSDFGIYScale environment_get_sdfgi_y_scale(RID p_env) const; + + // Adjustment + 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); + bool environment_get_adjustments_enabled(RID p_env) const; + float environment_get_adjustments_brightness(RID p_env) const; + float environment_get_adjustments_contrast(RID p_env) const; + float environment_get_adjustments_saturation(RID p_env) const; + bool environment_get_use_1d_color_correction(RID p_env) const; + RID environment_get_color_correction(RID p_env) const; +}; + +#endif // ENVIRONMENT_STORAGE_H diff --git a/servers/rendering/storage/light_storage.h b/servers/rendering/storage/light_storage.h index f627e46e52..087ea1a025 100644 --- a/servers/rendering/storage/light_storage.h +++ b/servers/rendering/storage/light_storage.h @@ -135,4 +135,4 @@ public: virtual float lightmap_get_probe_capture_update_speed() const = 0; }; -#endif // !LIGHT_STORAGE_H +#endif // LIGHT_STORAGE_H diff --git a/servers/rendering/storage/material_storage.h b/servers/rendering/storage/material_storage.h index 00790106af..6347b22240 100644 --- a/servers/rendering/storage/material_storage.h +++ b/servers/rendering/storage/material_storage.h @@ -38,22 +38,22 @@ class RendererMaterialStorage { public: virtual ~RendererMaterialStorage(){}; - /* GLOBAL VARIABLE API */ - virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0; - virtual void global_variable_remove(const StringName &p_name) = 0; - virtual Vector<StringName> global_variable_get_list() const = 0; + /* GLOBAL SHADER UNIFORM API */ + virtual void global_shader_uniform_add(const StringName &p_name, RS::GlobalShaderUniformType p_type, const Variant &p_value) = 0; + virtual void global_shader_uniform_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_shader_uniform_get_list() const = 0; - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0; - virtual Variant global_variable_get(const StringName &p_name) const = 0; - virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0; + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) = 0; + virtual Variant global_shader_uniform_get(const StringName &p_name) const = 0; + virtual RS::GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const = 0; - virtual void global_variables_load_settings(bool p_load_textures = true) = 0; - virtual void global_variables_clear() = 0; + virtual void global_shader_uniforms_load_settings(bool p_load_textures = true) = 0; + virtual void global_shader_uniforms_clear() = 0; - virtual int32_t global_variables_instance_allocate(RID p_instance) = 0; - virtual void global_variables_instance_free(RID p_instance) = 0; - virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; + virtual int32_t global_shader_uniforms_instance_allocate(RID p_instance) = 0; + virtual void global_shader_uniforms_instance_free(RID p_instance) = 0; + virtual void global_shader_uniforms_instance_update(RID p_instance, int p_index, const Variant &p_value) = 0; /* SHADER API */ virtual RID shader_allocate() = 0; @@ -61,6 +61,7 @@ public: virtual void shader_free(RID p_rid) = 0; virtual void shader_set_code(RID p_shader, const String &p_code) = 0; + virtual void shader_set_path_hint(RID p_shader, const String &p_path) = 0; virtual String shader_get_code(RID p_shader) const = 0; virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; @@ -98,4 +99,4 @@ public: virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0; }; -#endif // !MATERIAL_STORAGE_H +#endif // MATERIAL_STORAGE_H diff --git a/servers/rendering/storage/mesh_storage.h b/servers/rendering/storage/mesh_storage.h index 146f6fde40..5b3738dfd7 100644 --- a/servers/rendering/storage/mesh_storage.h +++ b/servers/rendering/storage/mesh_storage.h @@ -133,4 +133,4 @@ public: virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) = 0; }; -#endif // !MESH_STORAGE_H +#endif // MESH_STORAGE_H diff --git a/servers/rendering/storage/particles_storage.h b/servers/rendering/storage/particles_storage.h index eba68210a5..ee4b8679b3 100644 --- a/servers/rendering/storage/particles_storage.h +++ b/servers/rendering/storage/particles_storage.h @@ -125,4 +125,4 @@ public: virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0; }; -#endif // !PARTICLES_STORAGE_H +#endif // PARTICLES_STORAGE_H diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h index 92238c19ee..982ab4a958 100644 --- a/servers/rendering/storage/texture_storage.h +++ b/servers/rendering/storage/texture_storage.h @@ -148,4 +148,4 @@ public: virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) = 0; }; -#endif // !TEXTURE_STORAGE_H +#endif // TEXTURE_STORAGE_H diff --git a/servers/rendering/storage/utilities.h b/servers/rendering/storage/utilities.h index 4d7c34383c..d240d58917 100644 --- a/servers/rendering/storage/utilities.h +++ b/servers/rendering/storage/utilities.h @@ -183,4 +183,4 @@ public: virtual String get_video_adapter_api_version() const = 0; }; -#endif // !RENDERER_UTILITIES_H +#endif // RENDERER_UTILITIES_H diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 5ee12d04d9..6269b05d99 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1410,7 +1410,7 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su } #endif -int RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) { +int RenderingServer::global_shader_uniform_type_get_shader_datatype(GlobalShaderUniformType p_type) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: return ShaderLanguage::TYPE_BOOL; @@ -1709,6 +1709,8 @@ void RenderingServer::_bind_methods() { /* SHADER */ ClassDB::bind_method(D_METHOD("shader_create"), &RenderingServer::shader_create); + ClassDB::bind_method(D_METHOD("shader_set_code", "shader", "code"), &RenderingServer::shader_set_code); + ClassDB::bind_method(D_METHOD("shader_set_path_hint", "shader", "path"), &RenderingServer::shader_set_path_hint); ClassDB::bind_method(D_METHOD("shader_get_code", "shader"), &RenderingServer::shader_get_code); ClassDB::bind_method(D_METHOD("shader_get_param_list", "shader"), &RenderingServer::_shader_get_param_list); ClassDB::bind_method(D_METHOD("shader_get_param_default", "shader", "param"), &RenderingServer::shader_get_param_default); @@ -2182,7 +2184,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_mode", "viewport", "scaling_3d_mode"), &RenderingServer::viewport_set_scaling_3d_mode); ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_scale", "viewport", "scale"), &RenderingServer::viewport_set_scaling_3d_scale); ClassDB::bind_method(D_METHOD("viewport_set_fsr_sharpness", "viewport", "sharpness"), &RenderingServer::viewport_set_fsr_sharpness); - ClassDB::bind_method(D_METHOD("viewport_set_fsr_mipmap_bias", "viewport", "mipmap_bias"), &RenderingServer::viewport_set_fsr_mipmap_bias); + ClassDB::bind_method(D_METHOD("viewport_set_texture_mipmap_bias", "viewport", "mipmap_bias"), &RenderingServer::viewport_set_texture_mipmap_bias); ClassDB::bind_method(D_METHOD("viewport_set_update_mode", "viewport", "update_mode"), &RenderingServer::viewport_set_update_mode); ClassDB::bind_method(D_METHOD("viewport_set_clear_mode", "viewport", "clear_mode"), &RenderingServer::viewport_set_clear_mode); ClassDB::bind_method(D_METHOD("viewport_get_texture", "viewport"), &RenderingServer::viewport_get_texture); @@ -2688,15 +2690,15 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE); BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE); - /* GLOBAL VARIABLES */ + /* GLOBAL SHADER UNIFORMS */ - ClassDB::bind_method(D_METHOD("global_variable_add", "name", "type", "default_value"), &RenderingServer::global_variable_add); - ClassDB::bind_method(D_METHOD("global_variable_remove", "name"), &RenderingServer::global_variable_remove); - ClassDB::bind_method(D_METHOD("global_variable_get_list"), &RenderingServer::global_variable_get_list); - ClassDB::bind_method(D_METHOD("global_variable_set", "name", "value"), &RenderingServer::global_variable_set); - ClassDB::bind_method(D_METHOD("global_variable_set_override", "name", "value"), &RenderingServer::global_variable_set_override); - ClassDB::bind_method(D_METHOD("global_variable_get", "name"), &RenderingServer::global_variable_get); - ClassDB::bind_method(D_METHOD("global_variable_get_type", "name"), &RenderingServer::global_variable_get_type); + ClassDB::bind_method(D_METHOD("global_shader_uniform_add", "name", "type", "default_value"), &RenderingServer::global_shader_uniform_add); + ClassDB::bind_method(D_METHOD("global_shader_uniform_remove", "name"), &RenderingServer::global_shader_uniform_remove); + ClassDB::bind_method(D_METHOD("global_shader_uniform_get_list"), &RenderingServer::global_shader_uniform_get_list); + ClassDB::bind_method(D_METHOD("global_shader_uniform_set", "name", "value"), &RenderingServer::global_shader_uniform_set); + ClassDB::bind_method(D_METHOD("global_shader_uniform_set_override", "name", "value"), &RenderingServer::global_shader_uniform_set_override); + ClassDB::bind_method(D_METHOD("global_shader_uniform_get", "name"), &RenderingServer::global_shader_uniform_get); + ClassDB::bind_method(D_METHOD("global_shader_uniform_get_type", "name"), &RenderingServer::global_shader_uniform_get_type); BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BOOL); BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_BVEC2); @@ -2829,7 +2831,6 @@ void RenderingServer::set_render_loop_enabled(bool p_enabled) { RenderingServer::RenderingServer() { //ERR_FAIL_COND(singleton); - thread_pool = memnew(RendererThreadPool); singleton = this; } @@ -2945,7 +2946,7 @@ void RenderingServer::init() { GLOBAL_DEF("rendering/scaling_3d/mode", 0); GLOBAL_DEF("rendering/scaling_3d/scale", 1.0); GLOBAL_DEF("rendering/scaling_3d/fsr_sharpness", 0.2f); - GLOBAL_DEF("rendering/scaling_3d/fsr_mipmap_bias", 0.0f); + GLOBAL_DEF("rendering/textures/default_filters/texture_mipmap_bias", 0.0f); ProjectSettings::get_singleton()->set_custom_property_info("rendering/scaling_3d/mode", PropertyInfo(Variant::INT, "rendering/scaling_3d/mode", @@ -2960,10 +2961,10 @@ void RenderingServer::init() { PropertyInfo(Variant::FLOAT, "rendering/scaling_3d/fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/scaling_3d/fsr_mipmap_bias", + ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/default_filters/texture_mipmap_bias", PropertyInfo(Variant::FLOAT, - "rendering/scaling_3d/fsr_mipmap_bias", - PROPERTY_HINT_RANGE, "-2,2,0.1")); + "rendering/textures/default_filters/texture_mipmap_bias", + PROPERTY_HINT_RANGE, "-2,2,0.001")); GLOBAL_DEF("rendering/textures/decals/filter", DECAL_FILTER_LINEAR_MIPMAPS); ProjectSettings::get_singleton()->set_custom_property_info("rendering/textures/decals/filter", PropertyInfo(Variant::INT, "rendering/textures/decals/filter", PROPERTY_HINT_ENUM, "Nearest (Fast),Nearest+Mipmaps,Linear,Linear+Mipmaps,Linear+Mipmaps Anisotropic (Slow)")); @@ -3030,6 +3031,5 @@ void RenderingServer::init() { } RenderingServer::~RenderingServer() { - memdelete(thread_pool); singleton = nullptr; } diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 8d224f2832..1f2012ac8d 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -35,11 +35,11 @@ #include "core/math/geometry_3d.h" #include "core/math/transform_2d.h" #include "core/object/class_db.h" +#include "core/object/worker_thread_pool.h" #include "core/templates/rid.h" #include "core/variant/typed_array.h" #include "core/variant/variant.h" #include "servers/display_server.h" -#include "servers/rendering/renderer_thread_pool.h" #include "servers/rendering/rendering_device.h" class RenderingServer : public Object { @@ -52,8 +52,6 @@ class RenderingServer : public Object { Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const; - RendererThreadPool *thread_pool = nullptr; - const Vector2 SMALL_VEC2 = Vector2(CMP_EPSILON, CMP_EPSILON); const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON); @@ -170,6 +168,7 @@ public: virtual RID shader_create() = 0; virtual void shader_set_code(RID p_shader, const String &p_code) = 0; + virtual void shader_set_path_hint(RID p_shader, const String &p_path) = 0; virtual String shader_get_code(RID p_shader) const = 0; virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0; virtual Variant shader_get_param_default(RID p_shader, const StringName &p_param) const = 0; @@ -798,7 +797,7 @@ public: virtual void viewport_set_scaling_3d_mode(RID p_viewport, ViewportScaling3DMode p_scaling_3d_mode) = 0; virtual void viewport_set_scaling_3d_scale(RID p_viewport, float p_scaling_3d_scale) = 0; virtual void viewport_set_fsr_sharpness(RID p_viewport, float p_fsr_sharpness) = 0; - virtual void viewport_set_fsr_mipmap_bias(RID p_viewport, float p_fsr_mipmap_bias) = 0; + virtual void viewport_set_texture_mipmap_bias(RID p_viewport, float p_texture_mipmap_bias) = 0; enum ViewportUpdateMode { VIEWPORT_UPDATE_DISABLED, @@ -1426,9 +1425,9 @@ public: virtual void canvas_set_shadow_texture_size(int p_size) = 0; - /* GLOBAL VARIABLES */ + /* GLOBAL SHADER UNIFORMS */ - enum GlobalVariableType { + enum GlobalShaderUniformType { GLOBAL_VAR_TYPE_BOOL, GLOBAL_VAR_TYPE_BVEC2, GLOBAL_VAR_TYPE_BVEC3, @@ -1460,20 +1459,20 @@ public: GLOBAL_VAR_TYPE_MAX }; - virtual void global_variable_add(const StringName &p_name, GlobalVariableType p_type, const Variant &p_value) = 0; - virtual void global_variable_remove(const StringName &p_name) = 0; - virtual Vector<StringName> global_variable_get_list() const = 0; + virtual void global_shader_uniform_add(const StringName &p_name, GlobalShaderUniformType p_type, const Variant &p_value) = 0; + virtual void global_shader_uniform_remove(const StringName &p_name) = 0; + virtual Vector<StringName> global_shader_uniform_get_list() const = 0; - virtual void global_variable_set(const StringName &p_name, const Variant &p_value) = 0; - virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_uniform_set(const StringName &p_name, const Variant &p_value) = 0; + virtual void global_shader_uniform_set_override(const StringName &p_name, const Variant &p_value) = 0; - virtual Variant global_variable_get(const StringName &p_name) const = 0; - virtual GlobalVariableType global_variable_get_type(const StringName &p_name) const = 0; + virtual Variant global_shader_uniform_get(const StringName &p_name) const = 0; + virtual GlobalShaderUniformType global_shader_uniform_get_type(const StringName &p_name) const = 0; - virtual void global_variables_load_settings(bool p_load_textures) = 0; - virtual void global_variables_clear() = 0; + virtual void global_shader_uniforms_load_settings(bool p_load_textures) = 0; + virtual void global_shader_uniforms_clear() = 0; - static int global_variable_type_get_shader_datatype(GlobalVariableType p_type); + static int global_shader_uniform_type_get_shader_datatype(GlobalShaderUniformType p_type); /* FREE */ @@ -1649,7 +1648,7 @@ VARIANT_ENUM_CAST(RenderingServer::CanvasLightMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightBlendMode); VARIANT_ENUM_CAST(RenderingServer::CanvasLightShadowFilter); VARIANT_ENUM_CAST(RenderingServer::CanvasOccluderPolygonCullMode); -VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType); +VARIANT_ENUM_CAST(RenderingServer::GlobalShaderUniformType); VARIANT_ENUM_CAST(RenderingServer::RenderingInfo); VARIANT_ENUM_CAST(RenderingServer::Features); VARIANT_ENUM_CAST(RenderingServer::CanvasTextureChannel); diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h index 2c4aab0784..318c844a2f 100644 --- a/servers/server_wrap_mt_common.h +++ b/servers/server_wrap_mt_common.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef SERVER_WRAP_MT_COMMON_H +#define SERVER_WRAP_MT_COMMON_H + #define FUNC0R(m_r, m_type) \ virtual m_r m_type() override { \ if (Thread::get_caller_id() != server_thread) { \ @@ -762,3 +765,5 @@ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ } \ } + +#endif // SERVER_WRAP_MT_COMMON_H diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index 0808b1fd7b..4b9ea40223 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -195,7 +195,7 @@ RID XRInterface::get_vrs_texture() { uint8_t *data_ptr = data.ptrw(); // Our near and far don't matter much for what we're doing here, but there are some interfaces that will remember this as the near and far and may fail as a result... - CameraMatrix cm = get_projection_for_view(i, aspect, 0.1, 1000.0); + Projection cm = get_projection_for_view(i, aspect, 0.1, 1000.0); Vector3 center = cm.xform(Vector3(0.0, 0.0, 999.0)); Vector2i view_center; diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index b4eb4694f6..f11458f1cc 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -31,7 +31,7 @@ #ifndef XR_INTERFACE_H #define XR_INTERFACE_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/os/thread_safe.h" #include "servers/xr_server.h" @@ -119,7 +119,7 @@ public: virtual uint32_t get_view_count() = 0; /* returns the view count we need (1 is monoscopic, 2 is stereoscopic but can be more) */ virtual Transform3D get_camera_transform() = 0; /* returns the position of our camera for updating our camera node. For monoscopic this is equal to the views transform, for stereoscopic this should be an average */ virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) = 0; /* get each views transform */ - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) = 0; /* get each view projection matrix */ + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) = 0; /* get each view projection matrix */ virtual RID get_vrs_texture(); /* obtain VRS texture */ // note, external color/depth/vrs texture support will be added here soon. diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp index 94953c69a9..7395cd5ad4 100644 --- a/servers/xr/xr_interface_extension.cpp +++ b/servers/xr/xr_interface_extension.cpp @@ -258,12 +258,12 @@ Transform3D XRInterfaceExtension::get_transform_for_view(uint32_t p_view, const return Transform3D(); } -CameraMatrix XRInterfaceExtension::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { - CameraMatrix cm; +Projection XRInterfaceExtension::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { + Projection cm; PackedFloat64Array arr; if (GDVIRTUAL_CALL(_get_projection_for_view, p_view, p_aspect, p_z_near, p_z_far, arr)) { - ERR_FAIL_COND_V_MSG(arr.size() != 16, CameraMatrix(), "Projection matrix must contain 16 floats"); + ERR_FAIL_COND_V_MSG(arr.size() != 16, Projection(), "Projection matrix must contain 16 floats"); real_t *m = (real_t *)cm.matrix; for (int i = 0; i < 16; i++) { m[i] = arr[i]; @@ -271,7 +271,7 @@ CameraMatrix XRInterfaceExtension::get_projection_for_view(uint32_t p_view, doub return cm; } - return CameraMatrix(); + return Projection(); } RID XRInterfaceExtension::get_vrs_texture() { diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h index 7174b412c5..65b474425e 100644 --- a/servers/xr/xr_interface_extension.h +++ b/servers/xr/xr_interface_extension.h @@ -100,7 +100,7 @@ public: virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual RID get_vrs_texture() override; GDVIRTUAL0R(Size2, _get_render_target_size); @@ -132,4 +132,4 @@ public: // RID get_render_target_depth(RID p_render_target); }; -#endif // !XR_INTERFACE_EXTENSION_H +#endif // XR_INTERFACE_EXTENSION_H diff --git a/servers/xr/xr_pose.h b/servers/xr/xr_pose.h index f306c22390..e7d363764b 100644 --- a/servers/xr/xr_pose.h +++ b/servers/xr/xr_pose.h @@ -78,4 +78,4 @@ public: VARIANT_ENUM_CAST(XRPose::TrackingConfidence); -#endif +#endif // XR_POSE_H diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index ad61aa94bc..990281d96d 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -33,6 +33,16 @@ #include "xr/xr_interface.h" #include "xr/xr_positional_tracker.h" +XRServer::XRMode XRServer::xr_mode = XRMODE_DEFAULT; + +XRServer::XRMode XRServer::get_xr_mode() { + return xr_mode; +} + +void XRServer::set_xr_mode(XRServer::XRMode p_mode) { + xr_mode = p_mode; +} + XRServer *XRServer::singleton = nullptr; XRServer *XRServer::get_singleton() { diff --git a/servers/xr_server.h b/servers/xr_server.h index d9188d2de1..74128bfb54 100644 --- a/servers/xr_server.h +++ b/servers/xr_server.h @@ -57,6 +57,12 @@ class XRServer : public Object { _THREAD_SAFE_CLASS_ public: + enum XRMode { + XRMODE_DEFAULT, /* Default behaviour, means we check project settings */ + XRMODE_OFF, /* Ignore project settings, disable OpenXR, disable shaders */ + XRMODE_ON, /* Ignore project settings, enable OpenXR, enable shaders, run editor in VR (if applicable) */ + }; + enum TrackerType { TRACKER_HEAD = 0x01, /* tracks the position of the players head (or in case of handheld AR, location of the phone) */ TRACKER_CONTROLLER = 0x02, /* tracks a controller */ @@ -75,6 +81,8 @@ public: }; private: + static XRMode xr_mode; + Vector<Ref<XRInterface>> interfaces; Dictionary trackers; @@ -90,6 +98,9 @@ protected: static void _bind_methods(); public: + static XRMode get_xr_mode(); + static void set_xr_mode(XRMode p_mode); + static XRServer *get_singleton(); /* diff --git a/tests/core/io/test_image.h b/tests/core/io/test_image.h index e6e23912d3..36e6b83bfd 100644 --- a/tests/core/io/test_image.h +++ b/tests/core/io/test_image.h @@ -300,4 +300,5 @@ TEST_CASE("[Image] Modifying pixels of an image") { "flip_y() should not leave old pixels behind."); } } // namespace TestImage + #endif // TEST_IMAGE_H diff --git a/tests/core/io/test_resource.h b/tests/core/io/test_resource.h index 84d651b63f..f94349fdd2 100644 --- a/tests/core/io/test_resource.h +++ b/tests/core/io/test_resource.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TEST_RESOURCE -#define TEST_RESOURCE +#ifndef TEST_RESOURCE_H +#define TEST_RESOURCE_H #include "core/io/resource.h" #include "core/io/resource_loader.h" @@ -111,4 +111,4 @@ TEST_CASE("[Resource] Saving and loading") { } } // namespace TestResource -#endif // TEST_RESOURCE +#endif // TEST_RESOURCE_H diff --git a/tests/core/math/test_basis.h b/tests/core/math/test_basis.h index ec58d95eed..ae8ca4acde 100644 --- a/tests/core/math/test_basis.h +++ b/tests/core/math/test_basis.h @@ -283,4 +283,4 @@ TEST_CASE("[Stress][Basis] Euler conversions") { } } // namespace TestBasis -#endif +#endif // TEST_BASIS_H diff --git a/tests/core/object/test_object.h b/tests/core/object/test_object.h index 5b9d9cab53..88a3e4ccad 100644 --- a/tests/core/object/test_object.h +++ b/tests/core/object/test_object.h @@ -95,8 +95,8 @@ public: Ref<Script> get_script() const override { return Ref<Script>(); } - const Vector<Multiplayer::RPCConfig> get_rpc_methods() const override { - return Vector<Multiplayer::RPCConfig>(); + const Variant get_rpc_config() const override { + return Variant(); } ScriptLanguage *get_language() override { return nullptr; diff --git a/tests/core/templates/test_hash_set.h b/tests/core/templates/test_hash_set.h index 93fc0b26a3..3b9a800641 100644 --- a/tests/core/templates/test_hash_set.h +++ b/tests/core/templates/test_hash_set.h @@ -225,4 +225,4 @@ TEST_CASE("[HashSet] Copy") { } // namespace TestHashSet -#endif // TEST_HASH_MAP_H +#endif // TEST_HASH_SET_H diff --git a/tests/core/threads/test_worker_thread_pool.h b/tests/core/threads/test_worker_thread_pool.h new file mode 100644 index 0000000000..641b293c8a --- /dev/null +++ b/tests/core/threads/test_worker_thread_pool.h @@ -0,0 +1,158 @@ +/*************************************************************************/ +/* test_worker_thread_pool.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 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_WORKER_THREAD_POOL_H +#define TEST_WORKER_THREAD_POOL_H + +#include "core/object/worker_thread_pool.h" + +#include "tests/test_macros.h" + +namespace TestWorkerThreadPool { + +int u32scmp(const char32_t *l, const char32_t *r) { + for (; *l == *r && *l && *r; l++, r++) { + // Continue. + } + return *l - *r; +} + +static void static_test(void *p_arg) { + SafeNumeric<uint32_t> *counter = (SafeNumeric<uint32_t> *)p_arg; + counter->increment(); +} + +static SafeNumeric<uint32_t> callable_counter; + +static void static_callable_test() { + callable_counter.increment(); +} + +TEST_CASE("[WorkerThreadPool] Process 256 threads using native task") { + const int count = 256; + SafeNumeric<uint32_t> counter; + WorkerThreadPool::TaskID tasks[count]; + for (int i = 0; i < count; i++) { + tasks[i] = WorkerThreadPool::get_singleton()->add_native_task(static_test, &counter, true); + } + for (int i = 0; i < count; i++) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]); + } + + CHECK(counter.get() == count); +} + +TEST_CASE("[WorkerThreadPool] Process 256 threads using native low priority") { + const int count = 256; + SafeNumeric<uint32_t> counter = SafeNumeric<uint32_t>(0); + WorkerThreadPool::TaskID tasks[count]; + for (int i = 0; i < count; i++) { + tasks[i] = WorkerThreadPool::get_singleton()->add_native_task(static_test, &counter, false); + } + for (int i = 0; i < count; i++) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]); + } + + CHECK(counter.get() == count); +} + +TEST_CASE("[WorkerThreadPool] Process 256 threads using callable") { + const int count = 256; + WorkerThreadPool::TaskID tasks[count]; + callable_counter.set(0); + for (int i = 0; i < count; i++) { + tasks[i] = WorkerThreadPool::get_singleton()->add_task(callable_mp_static(static_callable_test), true); + } + for (int i = 0; i < count; i++) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]); + } + + CHECK(callable_counter.get() == count); +} + +TEST_CASE("[WorkerThreadPool] Process 256 threads using callable low priority") { + const int count = 256; + WorkerThreadPool::TaskID tasks[count]; + callable_counter.set(0); + for (int i = 0; i < count; i++) { + tasks[i] = WorkerThreadPool::get_singleton()->add_task(callable_mp_static(static_callable_test), false); + } + for (int i = 0; i < count; i++) { + WorkerThreadPool::get_singleton()->wait_for_task_completion(tasks[i]); + } + + CHECK(callable_counter.get() == count); +} + +static void static_group_test(void *p_arg, uint32_t p_index) { + SafeNumeric<uint32_t> *counter = (SafeNumeric<uint32_t> *)p_arg; + counter->exchange_if_greater(p_index); +} + +TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group") { + const int count = 256; + SafeNumeric<uint32_t> counter; + WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_native_group_task(static_group_test, &counter, count, -1, true); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group); + CHECK(counter.get() == count - 1); +} + +TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group low priority") { + const int count = 256; + SafeNumeric<uint32_t> counter; + WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_native_group_task(static_group_test, &counter, count, -1, false); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group); + CHECK(counter.get() == count - 1); +} + +static SafeNumeric<uint32_t> callable_group_counter; + +static void static_callable_group_test(uint32_t p_index) { + callable_group_counter.exchange_if_greater(p_index); +} + +TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group") { + const int count = 256; + WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_group_task(callable_mp_static(static_callable_group_test), count, -1, true); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group); + CHECK(callable_group_counter.get() == count - 1); +} + +TEST_CASE("[WorkerThreadPool] Process 256 elements on native task group low priority") { + const int count = 256; + callable_group_counter.set(0); + WorkerThreadPool::GroupID group = WorkerThreadPool::get_singleton()->add_group_task(callable_mp_static(static_callable_group_test), count, -1, false); + WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group); + CHECK(callable_group_counter.get() == count - 1); +} + +} // namespace TestWorkerThreadPool + +#endif // TEST_WORKER_THREAD_POOL_H diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index d28380d056..7605f24cf8 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -3251,7 +3251,7 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") { SIGNAL_WATCH(code_edit, "symbol_validate"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(code_edit, Key::META); #else SEND_GUI_KEY_EVENT(code_edit, Key::CTRL); diff --git a/tests/scene/test_path_3d.h b/tests/scene/test_path_3d.h index 78f4e97f03..8ac3d7b5b4 100644 --- a/tests/scene/test_path_3d.h +++ b/tests/scene/test_path_3d.h @@ -81,4 +81,4 @@ TEST_CASE("[Path3D] Curve setter and getter") { } // namespace TestPath3D -#endif // TEST_PATH_3D +#endif // TEST_PATH_3D_H diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h index 5d969b1fbc..0fce359c5a 100644 --- a/tests/scene/test_text_edit.h +++ b/tests/scene/test_text_edit.h @@ -724,7 +724,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { CHECK(text_edit->has_selection()); CHECK(text_edit->get_selected_text() == "t"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::SHIFT | KeyModifierMask::ALT) #else SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::SHIFT | KeyModifierMask::CMD) @@ -736,7 +736,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { CHECK(text_edit->has_selection()); CHECK(text_edit->get_selected_text() == "tes"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::SHIFT | KeyModifierMask::ALT) #else SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::SHIFT | KeyModifierMask::CMD) @@ -1902,7 +1902,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::ALT | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::CMD | KeyModifierMask::SHIFT); @@ -2013,7 +2013,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::ALT | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::CMD | KeyModifierMask::SHIFT); @@ -2244,7 +2244,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::UP | KeyModifierMask::CMD | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::HOME | KeyModifierMask::CMD | KeyModifierMask::SHIFT); @@ -2285,7 +2285,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::DOWN | KeyModifierMask::CMD | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::END | KeyModifierMask::CMD | KeyModifierMask::SHIFT); @@ -2326,7 +2326,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::LEFT | KeyModifierMask::CMD | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::HOME | KeyModifierMask::SHIFT); @@ -2383,7 +2383,7 @@ TEST_CASE("[SceneTree][TextEdit] text entry") { SIGNAL_DISCARD("lines_edited_from"); SIGNAL_DISCARD("caret_changed"); -#ifdef OSX_ENABLED +#ifdef MACOS_ENABLED SEND_GUI_KEY_EVENT(text_edit, Key::RIGHT | KeyModifierMask::CMD | KeyModifierMask::SHIFT); #else SEND_GUI_KEY_EVENT(text_edit, Key::END | KeyModifierMask::SHIFT); diff --git a/tests/servers/test_text_server.h b/tests/servers/test_text_server.h index 066c280fd5..61207216fc 100644 --- a/tests/servers/test_text_server.h +++ b/tests/servers/test_text_server.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef TOOLS_ENABLED - #ifndef TEST_TEXT_SERVER_H #define TEST_TEXT_SERVER_H +#ifdef TOOLS_ENABLED + #include "editor/builtin_fonts.gen.h" #include "servers/text_server.h" #include "tests/test_macros.h" @@ -561,5 +561,6 @@ TEST_SUITE("[[TextServer]") { } }; // namespace TestTextServer -#endif // TEST_TEXT_SERVER_H #endif // TOOLS_ENABLED + +#endif // TEST_TEXT_SERVER_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 79cda7e512..13cbc7f8aa 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -70,6 +70,7 @@ #include "tests/core/test_crypto.h" #include "tests/core/test_hashing_context.h" #include "tests/core/test_time.h" +#include "tests/core/threads/test_worker_thread_pool.h" #include "tests/core/variant/test_array.h" #include "tests/core/variant/test_dictionary.h" #include "tests/core/variant/test_variant.h" @@ -256,7 +257,7 @@ struct GodotTestCaseListener : public doctest::IReporter { if (RenderingServer::get_singleton()) { RenderingServer::get_singleton()->sync(); - RenderingServer::get_singleton()->global_variables_clear(); + RenderingServer::get_singleton()->global_shader_uniforms_clear(); RenderingServer::get_singleton()->finish(); memdelete(RenderingServer::get_singleton()); } diff --git a/thirdparty/README.md b/thirdparty/README.md index 818f2f5892..b06d9cec81 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -213,7 +213,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 4.4.1 (096aaa62a6e0d07c02a4894fc036efc927e5aaf9, 2022) +- Version: 5.0.1 (cbccadba8d1e51d6cc03a891b7c3a17f598e774c, 2022) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh new file mode 100644 index 0000000000..e52a617c86 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh @@ -0,0 +1,338 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_COVERAGE_HH +#define OT_LAYOUT_COMMON_COVERAGE_HH + +#include "../types.hh" +#include "CoverageFormat1.hh" +#include "CoverageFormat2.hh" + +namespace OT { +namespace Layout { +namespace Common { + +template<typename Iterator> +static inline void Coverage_serialize (hb_serialize_context_t *c, + Iterator it); + +struct Coverage +{ + + protected: + union { + HBUINT16 format; /* Format identifier */ + CoverageFormat1_3<SmallTypes> format1; + CoverageFormat2_4<SmallTypes> format2; +#ifndef HB_NO_BORING_EXPANSION + CoverageFormat1_3<MediumTypes>format3; + CoverageFormat2_4<MediumTypes>format4; +#endif + } u; + public: + DEFINE_SIZE_UNION (2, format); + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) + { + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (u.format3.sanitize (c)); + case 4: return_trace (u.format4.sanitize (c)); +#endif + default:return_trace (true); + } + } + + /* Has interface. */ + static constexpr unsigned SENTINEL = NOT_COVERED; + typedef unsigned int value_t; + value_t operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + /* Predicate. */ + bool operator () (hb_codepoint_t k) const { return has (k); } + + unsigned int get (hb_codepoint_t k) const { return get_coverage (k); } + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { + switch (u.format) { + case 1: return u.format1.get_coverage (glyph_id); + case 2: return u.format2.get_coverage (glyph_id); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.get_coverage (glyph_id); + case 4: return u.format4.get_coverage (glyph_id); +#endif + default:return NOT_COVERED; + } + } + + unsigned get_population () const + { + switch (u.format) { + case 1: return u.format1.get_population (); + case 2: return u.format2.get_population (); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.get_population (); + case 4: return u.format4.get_population (); +#endif + default:return NOT_COVERED; + } + } + + template <typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (this))) return_trace (false); + + unsigned count = 0; + unsigned num_ranges = 0; + hb_codepoint_t last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + num_ranges++; + last = g; + count++; + } + u.format = count <= num_ranges * 3 ? 1 : 2; + +#ifndef HB_NO_BORING_EXPANSION + if (count && last > 0xFFFFu) + u.format += 2; +#endif + + switch (u.format) + { + case 1: return_trace (u.format1.serialize (c, glyphs)); + case 2: return_trace (u.format2.serialize (c, glyphs)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (u.format3.serialize (c, glyphs)); + case 4: return_trace (u.format4.serialize (c, glyphs)); +#endif + default:return_trace (false); + } + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto it = + + iter () + | hb_filter (c->plan->glyph_map_gsub) + | hb_map_retains_sorting (c->plan->glyph_map_gsub) + ; + + // Cache the iterator result as it will be iterated multiple times + // by the serialize code below. + hb_sorted_vector_t<hb_codepoint_t> glyphs (it); + Coverage_serialize (c->serializer, glyphs.iter ()); + return_trace (bool (glyphs)); + } + + bool intersects (const hb_set_t *glyphs) const + { + switch (u.format) + { + case 1: return u.format1.intersects (glyphs); + case 2: return u.format2.intersects (glyphs); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.intersects (glyphs); + case 4: return u.format4.intersects (glyphs); +#endif + default:return false; + } + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { + switch (u.format) + { + case 1: return u.format1.intersects_coverage (glyphs, index); + case 2: return u.format2.intersects_coverage (glyphs, index); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.intersects_coverage (glyphs, index); + case 4: return u.format4.intersects_coverage (glyphs, index); +#endif + default:return false; + } + } + + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template <typename set_t> + bool collect_coverage (set_t *glyphs) const + { + switch (u.format) + { + case 1: return u.format1.collect_coverage (glyphs); + case 2: return u.format2.collect_coverage (glyphs); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.collect_coverage (glyphs); + case 4: return u.format4.collect_coverage (glyphs); +#endif + default:return false; + } + } + + template <typename IterableOut, + hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> + void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const + { + switch (u.format) + { + case 1: return u.format1.intersect_set (glyphs, intersect_glyphs); + case 2: return u.format2.intersect_set (glyphs, intersect_glyphs); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.intersect_set (glyphs, intersect_glyphs); + case 4: return u.format4.intersect_set (glyphs, intersect_glyphs); +#endif + default:return ; + } + } + + struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> + { + static constexpr bool is_sorted_iterator = true; + iter_t (const Coverage &c_ = Null (Coverage)) + { + memset (this, 0, sizeof (*this)); + format = c_.u.format; + switch (format) + { + case 1: u.format1.init (c_.u.format1); return; + case 2: u.format2.init (c_.u.format2); return; +#ifndef HB_NO_BORING_EXPANSION + case 3: u.format3.init (c_.u.format3); return; + case 4: u.format4.init (c_.u.format4); return; +#endif + default: return; + } + } + bool __more__ () const + { + switch (format) + { + case 1: return u.format1.__more__ (); + case 2: return u.format2.__more__ (); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.__more__ (); + case 4: return u.format4.__more__ (); +#endif + default:return false; + } + } + void __next__ () + { + switch (format) + { + case 1: u.format1.__next__ (); break; + case 2: u.format2.__next__ (); break; +#ifndef HB_NO_BORING_EXPANSION + case 3: u.format3.__next__ (); break; + case 4: u.format4.__next__ (); break; +#endif + default: break; + } + } + typedef hb_codepoint_t __item_t__; + __item_t__ __item__ () const { return get_glyph (); } + + hb_codepoint_t get_glyph () const + { + switch (format) + { + case 1: return u.format1.get_glyph (); + case 2: return u.format2.get_glyph (); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.get_glyph (); + case 4: return u.format4.get_glyph (); +#endif + default:return 0; + } + } + bool operator != (const iter_t& o) const + { + if (unlikely (format != o.format)) return true; + switch (format) + { + case 1: return u.format1 != o.u.format1; + case 2: return u.format2 != o.u.format2; +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3 != o.u.format3; + case 4: return u.format4 != o.u.format4; +#endif + default:return false; + } + } + iter_t __end__ () const + { + iter_t it = {}; + it.format = format; + switch (format) + { + case 1: it.u.format1 = u.format1.__end__ (); break; + case 2: it.u.format2 = u.format2.__end__ (); break; +#ifndef HB_NO_BORING_EXPANSION + case 3: it.u.format3 = u.format3.__end__ (); break; + case 4: it.u.format4 = u.format4.__end__ (); break; +#endif + default: break; + } + return it; + } + + private: + unsigned int format; + union { +#ifndef HB_NO_BORING_EXPANSION + CoverageFormat2_4<MediumTypes>::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */ + CoverageFormat1_3<MediumTypes>::iter_t format3; +#endif + CoverageFormat2_4<SmallTypes>::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */ + CoverageFormat1_3<SmallTypes>::iter_t format1; + } u; + }; + iter_t iter () const { return iter_t (*this); } +}; + +template<typename Iterator> +static inline void +Coverage_serialize (hb_serialize_context_t *c, + Iterator it) +{ c->start_embed<Coverage> ()->serialize (c, it); } + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGE_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh new file mode 100644 index 0000000000..886babd2d1 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh @@ -0,0 +1,126 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + + +#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH +#define OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH + +namespace OT { +namespace Layout { +namespace Common { + +#define NOT_COVERED ((unsigned int) -1) + +template <typename Types> +struct CoverageFormat1_3 +{ + friend struct Coverage; + + protected: + HBUINT16 coverageFormat; /* Format identifier--format = 1 */ + SortedArray16Of<typename Types::HBGlyphID> + glyphArray; /* Array of GlyphIDs--in numerical order */ + public: + DEFINE_SIZE_ARRAY (4, glyphArray); + + private: + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (glyphArray.sanitize (c)); + } + + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { + unsigned int i; + glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED); + return i; + } + + unsigned get_population () const + { + return glyphArray.len; + } + + template <typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + return_trace (glyphArray.serialize (c, glyphs)); + } + + bool intersects (const hb_set_t *glyphs) const + { + /* TODO Speed up, using hb_set_next() and bsearch()? */ + for (const auto& g : glyphArray.as_array ()) + if (glyphs->has (g)) + return true; + return false; + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { return glyphs->has (glyphArray[index]); } + + template <typename IterableOut, + hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> + void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const + { + unsigned count = glyphArray.len; + for (unsigned i = 0; i < count; i++) + if (glyphs.has (glyphArray[i])) + intersect_glyphs << glyphArray[i]; + } + + template <typename set_t> + bool collect_coverage (set_t *glyphs) const + { return glyphs->add_sorted_array (glyphArray.as_array ()); } + + public: + /* Older compilers need this to be public. */ + struct iter_t + { + void init (const struct CoverageFormat1_3 &c_) { c = &c_; i = 0; } + bool __more__ () const { return i < c->glyphArray.len; } + void __next__ () { i++; } + hb_codepoint_t get_glyph () const { return c->glyphArray[i]; } + bool operator != (const iter_t& o) const + { return i != o.i; } + iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; } + + private: + const struct CoverageFormat1_3 *c; + unsigned int i; + }; + private: +}; + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh new file mode 100644 index 0000000000..4ddb2a73e4 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh @@ -0,0 +1,233 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH +#define OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH + +#include "RangeRecord.hh" + +namespace OT { +namespace Layout { +namespace Common { + +template <typename Types> +struct CoverageFormat2_4 +{ + friend struct Coverage; + + protected: + HBUINT16 coverageFormat; /* Format identifier--format = 2 */ + SortedArray16Of<RangeRecord<Types>> + rangeRecord; /* Array of glyph ranges--ordered by + * Start GlyphID. rangeCount entries + * long */ + public: + DEFINE_SIZE_ARRAY (4, rangeRecord); + + private: + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (rangeRecord.sanitize (c)); + } + + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { + const RangeRecord<Types> &range = rangeRecord.bsearch (glyph_id); + return likely (range.first <= range.last) + ? (unsigned int) range.value + (glyph_id - range.first) + : NOT_COVERED; + } + + unsigned get_population () const + { + typename Types::large_int ret = 0; + for (const auto &r : rangeRecord) + ret += r.get_population (); + return ret > UINT_MAX ? UINT_MAX : (unsigned) ret; + } + + template <typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (this))) return_trace (false); + + /* TODO(iter) Write more efficiently? */ + + unsigned num_ranges = 0; + hb_codepoint_t last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + num_ranges++; + last = g; + } + + if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false); + if (!num_ranges) return_trace (true); + + unsigned count = 0; + unsigned range = (unsigned) -1; + last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + { + range++; + rangeRecord[range].first = g; + rangeRecord[range].value = count; + } + rangeRecord[range].last = g; + last = g; + count++; + } + + return_trace (true); + } + + bool intersects (const hb_set_t *glyphs) const + { + return hb_any (+ hb_iter (rangeRecord) + | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); })); + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { + auto cmp = [] (const void *pk, const void *pr) -> int + { + unsigned index = * (const unsigned *) pk; + const RangeRecord<Types> &range = * (const RangeRecord<Types> *) pr; + if (index < range.value) return -1; + if (index > (unsigned int) range.value + (range.last - range.first)) return +1; + return 0; + }; + + auto arr = rangeRecord.as_array (); + unsigned idx; + if (hb_bsearch_impl (&idx, index, + arr.arrayZ, arr.length, sizeof (arr[0]), + (int (*)(const void *_key, const void *_item)) cmp)) + return arr.arrayZ[idx].intersects (*glyphs); + return false; + } + + template <typename IterableOut, + hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> + void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const + { + for (const auto& range : rangeRecord) + { + hb_codepoint_t last = range.last; + for (hb_codepoint_t g = range.first - 1; + glyphs.next (&g) && g <= last;) + intersect_glyphs << g; + } + } + + template <typename set_t> + bool collect_coverage (set_t *glyphs) const + { + for (const auto& range: rangeRecord) + if (unlikely (!range.collect_coverage (glyphs))) + return false; + return true; + } + + public: + /* Older compilers need this to be public. */ + struct iter_t + { + void init (const CoverageFormat2_4 &c_) + { + c = &c_; + coverage = 0; + i = 0; + j = c->rangeRecord.len ? c->rangeRecord[0].first : 0; + if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last)) + { + /* Broken table. Skip. */ + i = c->rangeRecord.len; + j = 0; + } + } + bool __more__ () const { return i < c->rangeRecord.len; } + void __next__ () + { + if (j >= c->rangeRecord[i].last) + { + i++; + if (__more__ ()) + { + unsigned int old = coverage; + j = c->rangeRecord[i].first; + coverage = c->rangeRecord[i].value; + if (unlikely (coverage != old + 1)) + { + /* Broken table. Skip. Important to avoid DoS. + * Also, our callers depend on coverage being + * consecutive and monotonically increasing, + * ie. iota(). */ + i = c->rangeRecord.len; + j = 0; + return; + } + } + else + j = 0; + return; + } + coverage++; + j++; + } + hb_codepoint_t get_glyph () const { return j; } + bool operator != (const iter_t& o) const + { return i != o.i || j != o.j; } + iter_t __end__ () const + { + iter_t it; + it.init (*c); + it.i = c->rangeRecord.len; + it.j = 0; + return it; + } + + private: + const struct CoverageFormat2_4 *c; + unsigned int i, coverage; + hb_codepoint_t j; + }; + private: +}; + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh new file mode 100644 index 0000000000..a62629fad3 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh @@ -0,0 +1,85 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_RANGERECORD_HH +#define OT_LAYOUT_COMMON_RANGERECORD_HH + +namespace OT { +namespace Layout { +namespace Common { + +template <typename Types> +struct RangeRecord +{ + typename Types::HBGlyphID first; /* First GlyphID in the range */ + typename Types::HBGlyphID last; /* Last GlyphID in the range */ + HBUINT16 value; /* Value */ + + DEFINE_SIZE_STATIC (2 + 2 * Types::size); + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + int cmp (hb_codepoint_t g) const + { return g < first ? -1 : g <= last ? 0 : +1; } + + unsigned get_population () const + { + if (unlikely (last < first)) return 0; + return (last - first + 1); + } + + bool intersects (const hb_set_t &glyphs) const + { return glyphs.intersects (first, last); } + + template <typename set_t> + bool collect_coverage (set_t *glyphs) const + { return glyphs->add_range (first, last); } +}; + +} +} +} + +// TODO(garretrieger): This was previously implemented using +// DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (OT, RangeRecord, 9); +// but that only works when there is only a single namespace level. +// The macro should probably be fixed so it can work in this situation. +extern HB_INTERNAL const unsigned char _hb_Null_OT_RangeRecord[9]; +template <typename Spec> +struct Null<OT::Layout::Common::RangeRecord<Spec>> { + static OT::Layout::Common::RangeRecord<Spec> const & get_null () { + return *reinterpret_cast<const OT::Layout::Common::RangeRecord<Spec> *> (_hb_Null_OT_RangeRecord); + } +}; + + +#endif // #ifndef OT_LAYOUT_COMMON_RANGERECORD_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh index e212fab976..7c34bb3c93 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -140,7 +140,7 @@ struct CursivePosFormat1 unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; - buffer->unsafe_to_break (i, j); + buffer->unsafe_to_break (i, j + 1); float entry_x, entry_y, exit_x, exit_y; (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y); @@ -223,7 +223,13 @@ struct CursivePosFormat1 * https://github.com/harfbuzz/harfbuzz/issues/2469 */ if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain())) + { pos[parent].attach_chain() = 0; + if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) + pos[parent].y_offset = 0; + else + pos[parent].x_offset = 0; + } buffer->idx++; return_trace (true); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh index 224d6b746b..72829377a6 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh @@ -1,12 +1,15 @@ -#ifndef OT_LAYOUT_GPOS_HH -#define OT_LAYOUT_GPOS_HH +#ifndef OT_LAYOUT_GPOS_GPOS_HH +#define OT_LAYOUT_GPOS_GPOS_HH -#include "../../hb-ot-layout-common.hh" -#include "../../hb-ot-layout-gsubgpos.hh" -#include "GPOS/Common.hh" -#include "GPOS/PosLookup.hh" +#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-layout-gsubgpos.hh" +#include "Common.hh" +#include "PosLookup.hh" namespace OT { + +using Layout::GPOS_impl::PosLookup; + namespace Layout { static void @@ -25,10 +28,10 @@ struct GPOS : GSUBGPOS { static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS; - using Lookup = GPOS_impl::PosLookup; + using Lookup = PosLookup; - const GPOS_impl::PosLookup& get_lookup (unsigned int i) const - { return static_cast<const GPOS_impl::PosLookup &> (GSUBGPOS::get_lookup (i)); } + const PosLookup& get_lookup (unsigned int i) const + { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); } static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); @@ -37,11 +40,14 @@ struct GPOS : GSUBGPOS bool subset (hb_subset_context_t *c) const { hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features); - return GSUBGPOS::subset<GPOS_impl::PosLookup> (&l); + return GSUBGPOS::subset<PosLookup> (&l); } bool sanitize (hb_sanitize_context_t *c) const - { return GSUBGPOS::sanitize<GPOS_impl::PosLookup> (c); } + { + TRACE_SANITIZE (this); + return_trace (GSUBGPOS::sanitize<PosLookup> (c)); + } HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, hb_face_t *face) const; @@ -51,7 +57,7 @@ struct GPOS : GSUBGPOS for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++) { if (!c->gpos_lookups->has (i)) continue; - const GPOS_impl::PosLookup &l = get_lookup (i); + const PosLookup &l = get_lookup (i); l.dispatch (c); } } @@ -59,7 +65,7 @@ struct GPOS : GSUBGPOS void closure_lookups (hb_face_t *face, const hb_set_t *glyphs, hb_set_t *lookup_indexes /* IN/OUT */) const - { GSUBGPOS::closure_lookups<GPOS_impl::PosLookup> (face, glyphs, lookup_indexes); } + { GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); } typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t; }; @@ -162,4 +168,4 @@ struct GPOS_accelerator_t : Layout::GPOS::accelerator_t { } -#endif /* OT_LAYOUT_GPOS_HH */ +#endif /* OT_LAYOUT_GPOS_GPOS_HH */ diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh new file mode 100644 index 0000000000..a2d807cc32 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh @@ -0,0 +1,56 @@ +#ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH +#define OT_LAYOUT_GPOS_LIGATUREARRAY_HH + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +typedef AnchorMatrix LigatureAttach; /* component-major-- + * in order of writing direction--, + * mark-minor-- + * ordered by class--zero-based. */ + +/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ +struct LigatureArray : List16OfOffset16To<LigatureAttach> +{ + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool subset (hb_subset_context_t *c, + Iterator coverage, + unsigned class_count, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + for (const auto _ : + hb_zip (coverage, *this) + | hb_filter (glyphset, hb_first)) + { + auto *matrix = out->serialize_append (c->serializer); + if (unlikely (!matrix)) return_trace (false); + + const LigatureAttach& src = (this + _.second); + auto indexes = + + hb_range (src.rows * class_count) + | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) + ; + matrix->serialize_subset (c, + _.second, + this, + src.rows, + indexes); + } + return_trace (this->len); + } +}; + + +} +} +} + +#endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */ diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh index e99e13ff84..c99b6b2e4b 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh @@ -11,8 +11,11 @@ struct MarkBasePos { protected: union { - HBUINT16 format; /* Format identifier */ - MarkBasePosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkBasePosFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + MarkBasePosFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -23,6 +26,9 @@ struct MarkBasePos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh index a10b806fe5..ebb8c31c67 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -12,26 +12,27 @@ typedef AnchorMatrix BaseArray; /* base-major-- * mark-minor-- * ordered by class--zero-based. */ -struct MarkBasePosFormat1 +template <typename Types> +struct MarkBasePosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> markCoverage; /* Offset to MarkCoverage table--from * beginning of MarkBasePos subtable */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> baseCoverage; /* Offset to BaseCoverage table--from * beginning of MarkBasePos subtable */ HBUINT16 classCount; /* Number of classes defined for marks */ - Offset16To<MarkArray> + typename Types::template OffsetTo<MarkArray> markArray; /* Offset to MarkArray table--from * beginning of MarkBasePos subtable */ - Offset16To<BaseArray> + typename Types::template OffsetTo<BaseArray> baseArray; /* Offset to BaseArray table--from * beginning of MarkBasePos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -117,6 +118,7 @@ struct MarkBasePosFormat1 0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) || (skippy_iter.idx == 0 || _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) || + !_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx - 1]) || _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) != _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) || _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) != diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh index 7e74aa73e0..8a4de9ffaa 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh @@ -11,8 +11,11 @@ struct MarkLigPos { protected: union { - HBUINT16 format; /* Format identifier */ - MarkLigPosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkLigPosFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + MarkLigPosFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -23,6 +26,9 @@ struct MarkLigPos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh index 4382aa6c6c..1a8021237e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -1,72 +1,34 @@ #ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH #define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH +#include "LigatureArray.hh" + namespace OT { namespace Layout { namespace GPOS_impl { -typedef AnchorMatrix LigatureAttach; /* component-major-- - * in order of writing direction--, - * mark-minor-- - * ordered by class--zero-based. */ - -/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ -struct LigatureArray : List16OfOffset16To<LigatureAttach> -{ - template <typename Iterator, - hb_requires (hb_is_iterator (Iterator))> - bool subset (hb_subset_context_t *c, - Iterator coverage, - unsigned class_count, - const hb_map_t *klass_mapping) const - { - TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - - auto *out = c->serializer->start_embed (this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - - for (const auto _ : + hb_zip (coverage, *this) - | hb_filter (glyphset, hb_first)) - { - auto *matrix = out->serialize_append (c->serializer); - if (unlikely (!matrix)) return_trace (false); - - const LigatureAttach& src = (this + _.second); - auto indexes = - + hb_range (src.rows * class_count) - | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) - ; - matrix->serialize_subset (c, - _.second, - this, - src.rows, - indexes); - } - return_trace (this->len); - } -}; -struct MarkLigPosFormat1 +template <typename Types> +struct MarkLigPosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> markCoverage; /* Offset to Mark Coverage table--from * beginning of MarkLigPos subtable */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> ligatureCoverage; /* Offset to Ligature Coverage * table--from beginning of MarkLigPos * subtable */ HBUINT16 classCount; /* Number of defined mark classes */ - Offset16To<MarkArray> + typename Types::template OffsetTo<MarkArray> markArray; /* Offset to MarkArray table--from * beginning of MarkLigPos subtable */ - Offset16To<LigatureArray> + typename Types::template OffsetTo<LigatureArray> ligatureArray; /* Offset to LigatureArray table--from * beginning of MarkLigPos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh index c0eee6d54c..74b5105c42 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh @@ -11,8 +11,11 @@ struct MarkMarkPos { protected: union { - HBUINT16 format; /* Format identifier */ - MarkMarkPosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkMarkPosFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + MarkMarkPosFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -23,6 +26,9 @@ struct MarkMarkPos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index c48a74f773..fbcebb8044 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -12,27 +12,28 @@ typedef AnchorMatrix Mark2Array; /* mark2-major-- * mark1-minor-- * ordered by class--zero-based. */ -struct MarkMarkPosFormat1 +template <typename Types> +struct MarkMarkPosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> mark1Coverage; /* Offset to Combining Mark1 Coverage * table--from beginning of MarkMarkPos * subtable */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> mark2Coverage; /* Offset to Combining Mark2 Coverage * table--from beginning of MarkMarkPos * subtable */ HBUINT16 classCount; /* Number of defined mark classes */ - Offset16To<MarkArray> + typename Types::template OffsetTo<MarkArray> mark1Array; /* Offset to Mark1Array table--from * beginning of MarkMarkPos subtable */ - Offset16To<Mark2Array> + typename Types::template OffsetTo<Mark2Array> mark2Array; /* Offset to Mark2Array table--from * beginning of MarkMarkPos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -100,7 +101,7 @@ struct MarkMarkPosFormat1 /* now we search backwards for a suitable mark glyph until a non-mark glyph */ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); - skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); + skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); unsigned unsafe_from; if (!skippy_iter.prev (&unsafe_from)) { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh index 8479178d38..72bfc43dc4 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh @@ -12,9 +12,13 @@ struct PairPos { protected: union { - HBUINT16 format; /* Format identifier */ - PairPosFormat1 format1; - PairPosFormat2 format2; + HBUINT16 format; /* Format identifier */ + PairPosFormat1_3<SmallTypes> format1; + PairPosFormat2_4<SmallTypes> format2; +#ifndef HB_NO_BORING_EXPANSION + PairPosFormat1_3<MediumTypes> format3; + PairPosFormat2_4<MediumTypes> format4; +#endif } u; public: @@ -26,6 +30,10 @@ struct PairPos switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh index 35a2db2d45..3cb207281d 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -1,248 +1,22 @@ #ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH #define OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH +#include "PairSet.hh" + namespace OT { namespace Layout { namespace GPOS_impl { -struct PairValueRecord -{ - friend struct PairSet; - - int cmp (hb_codepoint_t k) const - { return secondGlyph.cmp (k); } - - struct context_t - { - const void *base; - const ValueFormat *valueFormats; - const ValueFormat *newFormats; - unsigned len1; /* valueFormats[0].get_len() */ - const hb_map_t *glyph_map; - const hb_map_t *layout_variation_idx_map; - }; - - bool subset (hb_subset_context_t *c, - context_t *closure) const - { - TRACE_SERIALIZE (this); - auto *s = c->serializer; - auto *out = s->start_embed (*this); - if (unlikely (!s->extend_min (out))) return_trace (false); - - out->secondGlyph = (*closure->glyph_map)[secondGlyph]; - - closure->valueFormats[0].copy_values (s, - closure->newFormats[0], - closure->base, &values[0], - closure->layout_variation_idx_map); - closure->valueFormats[1].copy_values (s, - closure->newFormats[1], - closure->base, - &values[closure->len1], - closure->layout_variation_idx_map); - - return_trace (true); - } - - void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const ValueFormat *valueFormats, - const void *base) const - { - unsigned record1_len = valueFormats[0].get_len (); - unsigned record2_len = valueFormats[1].get_len (); - const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len); - - if (valueFormats[0].has_device ()) - valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len)); - - if (valueFormats[1].has_device ()) - valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len)); - } - - bool intersects (const hb_set_t& glyphset) const - { - return glyphset.has(secondGlyph); - } - - const Value* get_values_1 () const - { - return &values[0]; - } - - const Value* get_values_2 (ValueFormat format1) const - { - return &values[format1.get_len ()]; - } - protected: - HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the - * pair--first glyph is listed in the - * Coverage table */ - ValueRecord values; /* Positioning data for the first glyph - * followed by for second glyph */ - public: - DEFINE_SIZE_ARRAY (2, values); -}; - -struct PairSet +template <typename Types> +struct PairPosFormat1_3 { - friend struct PairPosFormat1; - - bool intersects (const hb_set_t *glyphs, - const ValueFormat *valueFormats) const - { - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - { - if (glyphs->has (record->secondGlyph)) - return true; - record = &StructAtOffset<const PairValueRecord> (record, record_size); - } - return false; - } - - void collect_glyphs (hb_collect_glyphs_context_t *c, - const ValueFormat *valueFormats) const - { - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - c->input->add_array (&record->secondGlyph, len, record_size); - } - - void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const ValueFormat *valueFormats) const - { - unsigned len1 = valueFormats[0].get_len (); - unsigned len2 = valueFormats[1].get_len (); - unsigned record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - unsigned count = len; - for (unsigned i = 0; i < count; i++) - { - if (c->glyph_set->has (record->secondGlyph)) - { record->collect_variation_indices (c, valueFormats, this); } - - record = &StructAtOffset<const PairValueRecord> (record, record_size); - } - } + using PairSet = GPOS_impl::PairSet<Types>; + using PairValueRecord = GPOS_impl::PairValueRecord<Types>; - bool apply (hb_ot_apply_context_t *c, - const ValueFormat *valueFormats, - unsigned int pos) const - { - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint, - &firstPairValueRecord, - len, - record_size); - if (record) - { - bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); - bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); - if (applied_first || applied_second) - buffer->unsafe_to_break (buffer->idx, pos + 1); - if (len2) - pos++; - buffer->idx = pos; - return_trace (true); - } - buffer->unsafe_to_concat (buffer->idx, pos + 1); - return_trace (false); - } - - bool subset (hb_subset_context_t *c, - const ValueFormat valueFormats[2], - const ValueFormat newFormats[2]) const - { - TRACE_SUBSET (this); - auto snap = c->serializer->snapshot (); - - auto *out = c->serializer->start_embed (*this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - out->len = 0; - - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; - - unsigned len1 = valueFormats[0].get_len (); - unsigned len2 = valueFormats[1].get_len (); - unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); - - PairValueRecord::context_t context = - { - this, - valueFormats, - newFormats, - len1, - &glyph_map, - c->plan->layout_variation_idx_map - }; - - const PairValueRecord *record = &firstPairValueRecord; - unsigned count = len, num = 0; - for (unsigned i = 0; i < count; i++) - { - if (glyphset.has (record->secondGlyph) - && record->subset (c, &context)) num++; - record = &StructAtOffset<const PairValueRecord> (record, record_size); - } - - out->len = num; - if (!num) c->serializer->revert (snap); - return_trace (num); - } - - struct sanitize_closure_t - { - const ValueFormat *valueFormats; - unsigned int len1; /* valueFormats[0].get_len() */ - unsigned int stride; /* 1 + len1 + len2 */ - }; - - bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const - { - TRACE_SANITIZE (this); - if (!(c->check_struct (this) - && c->check_range (&firstPairValueRecord, - len, - HBUINT16::static_size, - closure->stride))) return_trace (false); - - unsigned int count = len; - const PairValueRecord *record = &firstPairValueRecord; - return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) && - closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride)); - } - - protected: - HBUINT16 len; /* Number of PairValueRecords */ - PairValueRecord firstPairValueRecord; - /* Array of PairValueRecords--ordered - * by GlyphID of the second glyph */ - public: - DEFINE_SIZE_MIN (2); -}; - -struct PairPosFormat1 -{ protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat[2]; /* [0] Defines the types of data in @@ -251,11 +25,11 @@ struct PairPosFormat1 /* [1] Defines the types of data in * ValueRecord2--for the second glyph * in the pair--may be zero (0) */ - Array16OfOffset16To<PairSet> + Array16Of<typename Types::template OffsetTo<PairSet>> pairSet; /* Array of PairSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (10, pairSet); + DEFINE_SIZE_ARRAY (8 + Types::size, pairSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -265,7 +39,7 @@ struct PairPosFormat1 unsigned int len1 = valueFormat[0].get_len (); unsigned int len2 = valueFormat[1].get_len (); - PairSet::sanitize_closure_t closure = + typename PairSet::sanitize_closure_t closure = { valueFormat, len1, @@ -275,14 +49,13 @@ struct PairPosFormat1 return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); } - bool intersects (const hb_set_t *glyphs) const { return + hb_zip (this+coverage, pairSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) - | hb_map ([glyphs, this] (const Offset16To<PairSet> &_) + | hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_) { return (this+_).intersects (glyphs, valueFormat); }) | hb_any ; @@ -358,7 +131,7 @@ struct PairPosFormat1 + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) - | hb_filter ([this, c, out] (const Offset16To<PairSet>& _) + | hb_filter ([this, c, out] (const typename Types::template OffsetTo<PairSet>& _) { auto snap = c->serializer->snapshot (); auto *o = out->pairSet.serialize_append (c->serializer); @@ -391,7 +164,7 @@ struct PairPosFormat1 unsigned format1 = 0; unsigned format2 = 0; - for (const Offset16To<PairSet>& _ : + for (const auto & _ : + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second)) { const PairSet& set = (this + _); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh index 3f5f9959c4..f58bcb1b30 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -7,11 +7,12 @@ namespace OT { namespace Layout { namespace GPOS_impl { -struct PairPosFormat2 +template <typename Types> +struct PairPosFormat2_4 { protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat1; /* ValueRecord definition--for the @@ -20,11 +21,11 @@ struct PairPosFormat2 ValueFormat valueFormat2; /* ValueRecord definition--for the * second glyph of the pair--may be * zero (0) */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> classDef1; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the first glyph of the pair */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> classDef2; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the second glyph of the pair */ @@ -36,7 +37,7 @@ struct PairPosFormat2 * class1-major, class2-minor, * Each entry has value1 and value2 */ public: - DEFINE_SIZE_ARRAY (16, values); + DEFINE_SIZE_ARRAY (10 + 3 * Types::size, values); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh new file mode 100644 index 0000000000..58ba4de6c1 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh @@ -0,0 +1,173 @@ +#ifndef OT_LAYOUT_GPOS_PAIRSET_HH +#define OT_LAYOUT_GPOS_PAIRSET_HH + +#include "PairValueRecord.hh" + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +template <typename Types> +struct PairSet +{ + template <typename Types2> + friend struct PairPosFormat1_3; + + using PairValueRecord = GPOS_impl::PairValueRecord<Types>; + + protected: + HBUINT16 len; /* Number of PairValueRecords */ + PairValueRecord firstPairValueRecord; + /* Array of PairValueRecords--ordered + * by GlyphID of the second glyph */ + public: + DEFINE_SIZE_MIN (2); + + struct sanitize_closure_t + { + const ValueFormat *valueFormats; + unsigned int len1; /* valueFormats[0].get_len() */ + unsigned int stride; /* 1 + len1 + len2 */ + }; + + bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const + { + TRACE_SANITIZE (this); + if (!(c->check_struct (this) + && c->check_range (&firstPairValueRecord, + len, + HBUINT16::static_size, + closure->stride))) return_trace (false); + + unsigned int count = len; + const PairValueRecord *record = &firstPairValueRecord; + return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) && + closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride)); + } + + bool intersects (const hb_set_t *glyphs, + const ValueFormat *valueFormats) const + { + unsigned int len1 = valueFormats[0].get_len (); + unsigned int len2 = valueFormats[1].get_len (); + unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = &firstPairValueRecord; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + { + if (glyphs->has (record->secondGlyph)) + return true; + record = &StructAtOffset<const PairValueRecord> (record, record_size); + } + return false; + } + + void collect_glyphs (hb_collect_glyphs_context_t *c, + const ValueFormat *valueFormats) const + { + unsigned int len1 = valueFormats[0].get_len (); + unsigned int len2 = valueFormats[1].get_len (); + unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = &firstPairValueRecord; + c->input->add_array (&record->secondGlyph, len, record_size); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const ValueFormat *valueFormats) const + { + unsigned len1 = valueFormats[0].get_len (); + unsigned len2 = valueFormats[1].get_len (); + unsigned record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = &firstPairValueRecord; + unsigned count = len; + for (unsigned i = 0; i < count; i++) + { + if (c->glyph_set->has (record->secondGlyph)) + { record->collect_variation_indices (c, valueFormats, this); } + + record = &StructAtOffset<const PairValueRecord> (record, record_size); + } + } + + bool apply (hb_ot_apply_context_t *c, + const ValueFormat *valueFormats, + unsigned int pos) const + { + TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + unsigned int len1 = valueFormats[0].get_len (); + unsigned int len2 = valueFormats[1].get_len (); + unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint, + &firstPairValueRecord, + len, + record_size); + if (record) + { + bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); + bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); + if (applied_first || applied_second) + buffer->unsafe_to_break (buffer->idx, pos + 1); + if (len2) + pos++; + buffer->idx = pos; + return_trace (true); + } + buffer->unsafe_to_concat (buffer->idx, pos + 1); + return_trace (false); + } + + bool subset (hb_subset_context_t *c, + const ValueFormat valueFormats[2], + const ValueFormat newFormats[2]) const + { + TRACE_SUBSET (this); + auto snap = c->serializer->snapshot (); + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->len = 0; + + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + unsigned len1 = valueFormats[0].get_len (); + unsigned len2 = valueFormats[1].get_len (); + unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); + + typename PairValueRecord::context_t context = + { + this, + valueFormats, + newFormats, + len1, + &glyph_map, + c->plan->layout_variation_idx_map + }; + + const PairValueRecord *record = &firstPairValueRecord; + unsigned count = len, num = 0; + for (unsigned i = 0; i < count; i++) + { + if (glyphset.has (record->secondGlyph) + && record->subset (c, &context)) num++; + record = &StructAtOffset<const PairValueRecord> (record, record_size); + } + + out->len = num; + if (!num) c->serializer->revert (snap); + return_trace (num); + } +}; + + +} +} +} + +#endif // OT_LAYOUT_GPOS_PAIRSET_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh new file mode 100644 index 0000000000..55de5abebf --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh @@ -0,0 +1,97 @@ +#ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH +#define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +template <typename Types> +struct PairValueRecord +{ + template <typename Types2> + friend struct PairSet; + + protected: + typename Types::HBGlyphID + secondGlyph; /* GlyphID of second glyph in the + * pair--first glyph is listed in the + * Coverage table */ + ValueRecord values; /* Positioning data for the first glyph + * followed by for second glyph */ + public: + DEFINE_SIZE_ARRAY (Types::size, values); + + int cmp (hb_codepoint_t k) const + { return secondGlyph.cmp (k); } + + struct context_t + { + const void *base; + const ValueFormat *valueFormats; + const ValueFormat *newFormats; + unsigned len1; /* valueFormats[0].get_len() */ + const hb_map_t *glyph_map; + const hb_map_t *layout_variation_idx_map; + }; + + bool subset (hb_subset_context_t *c, + context_t *closure) const + { + TRACE_SERIALIZE (this); + auto *s = c->serializer; + auto *out = s->start_embed (*this); + if (unlikely (!s->extend_min (out))) return_trace (false); + + out->secondGlyph = (*closure->glyph_map)[secondGlyph]; + + closure->valueFormats[0].copy_values (s, + closure->newFormats[0], + closure->base, &values[0], + closure->layout_variation_idx_map); + closure->valueFormats[1].copy_values (s, + closure->newFormats[1], + closure->base, + &values[closure->len1], + closure->layout_variation_idx_map); + + return_trace (true); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const ValueFormat *valueFormats, + const void *base) const + { + unsigned record1_len = valueFormats[0].get_len (); + unsigned record2_len = valueFormats[1].get_len (); + const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len); + + if (valueFormats[0].has_device ()) + valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len)); + + if (valueFormats[1].has_device ()) + valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len)); + } + + bool intersects (const hb_set_t& glyphset) const + { + return glyphset.has(secondGlyph); + } + + const Value* get_values_1 () const + { + return &values[0]; + } + + const Value* get_values_2 (ValueFormat format1) const + { + return &values[format1.get_len ()]; + } +}; + + +} +} +} + +#endif // OT_LAYOUT_GPOS_PAIRVALUERECORD_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh index 57e146befd..702f578b3c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh @@ -45,10 +45,7 @@ struct SinglePos ValueFormat new_format = src->get_value_format (); if (glyph_val_iter_pairs) - { format = get_format (glyph_val_iter_pairs); - new_format = src->get_value_format ().get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second)); - } u.format = format; switch (u.format) { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh index 8b7840ed0e..c0e7d29cea 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -104,9 +104,11 @@ struct SinglePosFormat1 const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; + hb_set_t intersection; + (this+coverage).intersect_set (glyphset, intersection); + auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) + + hb_iter (intersection) | hb_map_retains_sorting (glyph_map) | hb_zip (hb_repeat (values.as_array (valueFormat.get_len ()))) ; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh index 484f347468..a5dcb65359 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh @@ -5,12 +5,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template <typename Types> struct AlternateSet { protected: - Array16Of<HBGlyphID16> + Array16Of<typename Types::HBGlyphID> alternates; /* Array of alternate GlyphIDs--in * arbitrary order */ public: diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh index e5d999261f..37406179a2 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh @@ -6,14 +6,17 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct AlternateSubst { protected: union { - HBUINT16 format; /* Format identifier */ - AlternateSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + AlternateSubstFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + AlternateSubstFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -24,10 +27,15 @@ struct AlternateSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + /* TODO This function is unused and not updated to 24bit GIDs. Should be done by using + * iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */ bool serialize (hb_serialize_context_t *c, hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> alternate_len_list, @@ -42,6 +50,9 @@ struct AlternateSubst default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh index af1cd7bedb..adec65d586 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct AlternateSubstFormat1 +template <typename Types> +struct AlternateSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To<AlternateSet> + Array16Of<typename Types::template OffsetTo<AlternateSet<Types>>> alternateSet; /* Array of AlternateSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, alternateSet); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, alternateSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -39,9 +40,8 @@ struct AlternateSubstFormat1 | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const AlternateSet &_) { _.closure (c); }) + | hb_apply ([c] (const AlternateSet<Types> &_) { _.closure (c); }) ; - } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -52,7 +52,7 @@ struct AlternateSubstFormat1 + hb_zip (this+coverage, alternateSet) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const AlternateSet<Types> &_) { _.collect_glyphs (c); }) ; } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh index bbb88b222f..08fd779f73 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ChainContextSubst : ChainContext {}; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh index f4c78a9f02..968bba0481 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh index 2af54e8ff4..9f8cb46b5e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ContextSubst : Context {}; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh index 40a3ff439f..831a7dfa2d 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ExtensionSubst : Extension<ExtensionSubst> { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh index 3f0c4b2ad9..c0ff098f49 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh @@ -1,16 +1,15 @@ #ifndef OT_LAYOUT_GSUB_GSUB_HH #define OT_LAYOUT_GSUB_GSUB_HH -// TODO(garretrieger): move to new layout. #include "../../../hb-ot-layout-gsubgpos.hh" #include "Common.hh" #include "SubstLookup.hh" -using OT::Layout::GSUB::SubstLookup; - namespace OT { + +using Layout::GSUB_impl::SubstLookup; + namespace Layout { -namespace GSUB { /* * GSUB -- Glyph Substitution @@ -33,7 +32,10 @@ struct GSUB : GSUBGPOS } bool sanitize (hb_sanitize_context_t *c) const - { return GSUBGPOS::sanitize<SubstLookup> (c); } + { + TRACE_SANITIZE (this); + return_trace (GSUBGPOS::sanitize<SubstLookup> (c)); + } HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, hb_face_t *face) const; @@ -48,10 +50,9 @@ struct GSUB : GSUBGPOS } -} -struct GSUB_accelerator_t : Layout::GSUB::GSUB::accelerator_t { - GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::GSUB::accelerator_t (face) {} +struct GSUB_accelerator_t : Layout::GSUB::accelerator_t { + GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::accelerator_t (face) {} }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh index 0448d925d1..22ed65f858 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh @@ -5,18 +5,20 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template <typename Types> struct Ligature { protected: - HBGlyphID16 ligGlyph; /* GlyphID of ligature to substitute */ - HeadlessArrayOf<HBGlyphID16> - component; /* Array of component GlyphIDs--start + typename Types::HBGlyphID + ligGlyph; /* GlyphID of ligature to substitute */ + HeadlessArrayOf<typename Types::HBGlyphID> + component; /* Array of component GlyphIDs--start * with the second component--ordered * in writing direction */ public: - DEFINE_SIZE_ARRAY (4, component); + DEFINE_SIZE_ARRAY (Types::size + 2, component); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh index 185b324b35..637cec7137 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh @@ -6,12 +6,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template <typename Types> struct LigatureSet { protected: - Array16OfOffset16To<Ligature> + Array16OfOffset16To<Ligature<Types>> ligature; /* Array LigatureSet tables * ordered by preference */ public: @@ -28,7 +29,7 @@ struct LigatureSet return + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); }) + | hb_map ([glyphs] (const Ligature<Types> &_) { return _.intersects (glyphs); }) | hb_any ; } @@ -37,7 +38,7 @@ struct LigatureSet { + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_apply ([c] (const Ligature &_) { _.closure (c); }) + | hb_apply ([c] (const Ligature<Types> &_) { _.closure (c); }) ; } @@ -45,7 +46,7 @@ struct LigatureSet { + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const Ligature<Types> &_) { _.collect_glyphs (c); }) ; } @@ -54,7 +55,7 @@ struct LigatureSet return + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_map ([c] (const Ligature &_) { return _.would_apply (c); }) + | hb_map ([c] (const Ligature<Types> &_) { return _.would_apply (c); }) | hb_any ; } @@ -65,7 +66,7 @@ struct LigatureSet unsigned int num_ligs = ligature.len; for (unsigned int i = 0; i < num_ligs; i++) { - const Ligature &lig = this+ligature[i]; + const auto &lig = this+ligature[i]; if (lig.apply (c)) return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh index a029bf5e9f..63707972a8 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh @@ -6,14 +6,17 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct LigatureSubst { protected: union { - HBUINT16 format; /* Format identifier */ - LigatureSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + LigatureSubstFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + LigatureSubstFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -24,10 +27,16 @@ struct LigatureSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + /* TODO This function is only used by small GIDs, and not updated to 24bit GIDs. Should + * be done by using iterators. While at it perhaps using iterator of arrays of hb_codepoint_t + * instead. */ bool serialize (hb_serialize_context_t *c, hb_sorted_array_t<const HBGlyphID16> first_glyphs, hb_array_t<const unsigned int> ligature_per_first_glyph_count_list, @@ -49,6 +58,9 @@ struct LigatureSubst default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh index 19dfe98469..32b642c38a 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct LigatureSubstFormat1 +template <typename Types> +struct LigatureSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To<LigatureSet> + Array16Of<typename Types::template OffsetTo<LigatureSet<Types>>> ligatureSet; /* Array LigatureSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, ligatureSet); + DEFINE_SIZE_ARRAY (4 + Types::size, ligatureSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -33,7 +34,7 @@ struct LigatureSubstFormat1 + hb_zip (this+coverage, ligatureSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) - | hb_map ([this, glyphs] (const Offset16To<LigatureSet> &_) + | hb_map ([this, glyphs] (const typename Types::template OffsetTo<LigatureSet<Types>> &_) { return (this+_).intersects (glyphs); }) | hb_any ; @@ -48,7 +49,7 @@ struct LigatureSubstFormat1 | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const LigatureSet &_) { _.closure (c); }) + | hb_apply ([c] (const LigatureSet<Types> &_) { _.closure (c); }) ; } @@ -62,7 +63,7 @@ struct LigatureSubstFormat1 + hb_zip (this+coverage, ligatureSet) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const LigatureSet<Types> &_) { _.collect_glyphs (c); }) ; } @@ -73,7 +74,7 @@ struct LigatureSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->glyphs[0]); if (likely (index == NOT_COVERED)) return false; - const LigatureSet &lig_set = this+ligatureSet[index]; + const auto &lig_set = this+ligatureSet[index]; return lig_set.would_apply (c); } @@ -84,7 +85,7 @@ struct LigatureSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const LigatureSet &lig_set = this+ligatureSet[index]; + const auto &lig_set = this+ligatureSet[index]; return_trace (lig_set.apply (c)); } @@ -128,7 +129,7 @@ struct LigatureSubstFormat1 hb_set_t new_coverage; + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this))) | hb_filter (glyphset, hb_first) - | hb_filter ([&] (const LigatureSet& _) { + | hb_filter ([&] (const LigatureSet<Types>& _) { return _.intersects (&glyphset); }, hb_second) | hb_map (hb_first) diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh index b289175504..98f2f5fe7a 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh @@ -6,14 +6,17 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct MultipleSubst { protected: union { - HBUINT16 format; /* Format identifier */ - MultipleSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + MultipleSubstFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + MultipleSubstFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -25,10 +28,15 @@ struct MultipleSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + /* TODO This function is unused and not updated to 24bit GIDs. Should be done by using + * iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */ bool serialize (hb_serialize_context_t *c, hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> substitute_len_list, @@ -43,6 +51,9 @@ struct MultipleSubst default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh index 54c6dc8478..89a04ec3b1 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct MultipleSubstFormat1 +template <typename Types> +struct MultipleSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To<Sequence> + Array16Of<typename Types::template OffsetTo<Sequence<Types>>> sequence; /* Array of Sequence tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, sequence); + DEFINE_SIZE_ARRAY (4 + Types::size, sequence); bool sanitize (hb_sanitize_context_t *c) const { @@ -39,7 +40,7 @@ struct MultipleSubstFormat1 | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const Sequence &_) { _.closure (c); }) + | hb_apply ([c] (const Sequence<Types> &_) { _.closure (c); }) ; } @@ -51,7 +52,7 @@ struct MultipleSubstFormat1 + hb_zip (this+coverage, sequence) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const Sequence<Types> &_) { _.collect_glyphs (c); }) ; } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh index 435d80fd31..48e208efb9 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ReverseChainSingleSubst { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index 7a79a9df25..1d27df95dd 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -5,7 +5,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ReverseChainSingleSubstFormat1 { @@ -33,10 +33,10 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); return_trace (substitute.sanitize (c)); } @@ -45,7 +45,7 @@ struct ReverseChainSingleSubstFormat1 if (!(this+coverage).intersects (glyphs)) return false; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); unsigned int count; @@ -69,8 +69,8 @@ struct ReverseChainSingleSubstFormat1 { if (!intersects (c->glyphs)) return; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); + hb_zip (this+coverage, substitute) | hb_filter (c->parent_active_glyphs (), hb_first) @@ -91,12 +91,12 @@ struct ReverseChainSingleSubstFormat1 for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); count = lookahead.len; for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return; - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); count = substitute.len; c->output->add_array (substitute.arrayZ, substitute.len); } @@ -115,8 +115,8 @@ struct ReverseChainSingleSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); if (unlikely (index >= substitute.len)) return_trace (false); @@ -206,8 +206,8 @@ struct ReverseChainSingleSubstFormat1 const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); auto it = + hb_zip (this+coverage, substitute) diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh index ebd451e6ba..c5cd15bb23 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh @@ -5,12 +5,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template <typename Types> struct Sequence { protected: - Array16Of<HBGlyphID16> + Array16Of<typename Types::HBGlyphID> substitute; /* String of GlyphIDs to substitute */ public: DEFINE_SIZE_ARRAY (2, substitute); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh index 786428fe45..6942e6997f 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh @@ -7,15 +7,19 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SingleSubst { protected: union { - HBUINT16 format; /* Format identifier */ - SingleSubstFormat1 format1; - SingleSubstFormat2 format2; + HBUINT16 format; /* Format identifier */ + SingleSubstFormat1_3<SmallTypes> format1; + SingleSubstFormat2_4<SmallTypes> format2; +#ifndef HB_NO_BORING_EXPANSION + SingleSubstFormat1_3<MediumTypes> format3; + SingleSubstFormat2_4<MediumTypes> format4; +#endif } u; public: @@ -28,6 +32,10 @@ struct SingleSubst switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } @@ -45,11 +53,24 @@ struct SingleSubst if (glyphs) { format = 1; + hb_codepoint_t mask = 0xFFFFu; + +#ifndef HB_NO_BORING_EXPANSION + if (+ glyphs + | hb_map_retains_sorting (hb_first) + | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; })) + { + format += 2; + mask = 0xFFFFFFu; + } +#endif + auto get_delta = [=] (hb_codepoint_pair_t _) - { return (unsigned) (_.second - _.first) & 0xFFFF; }; + { return (unsigned) (_.second - _.first) & mask; }; delta = get_delta (*glyphs); - if (!hb_all (++(+glyphs), delta, get_delta)) format = 2; + if (!hb_all (++(+glyphs), delta, get_delta)) format += 1; } + u.format = format; switch (u.format) { case 1: return_trace (u.format1.serialize (c, @@ -57,6 +78,13 @@ struct SingleSubst | hb_map_retains_sorting (hb_first), delta)); case 2: return_trace (u.format2.serialize (c, glyphs)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (u.format3.serialize (c, + + glyphs + | hb_map_retains_sorting (hb_first), + delta)); + case 4: return_trace (u.format4.serialize (c, glyphs)); +#endif default:return_trace (false); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh index 3c6b2954ce..dd44595741 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -5,20 +5,22 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct SingleSubstFormat1 +template <typename Types> +struct SingleSubstFormat1_3 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - HBUINT16 deltaGlyphID; /* Add to original GlyphID to get + typename Types::HBUINT + deltaGlyphID; /* Add to original GlyphID to get * substitute GlyphID, modulo 0x10000 */ public: - DEFINE_SIZE_STATIC (6); + DEFINE_SIZE_STATIC (2 + 2 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -26,6 +28,9 @@ struct SingleSubstFormat1 return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); } + hb_codepoint_t get_mask () const + { return (1 << (8 * Types::size)) - 1; } + bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } @@ -34,14 +39,16 @@ struct SingleSubstFormat1 void closure (hb_closure_context_t *c) const { - unsigned d = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); - + hb_iter (this+coverage) - | hb_filter (c->parent_active_glyphs ()) - | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) + hb_set_t intersection; + (this+coverage).intersect_set (c->parent_active_glyphs (), intersection); + + + hb_iter (intersection) + | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) | hb_sink (c->output) ; - } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -49,9 +56,11 @@ struct SingleSubstFormat1 void collect_glyphs (hb_collect_glyphs_context_t *c) const { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; - unsigned d = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + hb_iter (this+coverage) - | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) + | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) | hb_sink (c->output) ; } @@ -68,9 +77,11 @@ struct SingleSubstFormat1 unsigned int index = (this+coverage).get_coverage (glyph_id); if (likely (index == NOT_COVERED)) return_trace (false); - /* According to the Adobe Annotated OpenType Suite, result is always - * limited to 16bit. */ - glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + glyph_id = (glyph_id + d) & mask; + c->replace_glyph (glyph_id); return_trace (true); @@ -95,14 +106,17 @@ struct SingleSubstFormat1 const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - hb_codepoint_t delta = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + hb_set_t intersection; + (this+coverage).intersect_set (glyphset, intersection); auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) - | hb_map_retains_sorting ([&] (hb_codepoint_t g) { + + hb_iter (intersection) + | hb_map_retains_sorting ([d, mask] (hb_codepoint_t g) { return hb_codepoint_pair_t (g, - (g + delta) & 0xFFFF); }) + (g + d) & mask); }) | hb_filter (glyphset, hb_second) | hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh index df75bb52bb..386419a2a5 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -5,21 +5,22 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct SingleSubstFormat2 +template <typename Types> +struct SingleSubstFormat2_4 { protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16Of<HBGlyphID16> + Array16Of<typename Types::HBGlyphID> substitute; /* Array of substitute * GlyphIDs--ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, substitute); + DEFINE_SIZE_ARRAY (4 + Types::size, substitute); bool sanitize (hb_sanitize_context_t *c) const { @@ -103,7 +104,7 @@ struct SingleSubstFormat2 + hb_zip (this+coverage, substitute) | hb_filter (glyphset, hb_first) | hb_filter (glyphset, hb_second) - | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t + | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const typename Types::HBGlyphID &> p) -> hb_codepoint_pair_t { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) ; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh index 8fb3b55097..320685b868 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SubstLookup : Lookup { @@ -25,7 +25,7 @@ struct SubstLookup : Lookup { unsigned int type = get_type (); if (unlikely (type == SubTable::Extension)) - return reinterpret_cast<const ExtensionSubst &> (get_subtable (0)).is_reverse (); + return get_subtable (0).u.extension.is_reverse (); return lookup_type_is_reverse (type); } @@ -98,10 +98,15 @@ struct SubstLookup : Lookup return dispatch (c); } + template<typename Glyphs, typename Substitutes, + hb_requires (hb_is_sorted_source_of (Glyphs, + const hb_codepoint_t) && + hb_is_source_of (Substitutes, + const hb_codepoint_t))> bool serialize_single (hb_serialize_context_t *c, uint32_t lookup_props, - hb_sorted_array_t<const HBGlyphID16> glyphs, - hb_array_t<const HBGlyphID16> substitutes) + Glyphs glyphs, + Substitutes substitutes) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh index 53e963e2a2..a525fba039 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh @@ -13,7 +13,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SubstLookupSubTable { diff --git a/thirdparty/harfbuzz/src/OT/Layout/types.hh b/thirdparty/harfbuzz/src/OT/Layout/types.hh new file mode 100644 index 0000000000..6a43403e94 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/types.hh @@ -0,0 +1,66 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod, Garret Rieger + */ + +#ifndef OT_LAYOUT_TYPES_HH +#define OT_LAYOUT_TYPES_HH + +namespace OT { +namespace Layout { + +struct SmallTypes { + static constexpr unsigned size = 2; + using large_int = uint32_t; + using HBUINT = HBUINT16; + using HBGlyphID = HBGlyphID16; + using Offset = Offset16; + template <typename Type, bool has_null=true> + using OffsetTo = OT::Offset16To<Type, has_null>; + template <typename Type> + using ArrayOf = OT::Array16Of<Type>; + template <typename Type> + using SortedArrayOf = OT::SortedArray16Of<Type>; +}; + +struct MediumTypes { + static constexpr unsigned size = 3; + using large_int = uint64_t; + using HBUINT = HBUINT24; + using HBGlyphID = HBGlyphID24; + using Offset = Offset24; + template <typename Type, bool has_null=true> + using OffsetTo = OT::Offset24To<Type, has_null>; + template <typename Type> + using ArrayOf = OT::Array24Of<Type>; + template <typename Type> + using SortedArrayOf = OT::SortedArray24Of<Type>; +}; + +} +} + +#endif /* OT_LAYOUT_TYPES_HH */ diff --git a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh index c145beaa49..abe4c8330c 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh @@ -25,13 +25,16 @@ struct CompositeGlyphRecord USE_MY_METRICS = 0x0200, OVERLAP_COMPOUND = 0x0400, SCALED_COMPONENT_OFFSET = 0x0800, - UNSCALED_COMPONENT_OFFSET = 0x1000 + UNSCALED_COMPONENT_OFFSET = 0x1000, + GID_IS_24BIT = 0x2000 }; public: unsigned int get_size () const { unsigned int size = min_size; + /* glyphIndex is 24bit instead of 16bit */ + if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size; /* arg1 and 2 are int16 */ if (flags & ARG_1_AND_2_ARE_WORDS) size += 4; /* arg1 and 2 are int8 */ @@ -60,7 +63,11 @@ struct CompositeGlyphRecord bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); } void get_anchor_points (unsigned int &point1, unsigned int &point2) const { - const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex); + const auto *p = &StructAfter<const HBUINT8> (flags); + if (flags & GID_IS_24BIT) + p += HBGlyphID24::static_size; + else + p += HBGlyphID16::static_size; if (flags & ARG_1_AND_2_ARE_WORDS) { point1 = ((const HBUINT16 *) p)[0]; @@ -101,8 +108,12 @@ struct CompositeGlyphRecord matrix[0] = matrix[3] = 1.f; matrix[1] = matrix[2] = 0.f; + const auto *p = &StructAfter<const HBINT8> (flags); + if (flags & GID_IS_24BIT) + p += HBGlyphID24::static_size; + else + p += HBGlyphID16::static_size; int tx, ty; - const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex); if (flags & ARG_1_AND_2_ARE_WORDS) { tx = *(const HBINT16 *) p; @@ -145,8 +156,25 @@ struct CompositeGlyphRecord } public: + hb_codepoint_t get_gid () const + { + if (flags & GID_IS_24BIT) + return StructAfter<const HBGlyphID24> (flags); + else + return StructAfter<const HBGlyphID16> (flags); + } + void set_gid (hb_codepoint_t gid) + { + if (flags & GID_IS_24BIT) + StructAfter<HBGlyphID24> (flags) = gid; + else + /* TODO assert? */ + StructAfter<HBGlyphID16> (flags) = gid; + } + + protected: HBUINT16 flags; - HBGlyphID16 glyphIndex; + HBUINT24 pad; public: DEFINE_SIZE_MIN (4); }; diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh index 2199d2c48b..3efe538f37 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh @@ -105,19 +105,21 @@ struct Glyph if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { - int h_delta = (int) header->xMin - - glyf_accelerator.hmtx->get_side_bearing (gid); + int lsb = 0; + int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? + (int) header->xMin - lsb : 0; + int tsb = 0; int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_side_bearing (gid) + ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) #else 0 #endif ; - unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid); + unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_advance (gid) + glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid) #else - font->face->get_upem () #endif @@ -144,7 +146,7 @@ struct Glyph for (auto &item : get_composite_iterator ()) { comp_points.reset (); - if (unlikely (!glyf_accelerator.glyph_for_gid (item.glyphIndex) + if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ()) .get_points (font, glyf_accelerator, comp_points, phantom_only, depth + 1))) return false; @@ -198,11 +200,11 @@ struct Glyph return !all_points.in_error (); } - bool get_extents (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, - hb_glyph_extents_t *extents) const + bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, + hb_glyph_extents_t *extents) const { if (type == EMPTY) return true; /* Empty glyph; zero extents. */ - return header->get_extents (font, glyf_accelerator, gid, extents); + return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents); } hb_bytes_t get_bytes () const { return bytes; } diff --git a/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh b/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh index 792bd5478f..e4a9168b79 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh @@ -14,12 +14,14 @@ struct GlyphHeader bool has_data () const { return numberOfContours; } template <typename accelerator_t> - bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator, - hb_codepoint_t gid, hb_glyph_extents_t *extents) const + bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator, + hb_codepoint_t gid, hb_glyph_extents_t *extents) const { /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */ /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */ - extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid)); + int lsb = hb_min (xMin, xMax); + (void) glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + extents->x_bearing = font->em_scale_x (lsb); extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax)); extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax)); extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax)); diff --git a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh index ebe4372047..7ae8fe3078 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh @@ -42,8 +42,8 @@ struct SubsetGlyph for (auto &_ : Glyph (dest_glyph).get_composite_iterator ()) { hb_codepoint_t new_gid; - if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid)) - const_cast<CompositeGlyphRecord &> (_).glyphIndex = new_gid; + if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) + const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid); } if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh index f74513cb96..bcaf44fc1e 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh @@ -194,6 +194,7 @@ struct glyf_accelerator_t hb_font_t *font; hb_glyph_extents_t *extents; contour_point_t *phantoms; + bool scaled; struct contour_bounds_t { @@ -209,7 +210,7 @@ struct glyf_accelerator_t bool empty () const { return (min_x >= max_x) || (min_y >= max_y); } - void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) + void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scaled) { if (unlikely (empty ())) { @@ -219,26 +220,37 @@ struct glyf_accelerator_t extents->y_bearing = 0; return; } - extents->x_bearing = font->em_scalef_x (min_x); - extents->width = font->em_scalef_x (max_x) - extents->x_bearing; - extents->y_bearing = font->em_scalef_y (max_y); - extents->height = font->em_scalef_y (min_y) - extents->y_bearing; + if (scaled) + { + extents->x_bearing = font->em_scalef_x (min_x); + extents->width = font->em_scalef_x (max_x) - extents->x_bearing; + extents->y_bearing = font->em_scalef_y (max_y); + extents->height = font->em_scalef_y (min_y) - extents->y_bearing; + } + else + { + extents->x_bearing = roundf (min_x); + extents->width = roundf (max_x - extents->x_bearing); + extents->y_bearing = roundf (max_y); + extents->height = roundf (min_y - extents->y_bearing); + } } protected: float min_x, min_y, max_x, max_y; } bounds; - points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_) + points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_, bool scaled_) { font = font_; extents = extents_; phantoms = phantoms_; + scaled = scaled_; if (extents) bounds = contour_bounds_t (); } void consume_point (const contour_point_t &point) { bounds.add (point); } - void points_end () { bounds.get_extents (font, extents); } + void points_end () { bounds.get_extents (font, extents, scaled); } bool is_consuming_contour_points () { return extents; } contour_point_t *get_phantoms_sink () { return phantoms; } @@ -246,22 +258,22 @@ struct glyf_accelerator_t public: unsigned - get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const { if (unlikely (gid >= num_glyphs)) return 0; bool success = false; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (likely (font->num_coords == gvar->get_axis_count ())) - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms)); + if (font->num_coords) + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false)); if (unlikely (!success)) return #ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_advance (gid) : + is_vertical ? vmtx->get_advance_without_var_unscaled (gid) : #endif - hmtx->get_advance (gid); + hmtx->get_advance_without_var_unscaled (gid); float result = is_vertical ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y @@ -269,23 +281,20 @@ struct glyf_accelerator_t return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); } - int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const { - if (unlikely (gid >= num_glyphs)) return 0; + if (unlikely (gid >= num_glyphs)) return false; hb_glyph_extents_t extents; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms)))) - return -#ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_side_bearing (gid) : -#endif - hmtx->get_side_bearing (gid); + if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false)))) + return false; - return is_vertical - ? ceilf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing - : floorf (phantoms[glyf_impl::PHANTOM_LEFT].x); + *lsb = is_vertical + ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing + : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x); + return true; } #endif @@ -296,9 +305,9 @@ struct glyf_accelerator_t #ifndef HB_NO_VAR if (font->num_coords) - return get_points (font, gid, points_aggregator_t (font, extents, nullptr)); + return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true)); #endif - return glyph_for_gid (gid).get_extents (font, *this, extents); + return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); } const glyf_impl::Glyph diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh index 52ca9dd142..49638f34a7 100644 --- a/thirdparty/harfbuzz/src/graph/graph.hh +++ b/thirdparty/harfbuzz/src/graph/graph.hh @@ -265,28 +265,64 @@ struct graph_t } /* - * Assign unique space numbers to each connected subgraph of 32 bit offset(s). + * Finds the set of nodes (placed into roots) that should be assigned unique spaces. + * More specifically this looks for the top most 24 bit or 32 bit links in the graph. + * Some special casing is done that is specific to the layout of GSUB/GPOS tables. */ - bool assign_32bit_spaces () + void find_space_roots (hb_set_t& visited, hb_set_t& roots) { - unsigned root_index = root_idx (); - hb_set_t visited; - hb_set_t roots; - for (unsigned i = 0; i <= root_index; i++) + int root_index = (int) root_idx (); + for (int i = root_index; i >= 0; i--) { + if (visited.has (i)) continue; + // Only real links can form 32 bit spaces for (auto& l : vertices_[i].obj.real_links) { - if (l.width == 4 && !l.is_signed) + if (l.is_signed || l.width < 3) + continue; + + if (i == root_index && l.width == 3) + // Ignore 24bit links from the root node, this skips past the single 24bit + // pointer to the lookup list. + continue; + + if (l.width == 3) { - roots.add (l.objidx); - find_subgraph (l.objidx, visited); + // A 24bit offset forms a root, unless there is 32bit offsets somewhere + // in it's subgraph, then those become the roots instead. This is to make sure + // that extension subtables beneath a 24bit lookup become the spaces instead + // of the offset to the lookup. + hb_set_t sub_roots; + find_32bit_roots (l.objidx, sub_roots); + if (sub_roots) { + for (unsigned sub_root_idx : sub_roots) { + roots.add (sub_root_idx); + find_subgraph (sub_root_idx, visited); + } + continue; + } } + + roots.add (l.objidx); + find_subgraph (l.objidx, visited); } } + } - // Mark everything not in the subgraphs of 32 bit roots as visited. - // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs. + /* + * Assign unique space numbers to each connected subgraph of 24 bit and/or 32 bit offset(s). + * Currently, this is implemented specifically tailored to the structure of a GPOS/GSUB + * (including with 24bit offsets) table. + */ + bool assign_spaces () + { + hb_set_t visited; + hb_set_t roots; + find_space_roots (visited, roots); + + // Mark everything not in the subgraphs of the roots as visited. This prevents + // subgraphs from being connected via nodes not in those subgraphs. visited.invert (); if (!roots) return false; @@ -423,6 +459,22 @@ struct graph_t } /* + * Finds the topmost children of 32bit offsets in the subgraph starting + * at node_idx. Found indices are placed into 'found'. + */ + void find_32bit_roots (unsigned node_idx, hb_set_t& found) + { + for (const auto& link : vertices_[node_idx].obj.all_links ()) + { + if (!link.is_signed && link.width == 4) { + found.add (link.objidx); + continue; + } + find_32bit_roots (link.objidx, found); + } + } + + /* * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign * links. index_map is updated with mappings from old id to new id. If a duplication has already * been performed for a given index, then it will be skipped. @@ -622,7 +674,7 @@ struct graph_t private: /* - * Returns the numbers of incoming edges that are 32bits wide. + * Returns the numbers of incoming edges that are 24 or 32 bits wide. */ unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const { @@ -636,7 +688,9 @@ struct graph_t // Only real links can be wide for (const auto& l : vertices_[p].obj.real_links) { - if (l.objidx == node_idx && l.width == 4 && !l.is_signed) + if (l.objidx == node_idx + && (l.width == 3 || l.width == 4) + && !l.is_signed) { count++; parents.add (p); diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh index b52844e75d..bf12d2e699 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh @@ -42,7 +42,7 @@ struct BaselineTableFormat0Part bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -78,7 +78,7 @@ struct BaselineTableFormat2Part bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh index 1db0f1df92..6cbed82692 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh @@ -415,18 +415,7 @@ struct Lookup public: DEFINE_SIZE_UNION (2, format); }; -/* Lookup 0 has unbounded size (dependant on num_glyphs). So we need to defined - * special NULL objects for Lookup<> objects, but since it's template our macros - * don't work. So we have to hand-code them here. UGLY. */ -} /* Close namespace. */ -/* Ugly hand-coded null objects for template Lookup<> :(. */ -extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2]; -template <typename T> -struct Null<AAT::Lookup<T>> { - static AAT::Lookup<T> const & get_null () - { return *reinterpret_cast<const AAT::Lookup<T> *> (_hb_Null_AAT_Lookup); } -}; -namespace AAT { +DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); enum { DELETED_GLYPH = 0xFFFF }; @@ -681,6 +670,13 @@ struct ObsoleteTypes const void *base, const T *array) { + /* https://github.com/harfbuzz/harfbuzz/issues/3483 */ + /* If offset is less than base, return an offset that would + * result in an address half a 32bit address-space away, + * to make sure sanitize fails even on 32bit builds. */ + if (unlikely (offset < unsigned ((const char *) array - (const char *) base))) + return INT_MAX / T::static_size; + /* https://github.com/harfbuzz/harfbuzz/issues/2816 */ return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size; } diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh index 573f0cf9f6..815a1fd2aa 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh @@ -62,7 +62,7 @@ struct SettingName bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh index 0bf9bd2912..57c105967d 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh @@ -48,7 +48,7 @@ struct ActionSubrecordHeader bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } HBUINT16 actionClass; /* The JustClass value associated with this @@ -65,7 +65,7 @@ struct DecompositionAction bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } ActionSubrecordHeader @@ -112,7 +112,7 @@ struct ConditionalAddGlyphAction bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -137,7 +137,7 @@ struct DuctileGlyphAction bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -163,7 +163,7 @@ struct RepeatedAddGlyphAction bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -294,7 +294,7 @@ struct WidthDeltaPair bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh index 6a24c90c31..995492cd5a 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh @@ -751,7 +751,7 @@ struct KerxSubTableHeader bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } public: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh index 3d053cb13e..aa4ad4cf3c 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh @@ -980,6 +980,15 @@ struct Chain setting = HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS; goto retry; } +#ifndef HB_NO_AAT + else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE && setting && + /* TODO: Rudimentary language matching. */ + hb_language_matches (map->face->table.ltag->get_language (setting - 1), map->props.language)) + { + flags &= feature.disableFlags; + flags |= feature.enableFlags; + } +#endif } } return flags; diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh index b1a1512821..51b650fc33 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh @@ -42,7 +42,7 @@ struct OpticalBounds bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } FWORD leftSide; diff --git a/thirdparty/harfbuzz/src/hb-aat-layout.cc b/thirdparty/harfbuzz/src/hb-aat-layout.cc index caff204d67..e06d286ff0 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout.cc +++ b/thirdparty/harfbuzz/src/hb-aat-layout.cc @@ -229,7 +229,7 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, * * <note>Note: does not examine the `GSUB` table.</note> * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ @@ -300,7 +300,7 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) * * <note>Note: does not examine the `GPOS` table.</note> * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ @@ -333,7 +333,7 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, * Tests whether the specified face includes any tracking information * in the `trak` table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ diff --git a/thirdparty/harfbuzz/src/hb-aat-map.hh b/thirdparty/harfbuzz/src/hb-aat-map.hh index 5a0fa70544..c914f58d70 100644 --- a/thirdparty/harfbuzz/src/hb-aat-map.hh +++ b/thirdparty/harfbuzz/src/hb-aat-map.hh @@ -52,8 +52,9 @@ struct hb_aat_map_builder_t public: HB_INTERNAL hb_aat_map_builder_t (hb_face_t *face_, - const hb_segment_properties_t *props_ HB_UNUSED) : - face (face_) {} + const hb_segment_properties_t props_) : + face (face_), + props (props_) {} HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1); @@ -87,6 +88,7 @@ struct hb_aat_map_builder_t public: hb_face_t *face; + hb_segment_properties_t props; public: hb_sorted_vector_t<feature_info_t> features; diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index f1633d886a..cc37c073da 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -109,15 +109,16 @@ struct BEInt<Type, 2> struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; constexpr operator Type () const { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) /* Spoon-feed the compiler a big-endian integer with alignment 1. * https://github.com/harfbuzz/harfbuzz/pull/1398 */ #if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) this)->v); + return __builtin_bswap16 (((packed_uint16_t *) v)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) this)->v; + return ((packed_uint16_t *) v)->v; #endif #else return (v[0] << 8) @@ -153,15 +154,16 @@ struct BEInt<Type, 4> struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; constexpr operator Type () const { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) /* Spoon-feed the compiler a big-endian integer with alignment 1. * https://github.com/harfbuzz/harfbuzz/pull/1398 */ #if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap32 (((packed_uint32_t *) this)->v); + return __builtin_bswap32 (((packed_uint32_t *) v)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint32_t *) this)->v; + return ((packed_uint32_t *) v)->v; #endif #else return (v[0] << 24) @@ -525,7 +527,6 @@ struct hb_pair_t T1 first; T2 second; }; -#define hb_pair_t(T1,T2) hb_pair_t<T1, T2> template <typename T1, typename T2> static inline hb_pair_t<T1, T2> hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); } @@ -551,14 +552,14 @@ struct { template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (a <= b ? std::forward<T> (a) : std::forward<T2> (b)) + (a <= b ? a : b) } HB_FUNCOBJ (hb_min); struct { template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (a >= b ? std::forward<T> (a) : std::forward<T2> (b)) + (a >= b ? a : b) } HB_FUNCOBJ (hb_max); struct @@ -972,7 +973,7 @@ void hb_qsort(void *base, size_t nel, size_t width, [void *arg]); */ -#define SORT_R_SWAP(a,b,tmp) ((tmp) = (a), (a) = (b), (b) = (tmp)) +#define SORT_R_SWAP(a,b,tmp) ((void) ((tmp) = (a)), (void) ((a) = (b)), (b) = (tmp)) /* swap a and b */ /* a and b must not be equal! */ diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh index 5baeb6f7fe..826a901819 100644 --- a/thirdparty/harfbuzz/src/hb-array.hh +++ b/thirdparty/harfbuzz/src/hb-array.hh @@ -100,10 +100,9 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> /* Ouch. The operator== compares the contents of the array. For range-based for loops, * it's best if we can just compare arrayZ, though comparing contents is still fast, * but also would require that Type has operator==. As such, we optimize this operator - * for range-based for loop and just compare arrayZ. No need to compare length, as we - * assume we're only compared to .end(). */ + * for range-based for loop and just compare arrayZ and length. */ bool operator != (const hb_array_t& o) const - { return arrayZ != o.arrayZ; } + { return this->arrayZ != o.arrayZ || this->length != o.length; } /* Extra operators. */ @@ -220,11 +219,8 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> if (end < start + 2) return; - for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) { - Type temp = arrayZ[rhs]; - arrayZ[rhs] = arrayZ[lhs]; - arrayZ[lhs] = temp; - } + for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) + hb_swap (arrayZ[rhs], arrayZ[lhs]); } hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const @@ -328,6 +324,8 @@ struct hb_sorted_array_t : { hb_array_t<Type> (*this) = o; return *this; } /* Iterator implementation. */ + + /* See comment in hb_array_of::operator != */ bool operator != (const hb_sorted_array_t& o) const { return this->arrayZ != o.arrayZ || this->length != o.length; } diff --git a/thirdparty/harfbuzz/src/hb-atomic.hh b/thirdparty/harfbuzz/src/hb-atomic.hh index e640d1b586..d6dfb0f57a 100644 --- a/thirdparty/harfbuzz/src/hb-atomic.hh +++ b/thirdparty/harfbuzz/src/hb-atomic.hh @@ -111,6 +111,19 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #endif +#ifndef _hb_compiler_memory_r_barrier +/* This we always use std::atomic for; and should never be disabled... + * except that MSVC gives me an internal compiler error on it. */ +#if !defined(_MSC_VER) +#include <atomic> +#define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire) +#else +#define _hb_compiler_memory_r_barrier() do {} while (0) +#endif +#endif + + + #ifndef _hb_memory_r_barrier #define _hb_memory_r_barrier() _hb_memory_barrier () #endif diff --git a/thirdparty/harfbuzz/src/hb-bit-page.hh b/thirdparty/harfbuzz/src/hb-bit-page.hh index cbe918ee40..95ae1b7bf9 100644 --- a/thirdparty/harfbuzz/src/hb-bit-page.hh +++ b/thirdparty/harfbuzz/src/hb-bit-page.hh @@ -55,7 +55,7 @@ struct hb_bit_page_t void add (hb_codepoint_t g) { elt (g) |= mask (g); } void del (hb_codepoint_t g) { elt (g) &= ~mask (g); } - void set (hb_codepoint_t g, bool v) { if (v) add (g); else del (g); } + void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); } bool get (hb_codepoint_t g) const { return elt (g) & mask (g); } void add_range (hb_codepoint_t a, hb_codepoint_t b) diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh index 438fb66a2c..4765af67ce 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set.hh @@ -465,12 +465,10 @@ struct hb_bit_set_t } public: - template <typename Op> - void process (const Op& op, const hb_bit_set_t &other) + void process_ (hb_bit_page_t::vector_t (*op) (const hb_bit_page_t::vector_t &, const hb_bit_page_t::vector_t &), + bool passthru_left, bool passthru_right, + const hb_bit_set_t &other) { - const bool passthru_left = op (1, 0); - const bool passthru_right = op (0, 1); - if (unlikely (!successful)) return; dirty (); @@ -590,6 +588,15 @@ struct hb_bit_set_t assert (!count); resize (newCount); } + template <typename Op> + static hb_bit_page_t::vector_t + op_ (const hb_bit_page_t::vector_t &a, const hb_bit_page_t::vector_t &b) + { return Op{} (a, b); } + template <typename Op> + void process (const Op& op, const hb_bit_set_t &other) + { + process_ (op_<Op>, op (1, 0), op (0, 1), other); + } void union_ (const hb_bit_set_t &other) { process (hb_bitwise_or, other); } void intersect (const hb_bit_set_t &other) { process (hb_bitwise_and, other); } diff --git a/thirdparty/harfbuzz/src/hb-blob.cc b/thirdparty/harfbuzz/src/hb-blob.cc index b561a9374e..47062eab9a 100644 --- a/thirdparty/harfbuzz/src/hb-blob.cc +++ b/thirdparty/harfbuzz/src/hb-blob.cc @@ -99,7 +99,7 @@ hb_blob_create (const char *data, * is zero. This is in contrast to hb_blob_create(), which returns the singleton * empty blob (as returned by hb_blob_get_empty()) if @length is zero. * - * Return value: New blob, or %NULL if failed. Destroy with hb_blob_destroy(). + * Return value: New blob, or `NULL` if failed. Destroy with hb_blob_destroy(). * * Since: 2.8.2 **/ @@ -263,8 +263,6 @@ hb_blob_destroy (hb_blob_t *blob) { if (!hb_object_destroy (blob)) return; - blob->fini_shallow (); - hb_free (blob); } @@ -278,7 +276,7 @@ hb_blob_destroy (hb_blob_t *blob) * * Attaches a user-data key/data pair to the specified blob. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -335,7 +333,7 @@ hb_blob_make_immutable (hb_blob_t *blob) * * Tests whether a blob is immutable. * - * Return value: %true if @blob is immutable, %false otherwise + * Return value: `true` if @blob is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -394,7 +392,7 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length) * fails. * * Returns: (transfer none) (array length=length): Writable blob data, - * or %NULL if failed. + * or `NULL` if failed. * * Since: 0.9.2 **/ @@ -620,7 +618,7 @@ hb_blob_create_from_file (const char *file_name) * specified binary font file. * * Returns: An #hb_blob_t pointer with the content of the file, - * or %NULL if failed. + * or `NULL` if failed. * * Since: 2.8.2 **/ diff --git a/thirdparty/harfbuzz/src/hb-blob.hh b/thirdparty/harfbuzz/src/hb-blob.hh index a3683a681e..b1b3b94d3d 100644 --- a/thirdparty/harfbuzz/src/hb-blob.hh +++ b/thirdparty/harfbuzz/src/hb-blob.hh @@ -38,7 +38,7 @@ struct hb_blob_t { - void fini_shallow () { destroy_user_data (); } + ~hb_blob_t () { destroy_user_data (); } void destroy_user_data () { @@ -61,12 +61,12 @@ struct hb_blob_t public: hb_object_header_t header; - const char *data; - unsigned int length; - hb_memory_mode_t mode; + const char *data = nullptr; + unsigned int length = 0; + hb_memory_mode_t mode = (hb_memory_mode_t) 0; - void *user_data; - hb_destroy_func_t destroy; + void *user_data = nullptr; + hb_destroy_func_t destroy = nullptr; }; diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh index e80cfea6e7..44c802a00c 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh @@ -32,15 +32,16 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-json.hh" +#line 33 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, - 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 34u, 92u, 9u, 125u, 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0 + 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, + 9u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 34u, 92u, 9u, 125u, + 34u, 92u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 93u, + 9u, 123u, 0u, 0u, 0 }; static const char _deserialize_json_key_spans[] = { @@ -48,9 +49,10 @@ static const char _deserialize_json_key_spans[] = { 10, 117, 117, 117, 1, 50, 49, 10, 117, 117, 1, 1, 50, 49, 117, 117, 2, 1, 50, 49, 10, 117, 117, 1, - 50, 49, 10, 117, 117, 1, 50, 49, - 59, 117, 59, 117, 117, 1, 50, 49, - 117, 85, 115, 0 + 50, 49, 10, 117, 117, 1, 1, 50, + 49, 117, 117, 1, 50, 49, 59, 117, + 59, 117, 117, 1, 50, 49, 117, 85, + 115, 0 }; static const short _deserialize_json_index_offsets[] = { @@ -58,9 +60,10 @@ static const short _deserialize_json_index_offsets[] = { 271, 282, 400, 518, 636, 638, 689, 739, 750, 868, 986, 988, 990, 1041, 1091, 1209, 1327, 1330, 1332, 1383, 1433, 1444, 1562, 1680, - 1682, 1733, 1783, 1794, 1912, 2030, 2032, 2083, - 2133, 2193, 2311, 2371, 2489, 2607, 2609, 2660, - 2710, 2828, 2914, 3030 + 1682, 1733, 1783, 1794, 1912, 2030, 2032, 2034, + 2085, 2135, 2253, 2371, 2373, 2424, 2474, 2534, + 2652, 2712, 2830, 2948, 2950, 3001, 3051, 3169, + 3255, 3371 }; static const char _deserialize_json_indicies[] = { @@ -82,28 +85,28 @@ static const char _deserialize_json_indicies[] = { 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 1, 8, 1, + 5, 1, 6, 7, 1, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 9, 1, 10, 11, - 1, 12, 1, 12, 12, 12, 12, 12, + 1, 1, 1, 1, 10, 1, 11, 12, + 1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 12, 1, 1, 1, 1, 1, + 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 13, 1, 13, 13, - 13, 13, 13, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 14, 1, 14, 14, + 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 13, 1, 1, + 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 14, 1, 1, 15, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 1, - 17, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 1, 19, 19, 19, 19, 19, + 1, 1, 15, 1, 1, 16, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 1, + 18, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 1, 20, 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 19, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 20, 1, + 1, 1, 20, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -113,11 +116,11 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 21, - 1, 22, 22, 22, 22, 22, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 22, + 1, 23, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 22, 1, 1, 1, 1, 1, 1, 1, + 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -128,41 +131,58 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 23, 1, 19, - 19, 19, 19, 19, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 24, 1, 20, + 20, 20, 20, 20, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 20, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 21, 1, 1, 1, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 22, 1, 25, 1, 25, + 25, 25, 25, 25, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 25, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 20, 1, 1, 1, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, + 26, 1, 26, 26, 26, 26, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 26, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 27, 1, + 1, 28, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 1, 30, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 1, 32, + 32, 32, 32, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 21, 1, 24, 1, 24, - 24, 24, 24, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 25, 1, 25, 25, 25, 25, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 34, 1, 32, 32, 32, + 32, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 25, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 26, 1, - 1, 27, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 1, 29, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 1, 31, - 31, 31, 31, 31, 1, 1, 1, 1, + 1, 1, 1, 1, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 31, 1, + 33, 1, 1, 1, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -170,41 +190,41 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 34, 1, 35, 1, 36, 1, 36, + 36, 36, 36, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 33, 1, 31, 31, 31, - 31, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 32, 1, 1, 1, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 1, 1, + 37, 1, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 38, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 1, 40, 40, 40, 40, + 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 40, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 33, 1, 34, 1, 35, 1, 35, - 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 36, 1, 36, 36, 36, 36, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 36, 1, 1, 1, 1, 1, 1, + 42, 1, 40, 40, 40, 40, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 37, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 1, 39, 39, 39, 39, - 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 39, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 40, + 1, 40, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 41, 1, 1, + 1, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -212,137 +232,130 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 42, 1, + 44, 45, 1, 46, 1, 46, 46, 46, + 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 41, 1, 39, 39, 39, 39, 39, 1, + 1, 1, 1, 1, 1, 1, 47, 1, + 47, 47, 47, 47, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 47, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 40, 1, 1, - 1, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 48, 1, 1, 49, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 1, 51, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 1, 53, 53, 53, + 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 41, 1, - 43, 44, 1, 45, 1, 45, 45, 45, - 45, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 46, 1, - 46, 46, 46, 46, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 46, + 1, 55, 1, 53, 53, 53, 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 47, 1, 1, 48, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 1, 50, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 1, 52, 52, 52, - 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 52, 1, 1, 1, + 1, 1, 53, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 54, 1, + 1, 1, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 55, + 1, 56, 1, 56, 56, 56, 56, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 54, 1, 52, 52, 52, 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 57, 1, 57, 57, + 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 52, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 53, 1, - 1, 1, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 58, 1, 1, 59, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 1, + 61, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 1, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 63, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 54, - 1, 55, 1, 55, 55, 55, 55, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 56, 1, 56, 56, - 56, 56, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 56, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 65, + 1, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 57, 1, 1, 58, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 1, - 60, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 1, 62, 62, 62, 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, + 63, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 64, 1, 1, 1, + 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 62, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 65, 1, 66, + 1, 67, 1, 67, 67, 67, 67, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 64, - 1, 62, 62, 62, 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 68, 1, 68, 68, + 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 62, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 63, 1, 1, 1, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 69, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 1, + 71, 71, 71, 71, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 71, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 64, 1, 65, - 1, 65, 65, 65, 65, 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 66, 1, 66, 66, 66, 66, - 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 66, 1, 67, 1, 1, + 1, 1, 1, 1, 73, 1, 71, 71, + 71, 71, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 68, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 1, 71, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 72, 70, 73, 73, 73, 73, 73, 1, + 1, 1, 1, 1, 1, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 72, 1, 1, 1, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 73, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -350,21 +363,33 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 73, 1, 75, 1, 75, 75, + 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 75, 1, - 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 76, + 1, 76, 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 76, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 78, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 1, 81, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 82, 80, 83, + 83, 83, 83, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 70, 1, 76, 76, 76, 76, - 76, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 76, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -373,67 +398,85 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 85, 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 78, 1, 76, 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 76, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 77, 1, 1, - 1, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 80, + 1, 86, 86, 86, 86, 86, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 86, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 87, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 78, 1, - 80, 1, 80, 80, 80, 80, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 88, 1, 86, + 86, 86, 86, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 81, 1, 81, 81, 81, - 81, 81, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 81, 1, 1, 1, + 1, 1, 87, 1, 1, 1, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 82, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 1, 76, - 76, 76, 76, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 76, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 77, 1, 1, 1, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 88, 1, 90, 1, 90, + 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 78, 1, 85, 85, 85, - 85, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 85, 1, 1, 1, + 91, 1, 91, 91, 91, 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 91, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 92, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 1, 86, 86, 86, 86, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 86, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 87, + 1, 1, 1, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 88, 1, 95, 95, 95, 95, 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 95, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 87, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 97, 1, + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -442,46 +485,52 @@ static const char _deserialize_json_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, - 0 + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 1, 1, 0 }; static const char _deserialize_json_trans_targs[] = { 1, 0, 2, 2, 3, 4, 18, 24, - 37, 45, 5, 12, 6, 7, 8, 9, - 11, 9, 11, 10, 2, 49, 10, 49, - 13, 14, 15, 16, 17, 16, 17, 10, - 2, 49, 19, 20, 21, 22, 23, 10, - 2, 49, 23, 25, 31, 26, 27, 28, - 29, 30, 29, 30, 10, 2, 49, 32, - 33, 34, 35, 36, 35, 36, 10, 2, - 49, 38, 39, 40, 43, 44, 40, 41, - 42, 10, 2, 49, 10, 2, 49, 44, - 46, 47, 43, 48, 48, 49, 50, 51 + 37, 43, 51, 5, 12, 6, 7, 8, + 9, 11, 9, 11, 10, 2, 55, 10, + 55, 13, 14, 15, 16, 17, 16, 17, + 10, 2, 55, 19, 20, 21, 22, 23, + 10, 2, 55, 23, 25, 31, 26, 27, + 28, 29, 30, 29, 30, 10, 2, 55, + 32, 33, 34, 35, 36, 35, 36, 10, + 2, 55, 38, 39, 40, 41, 42, 10, + 2, 55, 42, 44, 45, 46, 49, 50, + 46, 47, 48, 10, 2, 55, 10, 2, + 55, 50, 52, 53, 49, 54, 54, 55, + 56, 57 }; static const char _deserialize_json_trans_actions[] = { 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 3, 3, 4, 0, 5, - 0, 0, 2, 2, 2, 0, 0, 6, - 6, 7, 0, 0, 0, 2, 2, 8, - 8, 9, 0, 0, 0, 0, 0, 2, - 2, 2, 0, 0, 10, 10, 11, 0, - 0, 2, 2, 2, 0, 0, 12, 12, - 13, 0, 0, 2, 14, 14, 0, 15, - 0, 16, 16, 17, 18, 18, 19, 15, - 0, 0, 20, 20, 21, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 2, + 2, 2, 0, 0, 3, 3, 4, 0, + 5, 0, 0, 2, 2, 2, 0, 0, + 6, 6, 7, 0, 0, 0, 2, 2, + 8, 8, 9, 0, 0, 0, 0, 0, + 2, 2, 2, 0, 0, 10, 10, 11, + 0, 0, 2, 2, 2, 0, 0, 12, + 12, 13, 0, 0, 0, 2, 2, 14, + 14, 15, 0, 0, 0, 2, 16, 16, + 0, 17, 0, 18, 18, 19, 20, 20, + 21, 17, 0, 0, 22, 22, 23, 0, + 0, 0 }; static const int deserialize_json_start = 1; -static const int deserialize_json_first_final = 49; +static const int deserialize_json_first_final = 55; static const int deserialize_json_error = 0; static const int deserialize_json_en_main = 1; -#line 108 "hb-buffer-deserialize-json.rl" +#line 111 "hb-buffer-deserialize-json.rl" static hb_bool_t @@ -508,12 +557,12 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 512 "hb-buffer-deserialize-json.hh" +#line 554 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 517 "hb-buffer-deserialize-json.hh" +#line 557 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -561,25 +610,25 @@ _resume: tok = p; } break; - case 15: + case 17: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 21: + case 23: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 16: + case 18: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ if (!hb_font_glyph_from_string (font, - tok, p - tok, + tok+1, p - tok - 2, /* Skip "" */ &info.codepoint)) return false; } break; - case 18: + case 20: #line 66 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.codepoint)) return false; } break; @@ -604,6 +653,10 @@ _resume: { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; case 14: +#line 72 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } + break; + case 16: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -611,7 +664,7 @@ _resume: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 20: + case 22: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -619,12 +672,12 @@ _resume: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 17: + case 19: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ if (!hb_font_glyph_from_string (font, - tok, p - tok, + tok+1, p - tok - 2, /* Skip "" */ &info.codepoint)) return false; } @@ -637,7 +690,7 @@ _resume: *end_ptr = p; } break; - case 19: + case 21: #line 66 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.codepoint)) return false; } #line 43 "hb-buffer-deserialize-json.rl" @@ -709,7 +762,19 @@ _resume: *end_ptr = p; } break; -#line 713 "hb-buffer-deserialize-json.hh" + case 15: +#line 72 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 735 "hb-buffer-deserialize-json.hh" } _again: @@ -721,7 +786,7 @@ _again: _out: {} } -#line 136 "hb-buffer-deserialize-json.rl" +#line 139 "hb-buffer-deserialize-json.rl" *end_ptr = p; diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh index 06a605e225..8fbcdcc18c 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh @@ -32,29 +32,32 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text.hh" +#line 33 "hb-buffer-deserialize-text.hh" static const unsigned char _deserialize_text_trans_keys[] = { 0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 45u, 57u, - 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, - 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 9u, 124u, + 48u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, + 44u, 57u, 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, - 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 0 + 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, + 9u, 124u, 9u, 124u, 9u, 124u, 0 }; static const char _deserialize_text_key_spans[] = { 0, 83, 1, 1, 55, 77, 10, 13, - 10, 10, 13, 10, 1, 13, 10, 14, - 82, 13, 10, 116, 116, 0, 77, 116, + 10, 10, 10, 13, 10, 1, 13, 10, + 14, 82, 13, 10, 116, 116, 0, 77, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116 + 116, 116, 116 }; static const short _deserialize_text_index_offsets[] = { 0, 0, 84, 86, 88, 144, 222, 233, - 247, 258, 269, 283, 294, 296, 310, 321, - 336, 419, 433, 444, 561, 678, 679, 757, - 874, 991, 1108, 1225, 1342, 1459, 1576, 1693, - 1810, 1927, 2044, 2161, 2278 + 247, 258, 269, 280, 294, 305, 307, 321, + 332, 347, 430, 444, 455, 572, 689, 690, + 768, 885, 1002, 1119, 1236, 1353, 1470, 1587, + 1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523, + 2640, 2757, 2874 }; static const char _deserialize_text_indicies[] = { @@ -91,50 +94,52 @@ static const char _deserialize_text_indicies[] = { 12, 12, 12, 12, 12, 12, 12, 1, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 15, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 1, 17, 1, - 1, 18, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 1, 20, 21, 21, 21, + 16, 16, 16, 16, 16, 1, 17, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 1, 19, 1, 1, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 22, - 1, 23, 1, 1, 24, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 1, 26, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 1, 24, 1, 25, 1, 1, 26, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 1, 22, 1, 1, 1, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 1, 28, 28, 1, 1, 1, 1, 1, + 27, 1, 28, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 1, 24, 1, 1, + 1, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 1, 30, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 28, 1, 1, 28, 1, + 1, 1, 1, 1, 1, 1, 30, 1, + 1, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 30, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 28, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 30, 1, 31, + 1, 1, 32, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 1, 34, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 1, + 36, 36, 36, 36, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 28, 1, 29, 1, 1, 30, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 1, 32, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 1, 34, 34, 34, - 34, 34, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 36, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 34, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 1, 1, 1, 38, 39, 1, 1, + 37, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 1, 1, - 1, 36, 37, 1, 1, 35, 35, 35, - 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 35, 35, 35, - 35, 35, 35, 1, 1, 1, 1, 1, + 37, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 38, 1, 39, 39, 39, 39, 39, 1, + 1, 1, 1, 40, 1, 41, 41, 41, + 41, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 40, + 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -142,24 +147,23 @@ static const char _deserialize_text_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 41, 1, 1, - 7, 7, 7, 7, 7, 1, 1, 1, + 43, 1, 1, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 1, 42, 42, - 42, 42, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 4, + 1, 44, 44, 44, 44, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 43, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -167,68 +171,83 @@ static const char _deserialize_text_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 44, 1, 42, 42, 42, 42, 42, + 1, 1, 1, 1, 46, 1, 44, 44, + 44, 44, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 1, + 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 1, 1, 1, 1, - 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 44, 1, - 47, 47, 47, 47, 47, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 47, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 48, 1, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 49, 46, 46, 50, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 51, 52, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 53, 46, 54, 54, 54, - 54, 54, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 54, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 55, - 1, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 56, 28, 28, 57, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 58, 59, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 60, 28, 61, 61, 61, 61, 61, 1, + 1, 46, 1, 49, 49, 49, 49, 49, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 49, 48, 48, 50, 48, 48, + 48, 48, 48, 48, 48, 51, 1, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 52, + 48, 48, 53, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 54, 55, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 56, 48, + 57, 57, 57, 57, 57, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 57, + 30, 30, 58, 30, 30, 30, 30, 30, + 30, 30, 59, 1, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 60, 30, 30, 61, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 62, 63, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 64, 30, 57, 57, 57, + 57, 57, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 57, 30, 30, 58, + 30, 30, 30, 30, 30, 30, 30, 59, + 1, 30, 30, 30, 65, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 30, 30, + 30, 60, 30, 30, 61, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 62, 63, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 64, 30, 67, 67, 67, 67, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 61, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 62, 1, 1, + 1, 67, 1, 1, 68, 1, 1, 1, + 1, 1, 1, 1, 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 63, 1, + 1, 1, 1, 1, 1, 1, 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 64, 1, 65, - 65, 65, 65, 65, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 71, 1, 72, + 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 65, 1, + 1, 1, 1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -236,172 +255,238 @@ static const char _deserialize_text_indicies[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 40, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 66, 1, 67, 67, 67, 67, - 67, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 67, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 48, 1, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 49, 46, 46, 50, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 51, - 52, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 53, - 46, 68, 68, 68, 68, 68, 1, 1, + 1, 1, 73, 1, 74, 74, 74, 74, + 74, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 74, 48, 48, 50, 48, + 48, 48, 48, 48, 48, 48, 51, 1, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 52, 48, 48, 53, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 54, + 55, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 56, + 48, 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 68, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 69, 1, 1, 1, 1, + 75, 1, 1, 76, 1, 1, 1, 1, + 1, 1, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 70, 1, 1, 1, 1, 1, 1, 1, + 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 43, 1, 1, + 1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 71, 1, 72, 72, - 72, 72, 72, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 79, 1, 80, 80, + 80, 80, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 72, 1, 1, + 1, 1, 1, 1, 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 73, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 72, 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 82, 1, 80, 80, 80, 80, 80, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 72, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 73, 1, 1, - 1, 1, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 75, 1, - 68, 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 69, 1, 1, 1, 1, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 1, 1, 1, 1, 1, 1, 70, + 1, 1, 1, 1, 1, 1, 82, 1, + 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 84, + 1, 1, 85, 1, 1, 1, 1, 1, + 1, 1, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 71, 1, 77, 77, 77, - 77, 77, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 87, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 88, 1, 84, 84, 84, + 84, 84, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 84, 1, 1, 85, + 1, 1, 1, 1, 1, 1, 1, 86, + 1, 1, 1, 1, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 87, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 88, 1, 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 75, 1, 1, 76, 1, 1, 1, + 1, 1, 1, 1, 77, 1, 1, 1, + 1, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 1, 1, 1, 1, 1, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 79, 1, 77, 77, 77, 77, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 77, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 79, 1, 90, + 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 90, 1, + 1, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 79, 1, 61, - 61, 61, 61, 61, 1, 1, 1, 1, + 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 61, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 62, 1, 1, 1, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 93, 1, 90, 90, 90, 90, + 90, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 90, 1, 1, 91, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 63, 1, 1, 1, 1, + 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 93, + 1, 67, 67, 67, 67, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 1, 0 + 1, 1, 1, 1, 1, 1, 1, 1, + 67, 1, 1, 68, 1, 1, 1, 1, + 1, 1, 1, 1, 69, 1, 1, 1, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 70, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 71, 1, 94, 94, + 94, 94, 94, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 94, 30, 30, + 58, 30, 30, 30, 30, 30, 30, 30, + 59, 1, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 60, 30, 30, 61, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 62, 95, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 96, 30, 94, 94, 94, 94, 94, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 94, 30, 30, 58, 30, 30, + 30, 30, 30, 30, 30, 59, 1, 30, + 30, 30, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 30, 30, 30, 60, + 30, 30, 61, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 62, 95, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 96, 30, + 0 }; static const char _deserialize_text_trans_targs[] = { - 1, 0, 2, 25, 3, 4, 19, 5, - 23, 24, 8, 27, 36, 27, 36, 30, - 33, 11, 12, 15, 12, 15, 13, 14, - 31, 32, 31, 32, 26, 18, 34, 35, - 34, 35, 20, 19, 6, 21, 22, 20, - 21, 22, 20, 21, 22, 24, 26, 26, - 7, 9, 10, 16, 21, 29, 26, 7, - 9, 10, 16, 21, 29, 28, 17, 21, - 29, 28, 29, 29, 28, 7, 10, 29, - 28, 7, 21, 29, 33, 28, 21, 29 + 1, 0, 2, 26, 3, 4, 20, 5, + 24, 25, 8, 29, 40, 29, 40, 32, + 37, 33, 34, 12, 13, 16, 13, 16, + 14, 15, 35, 36, 35, 36, 27, 19, + 38, 39, 38, 39, 21, 20, 6, 22, + 23, 21, 22, 23, 21, 22, 23, 25, + 27, 27, 28, 7, 9, 11, 17, 22, + 31, 27, 28, 7, 9, 11, 17, 22, + 31, 41, 42, 30, 10, 18, 22, 31, + 30, 31, 31, 30, 10, 7, 11, 31, + 30, 22, 31, 34, 30, 10, 7, 22, + 31, 37, 30, 10, 22, 31, 27, 22, + 31, 42 }; static const char _deserialize_text_trans_actions[] = { 0, 0, 0, 0, 1, 0, 2, 0, 2, 2, 3, 4, 4, 5, 5, 4, - 4, 3, 3, 3, 0, 0, 6, 3, - 4, 4, 5, 5, 5, 3, 4, 4, - 5, 5, 7, 8, 9, 7, 7, 0, - 0, 0, 10, 10, 10, 8, 12, 13, - 14, 14, 14, 15, 11, 11, 17, 18, - 18, 18, 0, 16, 16, 19, 20, 19, - 19, 0, 0, 13, 10, 21, 21, 10, - 22, 23, 22, 22, 5, 24, 24, 24 + 4, 4, 4, 3, 3, 3, 0, 0, + 6, 3, 4, 4, 5, 5, 5, 3, + 4, 4, 5, 5, 7, 8, 9, 7, + 7, 0, 0, 0, 10, 10, 10, 8, + 12, 13, 14, 15, 15, 15, 16, 11, + 11, 18, 19, 20, 20, 20, 0, 17, + 17, 4, 4, 21, 22, 22, 21, 21, + 0, 0, 13, 10, 23, 23, 23, 10, + 24, 24, 24, 5, 25, 26, 26, 25, + 25, 5, 27, 28, 27, 27, 30, 29, + 29, 5 }; static const char _deserialize_text_eof_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 0, 10, - 10, 11, 16, 19, 0, 11, 10, 22, - 22, 10, 24, 24, 19 + 0, 0, 0, 0, 7, 0, 0, 0, + 10, 10, 11, 17, 17, 21, 0, 11, + 10, 24, 24, 25, 25, 10, 27, 27, + 21, 29, 29 }; static const int deserialize_text_start = 1; -static const int deserialize_text_first_final = 19; +static const int deserialize_text_first_final = 20; static const int deserialize_text_error = 0; static const int deserialize_text_en_main = 1; -#line 114 "hb-buffer-deserialize-text.rl" +#line 117 "hb-buffer-deserialize-text.rl" static hb_bool_t @@ -424,12 +509,12 @@ _hb_buffer_deserialize_text (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 428 "hb-buffer-deserialize-text.hh" +#line 506 "hb-buffer-deserialize-text.hh" { cs = deserialize_text_start; } -#line 433 "hb-buffer-deserialize-text.hh" +#line 509 "hb-buffer-deserialize-text.hh" { int _slen; int _trans; @@ -475,7 +560,7 @@ _resume: #line 56 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 18: + case 20: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -489,7 +574,7 @@ _resume: #line 66 "hb-buffer-deserialize-text.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } break; - case 21: + case 23: #line 68 "hb-buffer-deserialize-text.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; @@ -497,15 +582,19 @@ _resume: #line 69 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; - case 23: + case 26: #line 70 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 20: + case 22: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 15: + case 28: +#line 72 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } + break; + case 16: #line 38 "hb-buffer-deserialize-text.rl" { memset (&info, 0, sizeof (info)); @@ -532,7 +621,7 @@ _resume: #line 56 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 16: + case 17: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -550,6 +639,18 @@ _resume: *end_ptr = p; } break; + case 19: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 55 "hb-buffer-deserialize-text.rl" + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; case 7: #line 66 "hb-buffer-deserialize-text.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } @@ -574,7 +675,7 @@ _resume: *end_ptr = p; } break; - case 22: + case 25: #line 70 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -586,7 +687,7 @@ _resume: *end_ptr = p; } break; - case 19: + case 21: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -598,7 +699,7 @@ _resume: *end_ptr = p; } break; - case 24: + case 27: #line 72 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -610,6 +711,18 @@ _resume: *end_ptr = p; } break; + case 24: +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; case 12: #line 38 "hb-buffer-deserialize-text.rl" { @@ -623,7 +736,7 @@ _resume: #line 55 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 14: + case 15: #line 38 "hb-buffer-deserialize-text.rl" { memset (&info, 0, sizeof (info)); @@ -642,7 +755,7 @@ _resume: return false; } break; - case 17: + case 18: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -662,6 +775,26 @@ _resume: *end_ptr = p; } break; + case 29: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; case 11: #line 38 "hb-buffer-deserialize-text.rl" { @@ -689,6 +822,49 @@ _resume: *end_ptr = p; } break; + case 14: +#line 38 "hb-buffer-deserialize-text.rl" + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text.rl" + { + tok = p; +} +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 55 "hb-buffer-deserialize-text.rl" + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; + case 30: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 55 "hb-buffer-deserialize-text.rl" + { if (unlikely (!buffer->ensure_glyphs ())) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; case 13: #line 38 "hb-buffer-deserialize-text.rl" { @@ -718,7 +894,7 @@ _resume: *end_ptr = p; } break; -#line 722 "hb-buffer-deserialize-text.hh" +#line 826 "hb-buffer-deserialize-text.hh" } _again: @@ -730,7 +906,7 @@ _again: if ( p == eof ) { switch ( _deserialize_text_eof_actions[cs] ) { - case 16: + case 17: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -772,7 +948,7 @@ _again: *end_ptr = p; } break; - case 22: + case 25: #line 70 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -784,7 +960,7 @@ _again: *end_ptr = p; } break; - case 19: + case 21: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -796,7 +972,7 @@ _again: *end_ptr = p; } break; - case 24: + case 27: #line 72 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -808,6 +984,38 @@ _again: *end_ptr = p; } break; + case 24: +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 29: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; case 11: #line 38 "hb-buffer-deserialize-text.rl" { @@ -835,14 +1043,14 @@ _again: *end_ptr = p; } break; -#line 839 "hb-buffer-deserialize-text.hh" +#line 953 "hb-buffer-deserialize-text.hh" } } _out: {} } -#line 138 "hb-buffer-deserialize-text.rl" +#line 141 "hb-buffer-deserialize-text.rl" *end_ptr = p; diff --git a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc index 3f619a113e..d1e1775430 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc +++ b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc @@ -56,7 +56,7 @@ hb_buffer_serialize_list_formats () /** * hb_buffer_serialize_format_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * * Parses a string into an #hb_buffer_serialize_format_t. Does not check if * @str is a valid buffer serialization format, use @@ -78,11 +78,11 @@ hb_buffer_serialize_format_from_string (const char *str, int len) * hb_buffer_serialize_format_to_string: * @format: an #hb_buffer_serialize_format_t to convert. * - * Converts @format to the string corresponding it, or %NULL if it is not a valid + * Converts @format to the string corresponding it, or `NULL` if it is not a valid * #hb_buffer_serialize_format_t. * * Return value: (transfer none): - * A %NULL terminated string corresponding to @format. Should not be freed. + * A `NULL` terminated string corresponding to @format. Should not be freed. * * Since: 0.9.7 **/ @@ -400,9 +400,9 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @font: (nullable): the #hb_font_t used to shape this buffer, needed to - * read glyph names and extents. If %NULL, an empty font will be used. + * read glyph names and extents. If `NULL`, an empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -514,7 +514,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -637,9 +637,9 @@ _hb_buffer_serialize_invalid (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @font: (nullable): the #hb_font_t used to shape this buffer, needed to - * read glyph names and extents. If %NULL, an empty font will be used. + * read glyph names and extents. If `NULL`, an empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -727,7 +727,7 @@ parse_hex (const char *pp, const char *end, uint32_t *pv) * hb_buffer_deserialize_glyphs: * @buffer: an #hb_buffer_t buffer. * @buf: (array length=buf_len): string to deserialize - * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @buf_len: the size of @buf, or -1 if it is `NULL`-terminated * @end_ptr: (out) (optional): output pointer to the character after last * consumed one. * @font: (nullable): font for getting glyph IDs @@ -736,7 +736,7 @@ parse_hex (const char *pp, const char *end, uint32_t *pv) * Deserializes glyphs @buffer from textual representation in the format * produced by hb_buffer_serialize_glyphs(). * - * Return value: %true if @buf is not fully consumed, %false otherwise. + * Return value: `true` if @buf is not fully consumed, `false` otherwise. * * Since: 0.9.7 **/ @@ -800,7 +800,7 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, * hb_buffer_deserialize_unicode: * @buffer: an #hb_buffer_t buffer. * @buf: (array length=buf_len): string to deserialize - * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @buf_len: the size of @buf, or -1 if it is `NULL`-terminated * @end_ptr: (out) (optional): output pointer to the character after last * consumed one. * @format: the #hb_buffer_serialize_format_t of the input @buf @@ -808,7 +808,7 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, * Deserializes Unicode @buffer from textual representation in the format * produced by hb_buffer_serialize_unicode(). * - * Return value: %true if @buf is not fully consumed, %false otherwise. + * Return value: `true` if @buf is not fully consumed, `false` otherwise. * * Since: 2.7.3 **/ diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index 2272ecf09b..fddda23304 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -51,7 +51,7 @@ * Checks the equality of two #hb_segment_properties_t's. * * Return value: - * %true if all properties of @a equal those of @b, %false otherwise. + * `true` if all properties of @a equal those of @b, `false` otherwise. * * Since: 0.9.7 **/ @@ -643,9 +643,9 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = * Return value: (transfer full): * A newly allocated #hb_buffer_t with a reference count of 1. The initial * reference count should be released with hb_buffer_destroy() when you are done - * using the #hb_buffer_t. This function never returns %NULL. If memory cannot + * using the #hb_buffer_t. This function never returns `NULL`. If memory cannot * be allocated, a special #hb_buffer_t object will be returned on which - * hb_buffer_allocation_successful() returns %false. + * hb_buffer_allocation_successful() returns `false`. * * Since: 0.9.2 **/ @@ -775,7 +775,7 @@ hb_buffer_destroy (hb_buffer_t *buffer) * * Attaches a user-data key/data pair to the specified buffer. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -1278,7 +1278,7 @@ hb_buffer_clear_contents (hb_buffer_t *buffer) * Pre allocates memory for @buffer to fit at least @size number of items. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise + * `true` if @buffer memory allocation succeeded, `false` otherwise * * Since: 0.9.2 **/ @@ -1295,7 +1295,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) * Check if allocating memory for the buffer succeeded. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise. + * `true` if @buffer memory allocation succeeded, `false` otherwise. * * Since: 0.9.2 **/ @@ -1340,7 +1340,7 @@ hb_buffer_add (hb_buffer_t *buffer, * end. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise. + * `true` if @buffer memory allocation succeeded, `false` otherwise. * * Since: 0.9.2 **/ @@ -1426,7 +1426,7 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer, * If buffer did not have positions before, the positions will be * initialized to zeros, unless this function is called from * within a buffer message callback (see hb_buffer_set_message_func()), - * in which case %NULL is returned. + * in which case `NULL` is returned. * * Return value: (transfer none) (array length=length): * The @buffer glyph position array. @@ -1461,7 +1461,7 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer, * and cleared of position data when hb_buffer_clear_contents() is called. * * Return value: - * %true if the @buffer has position array, %false otherwise. + * `true` if the @buffer has position array, `false` otherwise. * * Since: 2.7.3 **/ @@ -1645,10 +1645,10 @@ hb_buffer_add_utf (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * @text: (array length=text_length) (element-type uint8_t): An array of UTF-8 * characters to append. - * @text_length: The length of the @text, or -1 if it is %NULL terminated. + * @text_length: The length of the @text, or -1 if it is `NULL` terminated. * @item_offset: The offset of the first character to add to the @buffer. * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * end of @text (assuming it is `NULL` terminated). * * See hb_buffer_add_codepoints(). * @@ -1671,10 +1671,10 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer, * hb_buffer_add_utf16: * @buffer: An #hb_buffer_t * @text: (array length=text_length): An array of UTF-16 characters to append - * @text_length: The length of the @text, or -1 if it is %NULL terminated + * @text_length: The length of the @text, or -1 if it is `NULL` terminated * @item_offset: The offset of the first character to add to the @buffer * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * See hb_buffer_add_codepoints(). * @@ -1697,10 +1697,10 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer, * hb_buffer_add_utf32: * @buffer: An #hb_buffer_t * @text: (array length=text_length): An array of UTF-32 characters to append - * @text_length: The length of the @text, or -1 if it is %NULL terminated + * @text_length: The length of the @text, or -1 if it is `NULL` terminated * @item_offset: The offset of the first character to add to the @buffer * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * See hb_buffer_add_codepoints(). * @@ -1724,10 +1724,10 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 * characters to append - * @text_length: the length of the @text, or -1 if it is %NULL terminated + * @text_length: the length of the @text, or -1 if it is `NULL` terminated * @item_offset: the offset of the first character to add to the @buffer * @item_length: the number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * Similar to hb_buffer_add_codepoints(), but allows only access to first 256 * Unicode code points that can fit in 8-bit strings. @@ -1750,10 +1750,10 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer, * hb_buffer_add_codepoints: * @buffer: a #hb_buffer_t to append characters to. * @text: (array length=text_length): an array of Unicode code points to append. - * @text_length: the length of the @text, or -1 if it is %NULL terminated. + * @text_length: the length of the @text, or -1 if it is `NULL` terminated. * @item_offset: the offset of the first code point to add to the @buffer. * @item_length: the number of code points to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * end of @text (assuming it is `NULL` terminated). * * Appends characters from @text array to @buffer. The @item_offset is the * position of the first character from @text that will be appended, and diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h index 22fb3496f2..e095c5344c 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.h +++ b/thirdparty/harfbuzz/src/hb-buffer.h @@ -755,16 +755,16 @@ hb_buffer_diff (hb_buffer_t *buffer, * hb_buffer_message_func_t: * @buffer: An #hb_buffer_t to work upon * @font: The #hb_font_t the @buffer is shaped with - * @message: %NULL-terminated message passed to the function + * @message: `NULL`-terminated message passed to the function * @user_data: User data pointer passed by the caller * * A callback method for #hb_buffer_t. The method gets called with the * #hb_buffer_t it was set on, the #hb_font_t the buffer is shaped with and a * message describing what step of the shaping process will be performed. - * Returning %false from this method will skip this shaping step and move to + * Returning `false` from this method will skip this shaping step and move to * the next one. * - * Return value: %true to perform the shaping step, %false to skip it. + * Return value: `true` to perform the shaping step, `false` to skip it. * * Since: 1.1.3 */ diff --git a/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh b/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh index 2983ae54a1..f93c83ab45 100644 --- a/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh +++ b/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh @@ -57,6 +57,7 @@ struct call_context_t /* call stack */ const unsigned int kMaxCallLimit = 10; +const unsigned int kMaxOps = 10000; struct call_stack_t : cff_stack_t<call_context_t, kMaxCallLimit> {}; template <typename SUBRS> @@ -881,7 +882,13 @@ struct cs_interpreter_t : interpreter_t<ENV> { SUPER::env.set_endchar (false); + unsigned max_ops = kMaxOps; for (;;) { + if (unlikely (!--max_ops)) + { + SUPER::env.set_error (); + break; + } OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param); if (unlikely (SUPER::env.in_error ())) return false; diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc index 7266d9b01f..e6512872e8 100644 --- a/thirdparty/harfbuzz/src/hb-common.cc +++ b/thirdparty/harfbuzz/src/hb-common.cc @@ -108,7 +108,7 @@ _hb_options_init () /** * hb_tag_from_string: * @str: (array length=len) (element-type uint8_t): String to convert - * @len: Length of @str, or -1 if it is %NULL-terminated + * @len: Length of @str, or -1 if it is `NULL`-terminated * * Converts a string into an #hb_tag_t. Valid tags * are four characters. Shorter input strings will be @@ -170,7 +170,7 @@ static const char direction_strings[][4] = { /** * hb_direction_from_string: * @str: (array length=len) (element-type uint8_t): String to convert - * @len: Length of @str, or -1 if it is %NULL-terminated + * @len: Length of @str, or -1 if it is `NULL`-terminated * * Converts a string to an #hb_direction_t. * @@ -357,7 +357,7 @@ retry: * hb_language_from_string: * @str: (array length=len) (element-type uint8_t): a string representing * a BCP 47 language tag - * @len: length of the @str, or -1 if it is %NULL-terminated. + * @len: length of the @str, or -1 if it is `NULL`-terminated. * * Converts @str representing a BCP 47 language tag to the corresponding * #hb_language_t. @@ -396,7 +396,7 @@ hb_language_from_string (const char *str, int len) * Converts an #hb_language_t to a string. * * Return value: (transfer none): - * A %NULL-terminated string representing the @language. Must not be freed by + * A `NULL`-terminated string representing the @language. Must not be freed by * the caller. * * Since: 0.9.2 @@ -441,6 +441,38 @@ hb_language_get_default () return language; } +/** + * hb_language_matches: + * @language: The #hb_language_t to work on + * @specific: Another #hb_language_t + * + * Check whether a second language tag is the same or a more + * specific version of the provided language tag. For example, + * "fa_IR.utf8" is a more specific tag for "fa" or for "fa_IR". + * + * Return value: `true` if languages match, `false` otherwise. + * + * Since: 5.0.0 + **/ +hb_bool_t +hb_language_matches (hb_language_t language, + hb_language_t specific) +{ + if (language == specific) return true; + if (!language || !specific) return false; + + const char *l = language->s; + const char *s = specific->s; + unsigned ll = strlen (l); + unsigned sl = strlen (s); + + if (ll > sl) + return false; + + return strncmp (l, s, ll) == 0 && + (s[ll] == '\0' || s[ll] == '-'); +} + /* hb_script_t */ @@ -498,7 +530,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag) * hb_script_from_string: * @str: (array length=len) (element-type uint8_t): a string representing an * ISO 15924 tag. - * @len: length of the @str, or -1 if it is %NULL-terminated. + * @len: length of the @str, or -1 if it is `NULL`-terminated. * * Converts a string @str representing an ISO 15924 script tag to a * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then @@ -693,8 +725,8 @@ hb_version_string () * Tests the library version against a minimum value, * as three integer components. * - * Return value: %true if the library is equal to or greater than - * the test value, %false otherwise + * Return value: `true` if the library is equal to or greater than + * the test value, `false` otherwise * * Since: 0.9.30 **/ @@ -881,7 +913,7 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) /** * hb_feature_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * @feature: (out): the #hb_feature_t to initialize with the parsed values * * Parses a string into a #hb_feature_t. @@ -923,7 +955,7 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) * </informaltable> * * Return value: - * %true if @str is successfully parsed, %false otherwise + * `true` if @str is successfully parsed, `false` otherwise * * Since: 0.9.5 **/ @@ -954,7 +986,7 @@ hb_feature_from_string (const char *str, int len, * @buf: (array length=size) (out): output string * @size: the allocated size of @buf * - * Converts a #hb_feature_t into a %NULL-terminated string in the format + * Converts a #hb_feature_t into a `NULL`-terminated string in the format * understood by hb_feature_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * @@ -1022,7 +1054,7 @@ parse_one_variation (const char **pp, const char *end, hb_variation_t *variation /** * hb_variation_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * @variation: (out): the #hb_variation_t to initialize with the parsed values * * Parses a string into a #hb_variation_t. @@ -1035,7 +1067,7 @@ parse_one_variation (const char **pp, const char *end, hb_variation_t *variation * number. For example `wght=500`, or `slnt=-7.5`. * * Return value: - * %true if @str is successfully parsed, %false otherwise + * `true` if @str is successfully parsed, `false` otherwise * * Since: 1.4.2 */ @@ -1107,7 +1139,7 @@ get_C_locale () * @buf: (array length=size) (out): output string * @size: the allocated size of @buf * - * Converts an #hb_variation_t into a %NULL-terminated string in the format + * Converts an #hb_variation_t into a `NULL`-terminated string in the format * understood by hb_variation_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * diff --git a/thirdparty/harfbuzz/src/hb-common.h b/thirdparty/harfbuzz/src/hb-common.h index 7b897a6c51..7c7ad87c7c 100644 --- a/thirdparty/harfbuzz/src/hb-common.h +++ b/thirdparty/harfbuzz/src/hb-common.h @@ -326,6 +326,9 @@ hb_language_to_string (hb_language_t language); HB_EXTERN hb_language_t hb_language_get_default (void); +HB_EXTERN hb_bool_t +hb_language_matches (hb_language_t language, + hb_language_t specific); /** * hb_script_t: diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh index 2578231d23..db8ec0e908 100644 --- a/thirdparty/harfbuzz/src/hb-config.hh +++ b/thirdparty/harfbuzz/src/hb-config.hh @@ -98,6 +98,11 @@ /* Closure of options. */ +#ifdef HB_NO_BORING_EXPANSION +#define HB_NO_BEYOND_64K +#define HB_NO_VARIATIONS2 +#endif + #ifdef HB_DISABLE_DEPRECATED #define HB_IF_NOT_DEPRECATED(x) #else diff --git a/thirdparty/harfbuzz/src/hb-cplusplus.hh b/thirdparty/harfbuzz/src/hb-cplusplus.hh index 86d0452080..f06a32d912 100644 --- a/thirdparty/harfbuzz/src/hb-cplusplus.hh +++ b/thirdparty/harfbuzz/src/hb-cplusplus.hh @@ -166,8 +166,14 @@ HB_DEFINE_VTABLE (unicode_funcs); } // namespace hb +/* Workaround for GCC < 7, see: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480 + * https://stackoverflow.com/a/25594741 */ +namespace std { + + template<typename T> -struct std::hash<hb::shared_ptr<T>> +struct hash<hb::shared_ptr<T>> { std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept { @@ -177,7 +183,7 @@ struct std::hash<hb::shared_ptr<T>> }; template<typename T> -struct std::hash<hb::unique_ptr<T>> +struct hash<hb::unique_ptr<T>> { std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept { @@ -187,6 +193,8 @@ struct std::hash<hb::unique_ptr<T>> }; +} // namespace std + #endif /* __cplusplus */ #endif /* HB_CPLUSPLUS_HH */ diff --git a/thirdparty/harfbuzz/src/hb-deprecated.h b/thirdparty/harfbuzz/src/hb-deprecated.h index a130d77f77..333dc3cd4c 100644 --- a/thirdparty/harfbuzz/src/hb-deprecated.h +++ b/thirdparty/harfbuzz/src/hb-deprecated.h @@ -93,7 +93,7 @@ HB_BEGIN_DECLS * This method should retrieve the glyph ID for a specified Unicode code point * font, with an optional variation selector. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * Deprecated: 1.2.3 * **/ diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc index ce04f5bab1..de05b7d871 100644 --- a/thirdparty/harfbuzz/src/hb-directwrite.cc +++ b/thirdparty/harfbuzz/src/hb-directwrite.cc @@ -43,6 +43,14 @@ * Functions for using HarfBuzz with DirectWrite fonts. **/ +/* Declare object creator for dynamic support of DWRITE */ +typedef HRESULT (WINAPI *t_DWriteCreateFactory)( + DWRITE_FACTORY_TYPE factoryType, + REFIID iid, + IUnknown **factory +); + + /* * DirectWrite font stream helpers */ @@ -137,6 +145,7 @@ public: struct hb_directwrite_face_data_t { + HMODULE dwrite_dll; IDWriteFactory *dwriteFactory; IDWriteFontFile *fontFile; DWriteFontFileStream *fontFileStream; @@ -158,12 +167,33 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) return nullptr; \ } HB_STMT_END + data->dwrite_dll = LoadLibrary (TEXT ("DWRITE")); + if (unlikely (!data->dwrite_dll)) + FAIL ("Cannot find DWrite.DLL"); + + t_DWriteCreateFactory p_DWriteCreateFactory; + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + + p_DWriteCreateFactory = (t_DWriteCreateFactory) + GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + + if (unlikely (!p_DWriteCreateFactory)) + FAIL ("Cannot find DWriteCreateFactory()."); + HRESULT hr; // TODO: factory and fontFileLoader should be cached separately IDWriteFactory* dwriteFactory; - hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); + hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory); if (unlikely (hr != S_OK)) FAIL ("Failed to run DWriteCreateFactory()."); @@ -227,6 +257,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) delete data->fontFileStream; if (data->faceBlob) hb_blob_destroy (data->faceBlob); + if (data->dwrite_dll) + FreeLibrary (data->dwrite_dll); if (data) delete data; } diff --git a/thirdparty/harfbuzz/src/hb-draw.cc b/thirdparty/harfbuzz/src/hb-draw.cc index fdc71102d6..46797e64e6 100644 --- a/thirdparty/harfbuzz/src/hb-draw.cc +++ b/thirdparty/harfbuzz/src/hb-draw.cc @@ -120,6 +120,7 @@ hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \ if (dfuncs->destroy) \ dfuncs->destroy->name = nullptr; \ } \ + return; \ \ fail: \ if (destroy) \ @@ -137,7 +138,7 @@ HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS * Return value: (transfer full): * A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial * reference count should be released with hb_draw_funcs_destroy when you are - * done using the #hb_draw_funcs_t. This function never returns %NULL. If + * done using the #hb_draw_funcs_t. This function never returns `NULL`. If * memory cannot be allocated, a special singleton #hb_draw_funcs_t object will * be returned. * @@ -208,6 +209,9 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs) #undef HB_DRAW_FUNC_IMPLEMENT } + hb_free (dfuncs->destroy); + hb_free (dfuncs->user_data); + hb_free (dfuncs); } @@ -234,7 +238,7 @@ hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs) * * Checks whether @dfuncs is immutable. * - * Return value: %true if @dfuncs is immutable, %false otherwise + * Return value: `true` if @dfuncs is immutable, `false` otherwise * * Since: 4.0.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc index 7cdd6cb49f..8f8b1a6d14 100644 --- a/thirdparty/harfbuzz/src/hb-face.cc +++ b/thirdparty/harfbuzz/src/hb-face.cc @@ -315,7 +315,7 @@ hb_face_destroy (hb_face_t *face) * * Attaches a user-data key/data pair to the given face object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -371,7 +371,7 @@ hb_face_make_immutable (hb_face_t *face) * * Tests whether the given face object is immutable. * - * Return value: %true is @face is immutable, %false otherwise + * Return value: `true` is @face is immutable, `false` otherwise * * Since: 0.9.2 **/ diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc index 8c4fe863b6..fd9073c33e 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -754,7 +754,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) * * Attaches a user-data key/data pair to the specified font-functions structure. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -811,7 +811,7 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) * * Tests whether a font-functions structure is immutable. * - * Return value: %true if @ffuncs is immutable, %false otherwise + * Return value: `true` if @ffuncs is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -903,7 +903,7 @@ hb_font_t::has_func (unsigned int i) * Fetches the extents for a specified font, for horizontal * text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.1.3 **/ @@ -922,7 +922,7 @@ hb_font_get_h_extents (hb_font_t *font, * Fetches the extents for a specified font, for vertical * text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.1.3 **/ @@ -946,7 +946,7 @@ hb_font_get_v_extents (hb_font_t *font, * If @variation_selector is 0, calls hb_font_get_nominal_glyph(); * otherwise calls hb_font_get_variation_glyph(). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -974,7 +974,7 @@ hb_font_get_glyph (hb_font_t *font, * for code points modified by variation selectors. For variation-selector * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph(). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.2.3 **/ @@ -1026,7 +1026,7 @@ hb_font_get_nominal_glyphs (hb_font_t *font, * by the specified variation-selector code point, in the specified * font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.2.3 **/ @@ -1136,7 +1136,7 @@ hb_font_get_glyph_v_advances (hb_font_t* font, * Fetches the (X,Y) coordinates of the origin for a glyph ID * in the specified font, for horizontal text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1159,7 +1159,7 @@ hb_font_get_glyph_h_origin (hb_font_t *font, * Fetches the (X,Y) coordinates of the origin for a glyph ID * in the specified font, for vertical text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1232,7 +1232,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font, * Fetches the #hb_glyph_extents_t data for a glyph ID * in the specified font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1255,7 +1255,7 @@ hb_font_get_glyph_extents (hb_font_t *font, * Fetches the (x,y) coordinates of a specified contour-point index * in the specified glyph, within the specified font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1278,7 +1278,7 @@ hb_font_get_glyph_contour_point (hb_font_t *font, * * Fetches the glyph-name string for a glyph ID in the specified @font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1302,7 +1302,7 @@ hb_font_get_glyph_name (hb_font_t *font, * * <note>Note: @len == -1 means the name string is null-terminated.</note> * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1537,7 +1537,7 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, * Calls the appropriate direction-specific variant (horizontal * or vertical) depending on the value of @direction. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1566,7 +1566,7 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font, * Calls the appropriate direction-specific variant (horizontal * or vertical) depending on the value of @direction. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1617,7 +1617,7 @@ hb_font_glyph_to_string (hb_font_t *font, * * <note>Note: @len == -1 means the string is null-terminated.</note> * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1675,6 +1675,7 @@ _hb_font_create (hb_face_t *face) if (unlikely (!face)) face = hb_face_get_empty (); + if (!(font = hb_object_create<hb_font_t> ())) return hb_font_get_empty (); @@ -1866,7 +1867,7 @@ hb_font_destroy (hb_font_t *font) * * Attaches a user-data key/data pair to the specified font object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -1928,7 +1929,7 @@ hb_font_make_immutable (hb_font_t *font) * * Tests whether a font object is immutable. * - * Return value: %true if @font is immutable, %false otherwise + * Return value: `true` if @font is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -1948,7 +1949,7 @@ hb_font_is_immutable (hb_font_t *font) * * Return value: serial number * - * Since: 4.4.0. + * Since: 4.4.0 **/ unsigned int hb_font_get_serial (hb_font_t *font) @@ -1964,7 +1965,7 @@ hb_font_get_serial (hb_font_t *font) * This has the effect of increasing the serial as returned * by hb_font_get_serial(), which invalidates internal caches. * - * Since: 4.4.0. + * Since: 4.4.0 **/ void hb_font_changed (hb_font_t *font) @@ -2386,6 +2387,10 @@ hb_font_set_variations (hb_font_t *font, return; } + /* Initialize design coords to default from fvar. */ + for (unsigned int i = 0; i < coords_length; i++) + design_coords[i] = axes[i].get_default (); + for (unsigned int i = 0; i < variations_length; i++) { const auto tag = variations[i].tag; diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h index ca6ecf7963..3f27bca288 100644 --- a/thirdparty/harfbuzz/src/hb-font.h +++ b/thirdparty/harfbuzz/src/hb-font.h @@ -198,7 +198,7 @@ typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t; * This method should retrieve the nominal glyph ID for a specified Unicode code * point. Glyph IDs must be returned in a #hb_codepoint_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data, @@ -221,7 +221,7 @@ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *fo * followed by a specified Variation Selector code point. Glyph IDs must be * returned in a #hb_codepoint_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data, @@ -362,7 +362,7 @@ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t; * origin for a glyph. Each coordinate must be returned in an #hb_position_t * output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data, @@ -434,7 +434,7 @@ typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t; * This method should retrieve the extents for a specified glyph. Extents must be * returned in an #hb_glyph_extents output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data, @@ -458,7 +458,7 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo * specified contour point in a glyph. Each coordinate must be returned as * an #hb_position_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data, @@ -481,7 +481,7 @@ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, vo * This method should retrieve the glyph name that corresponds to a * glyph ID. The name should be returned in a string output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data, @@ -503,7 +503,7 @@ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_ * This method should retrieve the glyph ID that corresponds to a glyph-name * string. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data, diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index b526a82865..5c88a7f3bd 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -136,32 +136,56 @@ _hb_ft_font_destroy (void *data) /* hb_font changed, update FT_Face. */ static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face) { + float x_mult = 1.f, y_mult = 1.f; - FT_Set_Char_Size (ft_face, - abs (font->x_scale), abs (font->y_scale), - 0, 0); + if (font->x_scale < 0) x_mult = -x_mult; + if (font->y_scale < 0) y_mult = -y_mult; + + if (FT_Set_Char_Size (ft_face, + abs (font->x_scale), abs (font->y_scale), + 0, 0 #if 0 font->x_ppem * 72 * 64 / font->x_scale, - font->y_ppem * 72 * 64 / font->y_scale); + font->y_ppem * 72 * 64 / font->y_scale +#endif + ) && ft_face->num_fixed_sizes) + { +#ifdef HAVE_FT_GET_TRANSFORM + /* Bitmap font, eg. bitmap color emoji. */ + /* TODO Pick largest size? */ + int x_scale = ft_face->available_sizes[0].x_ppem; + int y_scale = ft_face->available_sizes[0].y_ppem; + FT_Set_Char_Size (ft_face, + x_scale, y_scale, + 0, 0); + + /* This contains the sign that was previously in x_mult/y_mult. */ + x_mult = (float) font->x_scale / x_scale; + y_mult = (float) font->y_scale / y_scale; #endif - if (font->x_scale < 0 || font->y_scale < 0) + } + else + { /* Shrug */ } + + + if (x_mult != 1.f || y_mult != 1.f) { - FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, - 0, font->y_scale < 0 ? -1 : +1}; + FT_Matrix matrix = { (int) roundf (x_mult * (1<<16)), 0, + 0, (int) roundf (y_mult * (1<<16))}; FT_Set_Transform (ft_face, &matrix, nullptr); } #if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) unsigned int num_coords; - const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); + const float *coords = hb_font_get_var_coords_design (font, &num_coords); if (num_coords) { FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); if (ft_coords) { for (unsigned int i = 0; i < num_coords; i++) - ft_coords[i] = coords[i] * 4; - FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); + ft_coords[i] = coords[i] * 65536.f; + FT_Set_Var_Design_Coordinates (ft_face, num_coords, ft_coords); hb_free (ft_coords); } } @@ -241,7 +265,7 @@ hb_ft_font_get_load_flags (hb_font_t *font) * Fetches the FT_Face associated with the specified #hb_font_t * font object. * - * Return value: (nullable): the FT_Face found or %NULL + * Return value: (nullable): the FT_Face found or `NULL` * * Since: 0.9.2 **/ @@ -263,7 +287,7 @@ hb_ft_font_get_face (hb_font_t *font) * Gets the FT_Face associated with @font, This face will be kept around until * you call hb_ft_font_unlock_face(). * - * Return value: (nullable): the FT_Face associated with @font or %NULL + * Return value: (nullable) (transfer none): the FT_Face associated with @font or `NULL` * Since: 2.6.5 **/ FT_Face @@ -280,7 +304,7 @@ hb_ft_font_lock_face (hb_font_t *font) } /** - * hb_ft_font_unlock_face: + * hb_ft_font_unlock_face: (skip) * @font: #hb_font_t to work upon * * Releases an FT_Face previously obtained with hb_ft_font_lock_face(). @@ -404,7 +428,13 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; int load_flags = ft_font->load_flags; - int mult = font->x_scale < 0 ? -1 : +1; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + float mult = matrix.xx / 65536.f; +#else + float mult = font->x_scale < 0 ? -1 : +1; +#endif for (unsigned int i = 0; i < count; i++) { @@ -420,7 +450,7 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, ft_font->advance_cache.set (glyph, v); } - *first_advance = (v * mult + (1<<9)) >> 10; + *first_advance = (int) (v * mult + (1<<9)) >> 10; first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } @@ -436,12 +466,18 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Fixed v; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_font->ft_face, &matrix, nullptr); + float y_mult = matrix.yy / 65536.f; +#else + float y_mult = font->y_scale < 0 ? -1 : +1; +#endif if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) return 0; - if (font->y_scale < 0) - v = -v; + v = (int) (y_mult * v); /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates * have a Y growing upward. Hence the extra negation. */ @@ -462,6 +498,15 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + float x_mult = matrix.xx / 65536.f; + float y_mult = matrix.yy / 65536.f; +#else + float x_mult = font->x_scale < 0 ? -1 : +1; + float y_mult = font->y_scale < 0 ? -1 : +1; +#endif if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) return false; @@ -471,10 +516,8 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, *x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX; *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY); - if (font->x_scale < 0) - *x = -*x; - if (font->y_scale < 0) - *y = -*y; + *x = (hb_position_t) (x_mult * *x); + *y = (hb_position_t) (y_mult * *y); return true; } @@ -510,24 +553,24 @@ hb_ft_get_glyph_extents (hb_font_t *font, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + float x_mult = matrix.xx / 65536.f; + float y_mult = matrix.yy / 65536.f; +#else + float x_mult = font->x_scale < 0 ? -1 : +1; + float y_mult = font->y_scale < 0 ? -1 : +1; +#endif if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) return false; - extents->x_bearing = ft_face->glyph->metrics.horiBearingX; - extents->y_bearing = ft_face->glyph->metrics.horiBearingY; - extents->width = ft_face->glyph->metrics.width; - extents->height = -ft_face->glyph->metrics.height; - if (font->x_scale < 0) - { - extents->x_bearing = -extents->x_bearing; - extents->width = -extents->width; - } - if (font->y_scale < 0) - { - extents->y_bearing = -extents->y_bearing; - extents->height = -extents->height; - } + extents->x_bearing = (hb_position_t) (x_mult * ft_face->glyph->metrics.horiBearingX); + extents->y_bearing = (hb_position_t) (y_mult * ft_face->glyph->metrics.horiBearingY); + extents->width = (hb_position_t) (x_mult * ft_face->glyph->metrics.width); + extents->height = (hb_position_t) (y_mult * -ft_face->glyph->metrics.height); + return true; } @@ -620,16 +663,32 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + float y_mult = matrix.yy / 65536.f; +#else + float y_mult = font->y_scale < 0 ? -1 : +1; +#endif - metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); - metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); - metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); - if (font->y_scale < 0) + if (ft_face->units_per_EM != 0) + { + metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); + metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); + metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); + } + else { - metrics->ascender = -metrics->ascender; - metrics->descender = -metrics->descender; - metrics->line_gap = -metrics->line_gap; + /* Bitmap-only font, eg. color bitmap font. */ + metrics->ascender = ft_face->size->metrics.ascender; + metrics->descender = ft_face->size->metrics.descender; + metrics->line_gap = ft_face->size->metrics.height - (metrics->ascender - metrics->descender); } + + metrics->ascender = (hb_position_t) (y_mult * metrics->ascender); + metrics->descender = (hb_position_t) (y_mult * metrics->descender); + metrics->line_gap = (hb_position_t) (y_mult * metrics->line_gap); + return true; } @@ -684,8 +743,6 @@ hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED, hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; - _hb_ft_hb_font_check_changed (font, ft_font); - if (unlikely (FT_Load_Glyph (ft_face, glyph, FT_LOAD_NO_BITMAP | ft_font->load_flags))) return; @@ -1028,6 +1085,8 @@ hb_ft_font_changed (hb_font_t *font) #endif } #endif + + _hb_ft_hb_font_check_changed (font, ft_font); } /** diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc index 63dc18b466..4d0e687c75 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -158,7 +158,7 @@ _hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data) } /** - * hb_graphite2_face_get_gr_face: + * hb_graphite2_face_get_gr_face: (skip) * @face: @hb_face_t to query * * Fetches the Graphite2 gr_face corresponding to the specified @@ -195,10 +195,10 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED #ifndef HB_DISABLE_DEPRECATED /** - * hb_graphite2_font_get_gr_font: + * hb_graphite2_font_get_gr_font: (skip) * @font: An #hb_font_t * - * Always returns %NULL. Use hb_graphite2_face_get_gr_face() instead. + * Always returns `NULL`. Use hb_graphite2_face_get_gr_face() instead. * * Return value: (nullable): Graphite2 font associated with @font. * @@ -223,7 +223,7 @@ struct hb_graphite2_cluster_t { unsigned int base_glyph; unsigned int num_glyphs; unsigned int cluster; - unsigned int advance; + int advance; }; hb_bool_t diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index d4461f166c..1a3ab43de0 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -253,6 +253,8 @@ struct hb_is_iterator_of }; #define hb_is_iterator_of(Iter, Item) hb_is_iterator_of<Iter, Item>::value #define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) +#define hb_is_sorted_iterator_of(Iter, Item) (hb_is_iterator_of<Iter, Item>::value && Iter::is_sorted_iterator) +#define hb_is_sorted_iterator(Iter) hb_is_sorted_iterator_of (Iter, typename Iter::item_t) /* hb_is_iterable() */ diff --git a/thirdparty/harfbuzz/src/hb-map.cc b/thirdparty/harfbuzz/src/hb-map.cc index 089615c72a..a29fa1a313 100644 --- a/thirdparty/harfbuzz/src/hb-map.cc +++ b/thirdparty/harfbuzz/src/hb-map.cc @@ -56,8 +56,6 @@ hb_map_create () if (!(map = hb_object_create<hb_map_t> ())) return hb_map_get_empty (); - map->init_shallow (); - return map; } @@ -107,8 +105,6 @@ hb_map_destroy (hb_map_t *map) { if (!hb_object_destroy (map)) return; - map->fini_shallow (); - hb_free (map); } @@ -122,7 +118,7 @@ hb_map_destroy (hb_map_t *map) * * Attaches a user-data key/data pair to the specified map. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 1.7.7 **/ @@ -162,7 +158,7 @@ hb_map_get_user_data (hb_map_t *map, * * Tests whether memory allocation for a set was successful. * - * Return value: %true if allocation succeeded, %false otherwise + * Return value: `true` if allocation succeeded, `false` otherwise * * Since: 1.7.7 **/ @@ -251,7 +247,7 @@ hb_map_del (hb_map_t *map, * * Tests whether @key is an element of @map. * - * Return value: %true if @key is found in @map, %false otherwise + * Return value: `true` if @key is found in @map, `false` otherwise * * Since: 1.7.7 **/ @@ -283,7 +279,7 @@ hb_map_clear (hb_map_t *map) * * Tests whether @map is empty (contains no elements). * - * Return value: %true if @map is empty + * Return value: `true` if @map is empty * * Since: 1.7.7 **/ @@ -317,7 +313,7 @@ hb_map_get_population (const hb_map_t *map) * Tests whether @map and @other are equal (contain the same * elements). * - * Return value: %true if the two maps are equal, %false otherwise. + * Return value: `true` if the two maps are equal, `false` otherwise. * * Since: 4.3.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh index 5efad8d20c..8302e3f8c7 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -124,21 +124,20 @@ struct hb_hashmap_t hb_swap (a.prime, b.prime); hb_swap (a.items, b.items); } - void init_shallow () + void init () { + hb_object_init (this); + successful = true; population = occupancy = 0; mask = 0; prime = 0; items = nullptr; } - void init () - { - hb_object_init (this); - init_shallow (); - } - void fini_shallow () + void fini () { + hb_object_fini (this); + if (likely (items)) { unsigned size = mask + 1; for (unsigned i = 0; i < size; i++) @@ -148,11 +147,6 @@ struct hb_hashmap_t } population = occupancy = 0; } - void fini () - { - hb_object_fini (this); - fini_shallow (); - } void reset () { @@ -219,13 +213,11 @@ struct hb_hashmap_t /* Has interface. */ typedef const V& value_t; value_t operator [] (K k) const { return get (k); } - bool has (K key, const V **vp = nullptr) const + template <typename VV=V> + bool has (K key, VV **vp = nullptr) const { if (unlikely (!items)) - { - if (vp) *vp = &item_t::default_value (); return false; - } unsigned int i = bucket_for (key); if (items[i].is_real () && items[i] == key) { @@ -233,10 +225,7 @@ struct hb_hashmap_t return true; } else - { - if (vp) *vp = &item_t::default_value (); return false; - } } /* Projection. */ V operator () (K k) const { return get (k); } @@ -301,6 +290,12 @@ struct hb_hashmap_t | hb_map (&item_t::key) | hb_map (hb_ridentity) ) + auto keys_ref () const HB_AUTO_RETURN + ( + + hb_array (items, mask ? mask + 1 : 0) + | hb_filter (&item_t::is_real) + | hb_map (&item_t::key) + ) auto values () const HB_AUTO_RETURN ( + hb_array (items, mask ? mask + 1 : 0) @@ -308,6 +303,12 @@ struct hb_hashmap_t | hb_map (&item_t::value) | hb_map (hb_ridentity) ) + auto values_ref () const HB_AUTO_RETURN + ( + + hb_array (items, mask ? mask + 1 : 0) + | hb_filter (&item_t::is_real) + | hb_map (&item_t::value) + ) /* Sink interface. */ hb_hashmap_t& operator << (const hb_pair_t<K, V>& v) @@ -443,4 +444,37 @@ struct hb_map_t : hb_hashmap_t<hb_codepoint_t, hb_map_t (const Iterable &o) : hashmap (o) {} }; +template <typename K, typename V> +static inline +hb_hashmap_t<K, V>* hb_hashmap_create () +{ + using hashmap = hb_hashmap_t<K, V>; + hashmap* map; + if (!(map = hb_object_create<hashmap> ())) + return nullptr; + + return map; +} + +template <typename K, typename V> +static inline +void hb_hashmap_destroy (hb_hashmap_t<K, V>* map) +{ + if (!hb_object_destroy (map)) + return; + + hb_free (map); +} + +namespace hb { + +template <typename K, typename V> +struct vtable<hb_hashmap_t<K, V>> +{ + static constexpr auto destroy = hb_hashmap_destroy<K,V>; +}; + +} + + #endif /* HB_MAP_HH */ diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh index e97d790fc3..1921ccbb6d 100644 --- a/thirdparty/harfbuzz/src/hb-meta.hh +++ b/thirdparty/harfbuzz/src/hb-meta.hh @@ -188,7 +188,7 @@ template <> struct hb_int_max<signed long long> : hb_integral_constant<signed l template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigned long long, ULLONG_MAX> {}; #define hb_int_max(T) hb_int_max<T>::value -#if defined(__GNUC__) && __GNUC__ < 5 +#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__) #define hb_is_trivially_copyable(T) __has_trivial_copy(T) #define hb_is_trivially_copy_assignable(T) __has_trivial_assign(T) #define hb_is_trivially_constructible(T) __has_trivial_constructor(T) diff --git a/thirdparty/harfbuzz/src/hb-null.hh b/thirdparty/harfbuzz/src/hb-null.hh index 78eb6474d5..0d7f4da79e 100644 --- a/thirdparty/harfbuzz/src/hb-null.hh +++ b/thirdparty/harfbuzz/src/hb-null.hh @@ -39,6 +39,24 @@ #define HB_NULL_POOL_SIZE 448 +template <typename T, typename> +struct _hb_has_min_size : hb_false_type {}; +template <typename T> +struct _hb_has_min_size<T, hb_void_t<decltype (T::min_size)>> + : hb_true_type {}; +template <typename T> +using hb_has_min_size = _hb_has_min_size<T, void>; +#define hb_has_min_size(T) hb_has_min_size<T>::value + +template <typename T, typename> +struct _hb_has_null_size : hb_false_type {}; +template <typename T> +struct _hb_has_null_size<T, hb_void_t<decltype (T::null_size)>> + : hb_true_type {}; +template <typename T> +using hb_has_null_size = _hb_has_null_size<T, void>; +#define hb_has_null_size(T) hb_has_null_size<T>::value + /* Use SFINAE to sniff whether T has min_size; in which case return the larger * of sizeof(T) and T::null_size, otherwise return sizeof(T). * @@ -117,8 +135,19 @@ struct NullHelper }; \ namespace Namespace { \ static_assert (true, "") /* Require semicolon after. */ +#define DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1(Namespace, Type, Size) \ + } /* Close namespace. */ \ + extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Size]; \ + template <typename Spec> \ + struct Null<Namespace::Type<Spec>> { \ + static Namespace::Type<Spec> const & get_null () { \ + return *reinterpret_cast<const Namespace::Type<Spec> *> (_hb_Null_##Namespace##_##Type); \ + } \ + }; \ + namespace Namespace { \ + static_assert (true, "") /* Require semicolon after. */ #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ - const unsigned char _hb_Null_##Namespace##_##Type[hb_null_size (Namespace::Type)] + const unsigned char _hb_Null_##Namespace##_##Type[sizeof (_hb_Null_##Namespace##_##Type)] /* Specializations for arbitrary-content Null objects expressed as struct initializer. */ #define DECLARE_NULL_INSTANCE(Type) \ diff --git a/thirdparty/harfbuzz/src/hb-number-parser.hh b/thirdparty/harfbuzz/src/hb-number-parser.hh index 1a9dbba6dd..ec68c3a728 100644 --- a/thirdparty/harfbuzz/src/hb-number-parser.hh +++ b/thirdparty/harfbuzz/src/hb-number-parser.hh @@ -31,7 +31,7 @@ #include "hb.hh" -#line 35 "hb-number-parser.hh" +#line 32 "hb-number-parser.hh" static const unsigned char _double_parser_trans_keys[] = { 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 46u, 101u, 0 @@ -135,12 +135,12 @@ strtod_rl (const char *p, const char **end_ptr /* IN/OUT */) int cs; -#line 139 "hb-number-parser.hh" +#line 132 "hb-number-parser.hh" { cs = double_parser_start; } -#line 144 "hb-number-parser.hh" +#line 135 "hb-number-parser.hh" { int _slen; int _trans; @@ -198,7 +198,7 @@ _resume: exp_overflow = true; } break; -#line 202 "hb-number-parser.hh" +#line 187 "hb-number-parser.hh" } _again: diff --git a/thirdparty/harfbuzz/src/hb-object.hh b/thirdparty/harfbuzz/src/hb-object.hh index 4b5bc32ade..f6c7a56991 100644 --- a/thirdparty/harfbuzz/src/hb-object.hh +++ b/thirdparty/harfbuzz/src/hb-object.hh @@ -222,8 +222,11 @@ static inline Type *hb_object_create () if (unlikely (!obj)) return obj; + new (obj) Type; + hb_object_init (obj); hb_object_trace (obj, HB_FUNC); + return obj; } template <typename Type> @@ -269,6 +272,9 @@ static inline bool hb_object_destroy (Type *obj) return false; hb_object_fini (obj); + + obj->~Type (); + return true; } template <typename Type> @@ -280,7 +286,7 @@ static inline void hb_object_fini (Type *obj) { user_data->fini (); hb_free (user_data); - user_data = nullptr; + obj->header.user_data.set_relaxed (nullptr); } } template <typename Type> diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index aee7064be3..d0d01a68c5 100644 --- a/thirdparty/harfbuzz/src/hb-open-type.hh +++ b/thirdparty/harfbuzz/src/hb-open-type.hh @@ -105,7 +105,7 @@ struct IntType bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: BEInt<Type, Size> v; @@ -170,7 +170,7 @@ struct LONGDATETIME bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: HBINT32 major; @@ -196,6 +196,10 @@ struct HBGlyphID16 : HBUINT16 { HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } }; +struct HBGlyphID24 : HBUINT24 +{ + HBGlyphID24& operator = (uint32_t i) { HBUINT24::operator= (i); return *this; } +}; /* Script/language-system/feature index */ struct Index : HBUINT16 { @@ -300,6 +304,10 @@ struct _hb_has_null<Type, true> template <typename Type, typename OffsetType, bool has_null=true> struct OffsetTo : Offset<OffsetType, has_null> { + // Make sure Type is not unbounded; works only for types that are fully defined at OffsetTo time. + static_assert (has_null == false || + (hb_has_null_size (Type) || !hb_has_min_size (Type)), ""); + HB_DELETE_COPY_ASSIGN (OffsetTo); OffsetTo () = default; @@ -450,14 +458,16 @@ struct UnsizedArrayOf { unsigned int i = (unsigned int) i_; const Type *p = &arrayZ[i]; - if (unlikely (p < arrayZ)) return Null (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) arrayZ)) return Null (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return *p; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; Type *p = &arrayZ[i]; - if (unlikely (p < arrayZ)) return Crap (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) arrayZ)) return Crap (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return *p; } @@ -550,14 +560,16 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_ { unsigned int i = (unsigned int) i_; const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i]; - if (unlikely (p < this->arrayZ)) return Null (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Null (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return this+*p; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i]; - if (unlikely (p < this->arrayZ)) return Crap (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Crap (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return this+*p; } @@ -608,12 +620,14 @@ struct ArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } @@ -729,6 +743,7 @@ struct ArrayOf DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; template <typename Type> using Array16Of = ArrayOf<Type, HBUINT16>; +template <typename Type> using Array24Of = ArrayOf<Type, HBUINT24>; template <typename Type> using Array32Of = ArrayOf<Type, HBUINT32>; using PString = ArrayOf<HBUINT8, HBUINT8>; @@ -738,26 +753,28 @@ template <typename Type> using Array16OfOffset32To = ArrayOf<OffsetTo<Type, HBUI template <typename Type> using Array32OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>; /* Array of offsets relative to the beginning of the array itself. */ -template <typename Type> -struct List16OfOffset16To : Array16OfOffset16To<Type> +template <typename Type, typename OffsetType> +struct List16OfOffsetTo : ArrayOf<OffsetTo<Type, OffsetType>, HBUINT16> { const Type& operator [] (int i_) const { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Null (Type); + _hb_compiler_memory_r_barrier (); return this+this->arrayZ[i]; } const Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return this+this->arrayZ[i]; } bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct List16OfOffset16To<Type> *out = c->serializer->embed (*this); + struct List16OfOffsetTo *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); unsigned int count = this->len; for (unsigned int i = 0; i < count; i++) @@ -769,10 +786,13 @@ struct List16OfOffset16To : Array16OfOffset16To<Type> bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); - return_trace (Array16OfOffset16To<Type>::sanitize (c, this, std::forward<Ts> (ds)...)); + return_trace ((Array16Of<OffsetTo<Type, OffsetType>>::sanitize (c, this, std::forward<Ts> (ds)...))); } }; +template <typename Type> +using List16OfOffset16To = List16OfOffsetTo<Type, HBUINT16>; + /* An array starting at second element. */ template <typename Type, typename LenType=HBUINT16> struct HeadlessArrayOf @@ -785,12 +805,14 @@ struct HeadlessArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i-1]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i-1]; } unsigned int get_size () const @@ -869,12 +891,14 @@ struct ArrayOfM1 { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } unsigned int get_size () const @@ -961,6 +985,7 @@ struct SortedArrayOf : ArrayOf<Type, LenType> }; template <typename Type> using SortedArray16Of = SortedArrayOf<Type, HBUINT16>; +template <typename Type> using SortedArray24Of = SortedArrayOf<Type, HBUINT24>; template <typename Type> using SortedArray32Of = SortedArrayOf<Type, HBUINT32>; /* @@ -1053,12 +1078,14 @@ struct VarSizedBinSearchArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Null (Type); + _hb_compiler_memory_r_barrier (); return StructAtOffset<Type> (&bytesZ, i * header.unitSize); } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Crap (Type); + _hb_compiler_memory_r_barrier (); return StructAtOffset<Type> (&bytesZ, i * header.unitSize); } unsigned int get_length () const diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh index dac755c02c..f01d383bdc 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh @@ -145,7 +145,7 @@ struct BaseGlyphRecord bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } public: @@ -524,6 +524,7 @@ struct PaintSweepGradient }; struct Paint; + // Paint a non-COLR glyph, filled as indicated by paint. struct PaintGlyph { @@ -1152,6 +1153,8 @@ struct Paint Variable<PaintSkewAroundCenter> paintformat31; PaintComposite paintformat32; } u; + public: + DEFINE_SIZE_MIN (2); }; struct BaseGlyphPaintRecord diff --git a/thirdparty/harfbuzz/src/hb-ot-color.cc b/thirdparty/harfbuzz/src/hb-ot-color.cc index 16077765bd..a9ae013682 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color.cc +++ b/thirdparty/harfbuzz/src/hb-ot-color.cc @@ -61,7 +61,7 @@ * * Tests whether a face includes a `CPAL` color-palette table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ @@ -192,7 +192,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, * * Tests whether a face includes any `COLR` color layers. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ @@ -239,7 +239,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, * * Tests whether a face includes any `SVG` glyph images. * - * Return value: %true if data found, %false otherwise. + * Return value: `true` if data found, `false` otherwise. * * Since: 2.1.0 */ @@ -279,7 +279,7 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) * * Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ diff --git a/thirdparty/harfbuzz/src/hb-ot-color.h b/thirdparty/harfbuzz/src/hb-ot-color.h index c23ce4de44..d11e07e230 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color.h +++ b/thirdparty/harfbuzz/src/hb-ot-color.h @@ -102,6 +102,10 @@ hb_ot_color_has_layers (hb_face_t *face); * * Pairs of glyph and color index. * + * A color index of 0xFFFF does not refer to a palette + * color, but indicates that the foreground color should + * be used. + * * Since: 2.1.0 **/ typedef struct hb_ot_color_layer_t { diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index af1bc86d48..3f13b9994a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -151,7 +151,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; #ifndef HB_NO_VAR - const OT::HVARVVAR &HVAR = *hmtx.var_table; + const OT::HVAR &HVAR = *hmtx.var_table; const OT::VariationStore &varStore = &HVAR + HVAR.varStore; OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; @@ -190,7 +190,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, { for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font, varStore_cache)); + *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } @@ -211,7 +211,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, v = cv; else { - v = hmtx.get_advance (*first_glyph, font, varStore_cache); + v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); ot_font->advance_cache->set (*first_glyph, v); } *first_advance = font->em_scale_x (v); @@ -242,7 +242,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, if (vmtx.has_data ()) { #ifndef HB_NO_VAR - const OT::HVARVVAR &VVAR = *vmtx.var_table; + const OT::VVAR &VVAR = *vmtx.var_table; const OT::VariationStore &varStore = &VVAR + VVAR.varStore; OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; #else @@ -251,7 +251,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font, varStore_cache)); + *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } @@ -293,17 +293,28 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, const OT::VORG &VORG = *ot_face->VORG; if (VORG.has_data ()) { - *y = font->em_scale_y (VORG.get_y_origin (glyph)); + float delta = 0; + +#ifndef HB_NO_VAR + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; + const OT::VVAR &VVAR = *vmtx.var_table; + if (font->num_coords) + VVAR.get_vorg_delta_unscaled (glyph, + font->coords, font->num_coords, + &delta); +#endif + + *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta); return true; } hb_glyph_extents_t extents = {0}; if (ot_face->glyf->get_extents (font, glyph, &extents)) { - if (ot_face->vmtx->has_data ()) + const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; + int tsb = 0; + if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb)) { - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - hb_position_t tsb = vmtx.get_side_bearing (font, glyph); *y = extents.y_bearing + font->em_scale_y (tsb); return true; } @@ -503,16 +514,17 @@ hb_ot_font_set_funcs (hb_font_t *font) } #ifndef HB_NO_VAR -int -_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) +bool +_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, + int *lsb) { - return font->face->table.glyf->get_side_bearing_var (font, glyph, is_vertical); + return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); } unsigned -_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) +_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) { - return font->face->table.glyf->get_advance_var (font, glyph, is_vertical); + return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); } #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh index d0e46e0b0f..50e4b54fde 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh @@ -43,11 +43,11 @@ #define HB_OT_TAG_vmtx HB_TAG('v','m','t','x') -HB_INTERNAL int -_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); +HB_INTERNAL bool +_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical, int *lsb); HB_INTERNAL unsigned -_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); +_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); namespace OT { @@ -62,7 +62,7 @@ struct LongMetric }; -template <typename T, typename H> +template <typename T/*Data table type*/, typename H/*Header table type*/, typename V/*Var table type*/> struct hmtxvmtx { bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const @@ -135,9 +135,9 @@ struct hmtxvmtx auto& plan = c->plan; num_long_metrics = plan->num_output_glyphs (); hb_codepoint_t old_gid = 0; - unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0; + unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance_without_var_unscaled (old_gid) : 0; while (num_long_metrics > 1 && - last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0)) + last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance_without_var_unscaled (old_gid) : 0)) { num_long_metrics--; } @@ -150,7 +150,9 @@ struct hmtxvmtx hb_codepoint_t old_gid; if (!c->plan->old_gid_for_new_gid (_, &old_gid)) return hb_pair (0u, 0); - return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid)); + int lsb = 0; + (void) _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); + return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); }) ; @@ -173,7 +175,7 @@ struct hmtxvmtx accelerator_t (hb_face_t *face) { table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag); - var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag); + var_table = hb_sanitize_context_t ().reference_table<V> (face, T::variationsTag); default_advance = T::is_horizontal ? hb_face_get_upem (face) / 2 : hb_face_get_upem (face); @@ -221,36 +223,46 @@ struct hmtxvmtx bool has_data () const { return (bool) num_bearings; } - int get_side_bearing (hb_codepoint_t glyph) const + bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, + int *lsb) const { if (glyph < num_long_metrics) - return table->longMetricZ[glyph].sb; + { + *lsb = table->longMetricZ[glyph].sb; + return true; + } if (unlikely (glyph >= num_bearings)) - return 0; + return false; const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; - return bearings[glyph - num_long_metrics]; + *lsb = bearings[glyph - num_long_metrics]; + return true; } - int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const + bool get_leading_bearing_with_var_unscaled (hb_font_t *font, + hb_codepoint_t glyph, + int *lsb) const { - int side_bearing = get_side_bearing (glyph); + if (!font->num_coords) + return get_leading_bearing_without_var_unscaled (glyph, lsb); #ifndef HB_NO_VAR - if (unlikely (glyph >= num_bearings) || !font->num_coords) - return side_bearing; - - if (var_table.get_length ()) - return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); + float delta; + if (var_table->get_lsb_delta_unscaled (glyph, font->coords, font->num_coords, &delta) && + get_leading_bearing_without_var_unscaled (glyph, lsb)) + { + *lsb += roundf (delta); + return true; + } - return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx, lsb); #else - return side_bearing; + return false; #endif } - unsigned int get_advance (hb_codepoint_t glyph) const + unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const { /* OpenType case. */ if (glyph < num_bearings) @@ -262,7 +274,7 @@ struct hmtxvmtx if (unlikely (!num_advances)) return default_advance; -#ifdef HB_NO_BORING_EXPANSION +#ifdef HB_NO_BEYOND_64K return 0; #endif @@ -275,7 +287,7 @@ struct hmtxvmtx /* TODO Optimize */ if (num_bearings == num_advances) - return get_advance (num_bearings - 1); + return get_advance_without_var_unscaled (num_bearings - 1); const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; const UFWORD *advances = (const UFWORD *) &bearings[num_bearings - num_long_metrics]; @@ -283,20 +295,22 @@ struct hmtxvmtx return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)]; } - unsigned int get_advance (hb_codepoint_t glyph, - hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, + hb_font_t *font, + VariationStore::cache_t *store_cache = nullptr) const { - unsigned int advance = get_advance (glyph); + unsigned int advance = get_advance_without_var_unscaled (glyph); #ifndef HB_NO_VAR if (unlikely (glyph >= num_bearings) || !font->num_coords) return advance; if (var_table.get_length ()) - return advance + roundf (var_table->get_advance_var (glyph, font, store_cache)); // TODO Optimize?! + return advance + roundf (var_table->get_advance_delta_unscaled (glyph, + font->coords, font->num_coords, + store_cache)); // TODO Optimize?! - return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); #else return advance; #endif @@ -313,7 +327,7 @@ struct hmtxvmtx public: hb_blob_ptr_t<hmtxvmtx> table; - hb_blob_ptr_t<HVARVVAR> var_table; + hb_blob_ptr_t<V> var_table; }; protected: @@ -346,12 +360,12 @@ struct hmtxvmtx DEFINE_SIZE_ARRAY (0, longMetricZ); }; -struct hmtx : hmtxvmtx<hmtx, hhea> { +struct hmtx : hmtxvmtx<hmtx, hhea, HVAR> { static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx; static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR; static constexpr bool is_horizontal = true; }; -struct vmtx : hmtxvmtx<vmtx, vhea> { +struct vmtx : hmtxvmtx<vmtx, vhea, VVAR> { static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx; static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR; static constexpr bool is_horizontal = false; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh index 1b9dfcd3f5..8179e5acd5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh @@ -49,7 +49,7 @@ struct BaseCoordFormat1 bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index d343805346..9a4157b21f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -35,6 +35,14 @@ #include "hb-set.hh" #include "hb-bimap.hh" +#include "OT/Layout/Common/Coverage.hh" +#include "OT/Layout/types.hh" + +// TODO(garretrieger): cleanup these after migration. +using OT::Layout::Common::Coverage; +using OT::Layout::Common::RangeRecord; +using OT::Layout::SmallTypes; +using OT::Layout::MediumTypes; #ifndef HB_MAX_NESTING_LEVEL #define HB_MAX_NESTING_LEVEL 64 @@ -46,10 +54,10 @@ /* * The maximum number of times a lookup can be applied during shaping. * Used to limit the number of iterations of the closure algorithm. - * This must be larger than the number of times add_pause() is + * This must be larger than the number of times add_gsub_pause() is * called in a collect_features call of any shaper. */ -#define HB_CLOSURE_MAX_STAGES 32 +#define HB_CLOSURE_MAX_STAGES 12 #endif #ifndef HB_MAX_SCRIPTS @@ -79,14 +87,6 @@ namespace OT { - -#define NOT_COVERED ((unsigned int) -1) - - -template<typename Iterator> -static inline void Coverage_serialize (hb_serialize_context_t *c, - Iterator it); - template<typename Iterator> static inline void ClassDef_serialize (hb_serialize_context_t *c, Iterator it); @@ -377,6 +377,51 @@ HB_FUNCOBJ (serialize_math_record_array); * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList */ +struct IndexArray : Array16Of<Index> +{ + bool intersects (const hb_map_t *indexes) const + { return hb_any (*this, indexes); } + + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + void serialize (hb_serialize_context_t *c, + hb_subset_layout_context_t *l, + Iterator it) + { + if (!it) return; + if (unlikely (!c->extend_min ((*this)))) return; + + for (const auto _ : it) + { + if (!l->visitLookupIndex()) break; + + Index i; + i = _; + c->copy (i); + this->len++; + } + } + + unsigned int get_indexes (unsigned int start_offset, + unsigned int *_count /* IN/OUT */, + unsigned int *_indexes /* OUT */) const + { + if (_count) + { + + this->sub_array (start_offset, _count) + | hb_sink (hb_array (_indexes, *_count)) + ; + } + return this->len; + } + + void add_indexes_to (hb_set_t* output /* OUT */) const + { + output->add_array (as_array ()); + } +}; + + struct Record_sanitize_closure_t { hb_tag_t tag; const void *list_base; @@ -465,363 +510,6 @@ struct RecordListOf : RecordArrayOf<Type> } }; -struct Feature; - -struct RecordListOfFeature : RecordListOf<Feature> -{ - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - unsigned count = this->len; - + hb_zip (*this, hb_range (count)) - | hb_filter (l->feature_index_map, hb_second) - | hb_map (hb_first) - | hb_apply (subset_record_array (l, out, this)) - ; - return_trace (true); - } -}; - -struct Script; -struct RecordListOfScript : RecordListOf<Script> -{ - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - unsigned count = this->len; - for (auto _ : + hb_zip (*this, hb_range (count))) - { - auto snap = c->serializer->snapshot (); - l->cur_script_index = _.second; - bool ret = _.first.subset (l, this); - if (!ret) c->serializer->revert (snap); - else out->len++; - } - - return_trace (true); - } -}; - -struct RangeRecord -{ - int cmp (hb_codepoint_t g) const - { return g < first ? -1 : g <= last ? 0 : +1; } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - bool intersects (const hb_set_t *glyphs) const - { return glyphs->intersects (first, last); } - - template <typename set_t> - bool collect_coverage (set_t *glyphs) const - { return glyphs->add_range (first, last); } - - HBGlyphID16 first; /* First GlyphID in the range */ - HBGlyphID16 last; /* Last GlyphID in the range */ - HBUINT16 value; /* Value */ - public: - DEFINE_SIZE_STATIC (6); -}; -DECLARE_NULL_NAMESPACE_BYTES (OT, RangeRecord); - - -struct IndexArray : Array16Of<Index> -{ - bool intersects (const hb_map_t *indexes) const - { return hb_any (*this, indexes); } - - template <typename Iterator, - hb_requires (hb_is_iterator (Iterator))> - void serialize (hb_serialize_context_t *c, - hb_subset_layout_context_t *l, - Iterator it) - { - if (!it) return; - if (unlikely (!c->extend_min ((*this)))) return; - - for (const auto _ : it) - { - if (!l->visitLookupIndex()) break; - - Index i; - i = _; - c->copy (i); - this->len++; - } - } - - unsigned int get_indexes (unsigned int start_offset, - unsigned int *_count /* IN/OUT */, - unsigned int *_indexes /* OUT */) const - { - if (_count) - { - + this->sub_array (start_offset, _count) - | hb_sink (hb_array (_indexes, *_count)) - ; - } - return this->len; - } - - void add_indexes_to (hb_set_t* output /* OUT */) const - { - output->add_array (as_array ()); - } -}; - - -struct LangSys -{ - unsigned int get_feature_count () const - { return featureIndex.len; } - hb_tag_t get_feature_index (unsigned int i) const - { return featureIndex[i]; } - unsigned int get_feature_indexes (unsigned int start_offset, - unsigned int *feature_count /* IN/OUT */, - unsigned int *feature_indexes /* OUT */) const - { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } - void add_feature_indexes_to (hb_set_t *feature_indexes) const - { featureIndex.add_indexes_to (feature_indexes); } - - bool has_required_feature () const { return reqFeatureIndex != 0xFFFFu; } - unsigned int get_required_feature_index () const - { - if (reqFeatureIndex == 0xFFFFu) - return Index::NOT_FOUND_INDEX; - return reqFeatureIndex; - } - - LangSys* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - return_trace (c->embed (*this)); - } - - bool compare (const LangSys& o, const hb_map_t *feature_index_map) const - { - if (reqFeatureIndex != o.reqFeatureIndex) - return false; - - auto iter = - + hb_iter (featureIndex) - | hb_filter (feature_index_map) - | hb_map (feature_index_map) - ; - - auto o_iter = - + hb_iter (o.featureIndex) - | hb_filter (feature_index_map) - | hb_map (feature_index_map) - ; - - for (; iter && o_iter; iter++, o_iter++) - { - unsigned a = *iter; - unsigned b = *o_iter; - if (a != b) return false; - } - - if (iter || o_iter) return false; - - return true; - } - - void collect_features (hb_prune_langsys_context_t *c) const - { - if (!has_required_feature () && !get_feature_count ()) return; - if (has_required_feature () && - c->duplicate_feature_map->has (reqFeatureIndex)) - c->new_feature_indexes->add (get_required_feature_index ()); - - + hb_iter (featureIndex) - | hb_filter (c->duplicate_feature_map) - | hb_sink (c->new_feature_indexes) - ; - } - - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l, - const Tag *tag = nullptr) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - const unsigned *v; - out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; - - if (!l->visitFeatureIndex (featureIndex.len)) - return_trace (false); - - auto it = - + hb_iter (featureIndex) - | hb_filter (l->feature_index_map) - | hb_map (l->feature_index_map) - ; - - bool ret = bool (it); - out->featureIndex.serialize (c->serializer, l, it); - return_trace (ret); - } - - bool sanitize (hb_sanitize_context_t *c, - const Record_sanitize_closure_t * = nullptr) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && featureIndex.sanitize (c)); - } - - Offset16 lookupOrderZ; /* = Null (reserved for an offset to a - * reordering table) */ - HBUINT16 reqFeatureIndex;/* Index of a feature required for this - * language system--if no required features - * = 0xFFFFu */ - IndexArray featureIndex; /* Array of indices into the FeatureList */ - public: - DEFINE_SIZE_ARRAY_SIZED (6, featureIndex); -}; -DECLARE_NULL_NAMESPACE_BYTES (OT, LangSys); - -struct Script -{ - unsigned int get_lang_sys_count () const - { return langSys.len; } - const Tag& get_lang_sys_tag (unsigned int i) const - { return langSys.get_tag (i); } - unsigned int get_lang_sys_tags (unsigned int start_offset, - unsigned int *lang_sys_count /* IN/OUT */, - hb_tag_t *lang_sys_tags /* OUT */) const - { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); } - const LangSys& get_lang_sys (unsigned int i) const - { - if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); - return this+langSys[i].offset; - } - bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const - { return langSys.find_index (tag, index); } - - bool has_default_lang_sys () const { return defaultLangSys != 0; } - const LangSys& get_default_lang_sys () const { return this+defaultLangSys; } - - void prune_langsys (hb_prune_langsys_context_t *c, - unsigned script_index) const - { - if (!has_default_lang_sys () && !get_lang_sys_count ()) return; - if (!c->visitScript ()) return; - - if (!c->script_langsys_map->has (script_index)) - { - if (unlikely (!c->script_langsys_map->set (script_index, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) - return; - } - - unsigned langsys_count = get_lang_sys_count (); - if (has_default_lang_sys ()) - { - //only collect features from non-redundant langsys - const LangSys& d = get_default_lang_sys (); - if (c->visitLangsys (d.get_feature_count ())) { - d.collect_features (c); - } - - for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) - { - const LangSys& l = this+_.first.offset; - if (!c->visitLangsys (l.get_feature_count ())) continue; - if (l.compare (d, c->duplicate_feature_map)) continue; - - l.collect_features (c); - c->script_langsys_map->get (script_index)->add (_.second); - } - } - else - { - for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) - { - const LangSys& l = this+_.first.offset; - if (!c->visitLangsys (l.get_feature_count ())) continue; - l.collect_features (c); - c->script_langsys_map->get (script_index)->add (_.second); - } - } - } - - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l, - const Tag *tag) const - { - TRACE_SUBSET (this); - if (!l->visitScript ()) return_trace (false); - - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - bool defaultLang = false; - if (has_default_lang_sys ()) - { - c->serializer->push (); - const LangSys& ls = this+defaultLangSys; - bool ret = ls.subset (c, l); - if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T')) - { - c->serializer->pop_discard (); - out->defaultLangSys = 0; - } - else - { - c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ()); - defaultLang = true; - } - } - - const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index); - if (active_langsys) - { - unsigned count = langSys.len; - + hb_zip (langSys, hb_range (count)) - | hb_filter (active_langsys, hb_second) - | hb_map (hb_first) - | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); }) - | hb_apply (subset_record_array (l, &(out->langSys), this)) - ; - } - - return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB); - } - - bool sanitize (hb_sanitize_context_t *c, - const Record_sanitize_closure_t * = nullptr) const - { - TRACE_SANITIZE (this); - return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); - } - - protected: - Offset16To<LangSys> - defaultLangSys; /* Offset to DefaultLangSys table--from - * beginning of Script table--may be Null */ - RecordArrayOf<LangSys> - langSys; /* Array of LangSysRecords--listed - * alphabetically by LangSysTag */ - public: - DEFINE_SIZE_ARRAY_SIZED (4, langSys); -}; - -typedef RecordListOfScript ScriptList; - - /* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */ struct FeatureParamsSize { @@ -1104,6 +792,7 @@ struct FeatureParams DEFINE_SIZE_MIN (0); }; + struct Feature { unsigned int get_lookup_count () const @@ -1199,9 +888,294 @@ struct Feature DEFINE_SIZE_ARRAY_SIZED (4, lookupIndex); }; +struct RecordListOfFeature : RecordListOf<Feature> +{ + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned count = this->len; + + hb_zip (*this, hb_range (count)) + | hb_filter (l->feature_index_map, hb_second) + | hb_map (hb_first) + | hb_apply (subset_record_array (l, out, this)) + ; + return_trace (true); + } +}; + typedef RecordListOf<Feature> FeatureList; +struct LangSys +{ + unsigned int get_feature_count () const + { return featureIndex.len; } + hb_tag_t get_feature_index (unsigned int i) const + { return featureIndex[i]; } + unsigned int get_feature_indexes (unsigned int start_offset, + unsigned int *feature_count /* IN/OUT */, + unsigned int *feature_indexes /* OUT */) const + { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } + void add_feature_indexes_to (hb_set_t *feature_indexes) const + { featureIndex.add_indexes_to (feature_indexes); } + + bool has_required_feature () const { return reqFeatureIndex != 0xFFFFu; } + unsigned int get_required_feature_index () const + { + if (reqFeatureIndex == 0xFFFFu) + return Index::NOT_FOUND_INDEX; + return reqFeatureIndex; + } + + LangSys* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace (c->embed (*this)); + } + + bool compare (const LangSys& o, const hb_map_t *feature_index_map) const + { + if (reqFeatureIndex != o.reqFeatureIndex) + return false; + + auto iter = + + hb_iter (featureIndex) + | hb_filter (feature_index_map) + | hb_map (feature_index_map) + ; + + auto o_iter = + + hb_iter (o.featureIndex) + | hb_filter (feature_index_map) + | hb_map (feature_index_map) + ; + + for (; iter && o_iter; iter++, o_iter++) + { + unsigned a = *iter; + unsigned b = *o_iter; + if (a != b) return false; + } + + if (iter || o_iter) return false; + + return true; + } + + void collect_features (hb_prune_langsys_context_t *c) const + { + if (!has_required_feature () && !get_feature_count ()) return; + if (has_required_feature () && + c->duplicate_feature_map->has (reqFeatureIndex)) + c->new_feature_indexes->add (get_required_feature_index ()); + + + hb_iter (featureIndex) + | hb_filter (c->duplicate_feature_map) + | hb_sink (c->new_feature_indexes) + ; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + const Tag *tag = nullptr) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + const unsigned *v; + out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu; + + if (!l->visitFeatureIndex (featureIndex.len)) + return_trace (false); + + auto it = + + hb_iter (featureIndex) + | hb_filter (l->feature_index_map) + | hb_map (l->feature_index_map) + ; + + bool ret = bool (it); + out->featureIndex.serialize (c->serializer, l, it); + return_trace (ret); + } + + bool sanitize (hb_sanitize_context_t *c, + const Record_sanitize_closure_t * = nullptr) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && featureIndex.sanitize (c)); + } + + Offset16 lookupOrderZ; /* = Null (reserved for an offset to a + * reordering table) */ + HBUINT16 reqFeatureIndex;/* Index of a feature required for this + * language system--if no required features + * = 0xFFFFu */ + IndexArray featureIndex; /* Array of indices into the FeatureList */ + public: + DEFINE_SIZE_ARRAY_SIZED (6, featureIndex); +}; +DECLARE_NULL_NAMESPACE_BYTES (OT, LangSys); + +struct Script +{ + unsigned int get_lang_sys_count () const + { return langSys.len; } + const Tag& get_lang_sys_tag (unsigned int i) const + { return langSys.get_tag (i); } + unsigned int get_lang_sys_tags (unsigned int start_offset, + unsigned int *lang_sys_count /* IN/OUT */, + hb_tag_t *lang_sys_tags /* OUT */) const + { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); } + const LangSys& get_lang_sys (unsigned int i) const + { + if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); + return this+langSys[i].offset; + } + bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const + { return langSys.find_index (tag, index); } + + bool has_default_lang_sys () const { return defaultLangSys != 0; } + const LangSys& get_default_lang_sys () const { return this+defaultLangSys; } + + void prune_langsys (hb_prune_langsys_context_t *c, + unsigned script_index) const + { + if (!has_default_lang_sys () && !get_lang_sys_count ()) return; + if (!c->visitScript ()) return; + + if (!c->script_langsys_map->has (script_index)) + { + if (unlikely (!c->script_langsys_map->set (script_index, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) + return; + } + + unsigned langsys_count = get_lang_sys_count (); + if (has_default_lang_sys ()) + { + //only collect features from non-redundant langsys + const LangSys& d = get_default_lang_sys (); + if (c->visitLangsys (d.get_feature_count ())) { + d.collect_features (c); + } + + for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) + { + const LangSys& l = this+_.first.offset; + if (!c->visitLangsys (l.get_feature_count ())) continue; + if (l.compare (d, c->duplicate_feature_map)) continue; + + l.collect_features (c); + c->script_langsys_map->get (script_index)->add (_.second); + } + } + else + { + for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) + { + const LangSys& l = this+_.first.offset; + if (!c->visitLangsys (l.get_feature_count ())) continue; + l.collect_features (c); + c->script_langsys_map->get (script_index)->add (_.second); + } + } + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + const Tag *tag) const + { + TRACE_SUBSET (this); + if (!l->visitScript ()) return_trace (false); + if (tag && !c->plan->layout_scripts->has (*tag)) + return false; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + bool defaultLang = false; + if (has_default_lang_sys ()) + { + c->serializer->push (); + const LangSys& ls = this+defaultLangSys; + bool ret = ls.subset (c, l); + if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T')) + { + c->serializer->pop_discard (); + out->defaultLangSys = 0; + } + else + { + c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ()); + defaultLang = true; + } + } + + const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index); + if (active_langsys) + { + unsigned count = langSys.len; + + hb_zip (langSys, hb_range (count)) + | hb_filter (active_langsys, hb_second) + | hb_map (hb_first) + | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); }) + | hb_apply (subset_record_array (l, &(out->langSys), this)) + ; + } + + return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB); + } + + bool sanitize (hb_sanitize_context_t *c, + const Record_sanitize_closure_t * = nullptr) const + { + TRACE_SANITIZE (this); + return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); + } + + protected: + Offset16To<LangSys> + defaultLangSys; /* Offset to DefaultLangSys table--from + * beginning of Script table--may be Null */ + RecordArrayOf<LangSys> + langSys; /* Array of LangSysRecords--listed + * alphabetically by LangSysTag */ + public: + DEFINE_SIZE_ARRAY_SIZED (4, langSys); +}; + +struct RecordListOfScript : RecordListOf<Script> +{ + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned count = this->len; + for (auto _ : + hb_zip (*this, hb_range (count))) + { + auto snap = c->serializer->snapshot (); + l->cur_script_index = _.second; + bool ret = _.first.subset (l, this); + if (!ret) c->serializer->revert (snap); + else out->len++; + } + + return_trace (true); + } +}; + +typedef RecordListOfScript ScriptList; + + + struct LookupFlag : HBUINT16 { enum Flags { @@ -1343,7 +1317,7 @@ struct Lookup if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ()))) return_trace (false); - if (unlikely (get_type () == TSubTable::Extension && subtables && !c->get_edit_count ())) + if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) { /* The spec says all subtables of an Extension lookup should * have the same type, which shall not be the Extension type @@ -1375,10 +1349,11 @@ struct Lookup DEFINE_SIZE_ARRAY (6, subTable); }; -typedef List16OfOffset16To<Lookup> LookupList; +template <typename Types> +using LookupList = List16OfOffsetTo<Lookup, typename Types::HBUINT>; -template <typename TLookup> -struct LookupOffsetList : List16OfOffset16To<TLookup> +template <typename TLookup, typename OffsetType> +struct LookupOffsetList : List16OfOffsetTo<TLookup, OffsetType> { bool subset (hb_subset_context_t *c, hb_subset_layout_context_t *l) const @@ -1408,470 +1383,6 @@ struct LookupOffsetList : List16OfOffset16To<TLookup> * Coverage Table */ -struct CoverageFormat1 -{ - friend struct Coverage; - - private: - unsigned int get_coverage (hb_codepoint_t glyph_id) const - { - unsigned int i; - glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED); - return i; - } - - template <typename Iterator, - hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> - bool serialize (hb_serialize_context_t *c, Iterator glyphs) - { - TRACE_SERIALIZE (this); - return_trace (glyphArray.serialize (c, glyphs)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (glyphArray.sanitize (c)); - } - - bool intersects (const hb_set_t *glyphs) const - { - /* TODO Speed up, using hb_set_next() and bsearch()? */ - for (const auto& g : glyphArray.as_array ()) - if (glyphs->has (g)) - return true; - return false; - } - bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const - { return glyphs->has (glyphArray[index]); } - - void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const - { - unsigned count = glyphArray.len; - for (unsigned i = 0; i < count; i++) - if (glyphs->has (glyphArray[i])) - intersect_glyphs->add (glyphArray[i]); - } - - template <typename set_t> - bool collect_coverage (set_t *glyphs) const - { return glyphs->add_sorted_array (glyphArray.as_array ()); } - - public: - /* Older compilers need this to be public. */ - struct iter_t - { - void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; } - void fini () {} - bool more () const { return i < c->glyphArray.len; } - void next () { i++; } - hb_codepoint_t get_glyph () const { return c->glyphArray[i]; } - bool operator != (const iter_t& o) const - { return i != o.i; } - iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; } - - private: - const struct CoverageFormat1 *c; - unsigned int i; - }; - private: - - protected: - HBUINT16 coverageFormat; /* Format identifier--format = 1 */ - SortedArray16Of<HBGlyphID16> - glyphArray; /* Array of GlyphIDs--in numerical order */ - public: - DEFINE_SIZE_ARRAY (4, glyphArray); -}; - -struct CoverageFormat2 -{ - friend struct Coverage; - - private: - unsigned int get_coverage (hb_codepoint_t glyph_id) const - { - const RangeRecord &range = rangeRecord.bsearch (glyph_id); - return likely (range.first <= range.last) - ? (unsigned int) range.value + (glyph_id - range.first) - : NOT_COVERED; - } - - template <typename Iterator, - hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> - bool serialize (hb_serialize_context_t *c, Iterator glyphs) - { - TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (this))) return_trace (false); - - /* TODO(iter) Write more efficiently? */ - - unsigned num_ranges = 0; - hb_codepoint_t last = (hb_codepoint_t) -2; - for (auto g: glyphs) - { - if (last + 1 != g) - num_ranges++; - last = g; - } - - if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false); - if (!num_ranges) return_trace (true); - - unsigned count = 0; - unsigned range = (unsigned) -1; - last = (hb_codepoint_t) -2; - for (auto g: glyphs) - { - if (last + 1 != g) - { - range++; - rangeRecord[range].first = g; - rangeRecord[range].value = count; - } - rangeRecord[range].last = g; - last = g; - count++; - } - - return_trace (true); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (rangeRecord.sanitize (c)); - } - - bool intersects (const hb_set_t *glyphs) const - { - return hb_any (+ hb_iter (rangeRecord.as_array ()) - | hb_map ([glyphs] (const RangeRecord &range) { return range.intersects (glyphs); })); - } - bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const - { - auto cmp = [] (const void *pk, const void *pr) -> int - { - unsigned index = * (const unsigned *) pk; - const RangeRecord &range = * (const RangeRecord *) pr; - if (index < range.value) return -1; - if (index > (unsigned int) range.value + (range.last - range.first)) return +1; - return 0; - }; - - auto arr = rangeRecord.as_array (); - unsigned idx; - if (hb_bsearch_impl (&idx, index, - arr.arrayZ, arr.length, sizeof (arr[0]), - (int (*)(const void *_key, const void *_item)) cmp)) - return arr.arrayZ[idx].intersects (glyphs); - return false; - } - - void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const - { - for (const auto& range : rangeRecord.as_array ()) - { - if (!range.intersects (glyphs)) continue; - unsigned last = range.last; - for (hb_codepoint_t g = range.first - 1; - glyphs->next (&g) && g <= last;) - intersect_glyphs->add (g); - } - } - - template <typename set_t> - bool collect_coverage (set_t *glyphs) const - { - unsigned int count = rangeRecord.len; - for (unsigned int i = 0; i < count; i++) - if (unlikely (!rangeRecord[i].collect_coverage (glyphs))) - return false; - return true; - } - - public: - /* Older compilers need this to be public. */ - struct iter_t - { - void init (const CoverageFormat2 &c_) - { - c = &c_; - coverage = 0; - i = 0; - j = c->rangeRecord.len ? c->rangeRecord[0].first : 0; - if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last)) - { - /* Broken table. Skip. */ - i = c->rangeRecord.len; - } - } - void fini () {} - bool more () const { return i < c->rangeRecord.len; } - void next () - { - if (j >= c->rangeRecord[i].last) - { - i++; - if (more ()) - { - unsigned int old = coverage; - j = c->rangeRecord[i].first; - coverage = c->rangeRecord[i].value; - if (unlikely (coverage != old + 1)) - { - /* Broken table. Skip. Important to avoid DoS. - * Also, our callers depend on coverage being - * consecutive and monotonically increasing, - * ie. iota(). */ - i = c->rangeRecord.len; - return; - } - } - else - j = 0; - return; - } - coverage++; - j++; - } - hb_codepoint_t get_glyph () const { return j; } - bool operator != (const iter_t& o) const - { return i != o.i || j != o.j; } - iter_t __end__ () const - { - iter_t it; - it.init (*c); - it.i = c->rangeRecord.len; - it.j = 0; - return it; - } - - private: - const struct CoverageFormat2 *c; - unsigned int i, coverage; - hb_codepoint_t j; - }; - private: - - protected: - HBUINT16 coverageFormat; /* Format identifier--format = 2 */ - SortedArray16Of<RangeRecord> - rangeRecord; /* Array of glyph ranges--ordered by - * Start GlyphID. rangeCount entries - * long */ - public: - DEFINE_SIZE_ARRAY (4, rangeRecord); -}; - -struct Coverage -{ - /* Has interface. */ - static constexpr unsigned SENTINEL = NOT_COVERED; - typedef unsigned int value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } - /* Predicate. */ - bool operator () (hb_codepoint_t k) const { return has (k); } - - unsigned int get (hb_codepoint_t k) const { return get_coverage (k); } - unsigned int get_coverage (hb_codepoint_t glyph_id) const - { - switch (u.format) { - case 1: return u.format1.get_coverage (glyph_id); - case 2: return u.format2.get_coverage (glyph_id); - default:return NOT_COVERED; - } - } - - template <typename Iterator, - hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> - bool serialize (hb_serialize_context_t *c, Iterator glyphs) - { - TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (this))) return_trace (false); - - unsigned count = 0; - unsigned num_ranges = 0; - hb_codepoint_t last = (hb_codepoint_t) -2; - for (auto g: glyphs) - { - if (last + 1 != g) - num_ranges++; - last = g; - count++; - } - u.format = count <= num_ranges * 3 ? 1 : 2; - - switch (u.format) - { - case 1: return_trace (u.format1.serialize (c, glyphs)); - case 2: return_trace (u.format2.serialize (c, glyphs)); - default:return_trace (false); - } - } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto it = - + iter () - | hb_filter (c->plan->glyph_map_gsub) - | hb_map_retains_sorting (c->plan->glyph_map_gsub) - ; - - // Cache the iterator result as it will be iterated multiple times - // by the serialize code below. - hb_sorted_vector_t<hb_codepoint_t> glyphs (it); - Coverage_serialize (c->serializer, glyphs.iter ()); - return_trace (bool (glyphs)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) - { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - default:return_trace (true); - } - } - - bool intersects (const hb_set_t *glyphs) const - { - switch (u.format) - { - case 1: return u.format1.intersects (glyphs); - case 2: return u.format2.intersects (glyphs); - default:return false; - } - } - bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const - { - switch (u.format) - { - case 1: return u.format1.intersects_coverage (glyphs, index); - case 2: return u.format2.intersects_coverage (glyphs, index); - default:return false; - } - } - - /* Might return false if array looks unsorted. - * Used for faster rejection of corrupt data. */ - template <typename set_t> - bool collect_coverage (set_t *glyphs) const - { - switch (u.format) - { - case 1: return u.format1.collect_coverage (glyphs); - case 2: return u.format2.collect_coverage (glyphs); - default:return false; - } - } - - void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const - { - switch (u.format) - { - case 1: return u.format1.intersected_coverage_glyphs (glyphs, intersect_glyphs); - case 2: return u.format2.intersected_coverage_glyphs (glyphs, intersect_glyphs); - default:return ; - } - } - - struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> - { - static constexpr bool is_sorted_iterator = true; - iter_t (const Coverage &c_ = Null (Coverage)) - { - memset (this, 0, sizeof (*this)); - format = c_.u.format; - switch (format) - { - case 1: u.format1.init (c_.u.format1); return; - case 2: u.format2.init (c_.u.format2); return; - default: return; - } - } - bool __more__ () const - { - switch (format) - { - case 1: return u.format1.more (); - case 2: return u.format2.more (); - default:return false; - } - } - void __next__ () - { - switch (format) - { - case 1: u.format1.next (); break; - case 2: u.format2.next (); break; - default: break; - } - } - typedef hb_codepoint_t __item_t__; - __item_t__ __item__ () const { return get_glyph (); } - - hb_codepoint_t get_glyph () const - { - switch (format) - { - case 1: return u.format1.get_glyph (); - case 2: return u.format2.get_glyph (); - default:return 0; - } - } - bool operator != (const iter_t& o) const - { - if (unlikely (format != o.format)) return true; - switch (format) - { - case 1: return u.format1 != o.u.format1; - case 2: return u.format2 != o.u.format2; - default:return false; - } - } - iter_t __end__ () const - { - iter_t it = {}; - it.format = format; - switch (format) - { - case 1: it.u.format1 = u.format1.__end__ (); break; - case 2: it.u.format2 = u.format2.__end__ (); break; - default: break; - } - return it; - } - - private: - unsigned int format; - union { - CoverageFormat2::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */ - CoverageFormat1::iter_t format1; - } u; - }; - iter_t iter () const { return iter_t (*this); } - - protected: - union { - HBUINT16 format; /* Format identifier */ - CoverageFormat1 format1; - CoverageFormat2 format2; - } u; - public: - DEFINE_SIZE_UNION (2, format); -}; - -template<typename Iterator> -static inline void -Coverage_serialize (hb_serialize_context_t *c, - Iterator it) -{ c->start_embed<Coverage> ()->serialize (c, it); } static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, const hb_set_t &klasses, @@ -1913,7 +1424,8 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, * Class Definition Table */ -struct ClassDefFormat1 +template <typename Types> +struct ClassDefFormat1_3 { friend struct ClassDef; @@ -1924,7 +1436,7 @@ struct ClassDefFormat1 } template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator it) { @@ -2118,14 +1630,16 @@ struct ClassDefFormat1 protected: HBUINT16 classFormat; /* Format identifier--format = 1 */ - HBGlyphID16 startGlyph; /* First GlyphID of the classValueArray */ - Array16Of<HBUINT16> + typename Types::HBGlyphID + startGlyph; /* First GlyphID of the classValueArray */ + typename Types::template ArrayOf<HBUINT16> classValue; /* Array of Class Values--one per GlyphID */ public: - DEFINE_SIZE_ARRAY (6, classValue); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, classValue); }; -struct ClassDefFormat2 +template <typename Types> +struct ClassDefFormat2_4 { friend struct ClassDef; @@ -2136,7 +1650,7 @@ struct ClassDefFormat2 } template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator it) { @@ -2154,12 +1668,12 @@ struct ClassDefFormat2 hb_codepoint_t prev_gid = (*it).first; unsigned prev_klass = (*it).second; - RangeRecord range_rec; + RangeRecord<Types> range_rec; range_rec.first = prev_gid; range_rec.last = prev_gid; range_rec.value = prev_klass; - RangeRecord *record = c->copy (range_rec); + auto *record = c->copy (range_rec); if (unlikely (!record)) return_trace (false); for (const auto gid_klass_pair : + (++it)) @@ -2202,13 +1716,14 @@ struct ClassDefFormat2 hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass; hb_set_t orig_klasses; + unsigned num_source_glyphs = c->plan->source->get_num_glyphs (); unsigned count = rangeRecord.len; for (unsigned i = 0; i < count; i++) { unsigned klass = rangeRecord[i].value; if (!klass) continue; hb_codepoint_t start = rangeRecord[i].first; - hb_codepoint_t end = rangeRecord[i].last + 1; + hb_codepoint_t end = hb_min (rangeRecord[i].last + 1, num_source_glyphs); for (hb_codepoint_t g = start; g < end; g++) { hb_codepoint_t new_gid = glyph_map[g]; @@ -2272,7 +1787,7 @@ struct ClassDefFormat2 for (unsigned int i = 0; i < count; i++) { const auto& range = rangeRecord[i]; - if (range.intersects (glyphs) && range.value) + if (range.intersects (*glyphs) && range.value) return true; } return false; @@ -2296,11 +1811,8 @@ struct ClassDefFormat2 return true; /* Fall through. */ } - /* TODO Speed up, using set overlap first? */ - /* TODO(iter) Rewrite as dagger. */ - const RangeRecord *arr = rangeRecord.arrayZ; - for (unsigned int i = 0; i < count; i++) - if (arr[i].value == klass && arr[i].intersects (glyphs)) + for (const auto &range : rangeRecord) + if (range.value == klass && range.intersects (*glyphs)) return true; return false; } @@ -2374,18 +1886,18 @@ struct ClassDefFormat2 if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) intersect_classes->add (0); - for (const RangeRecord& record : rangeRecord.iter ()) - if (record.intersects (glyphs)) + for (const auto& record : rangeRecord.iter ()) + if (record.intersects (*glyphs)) intersect_classes->add (record.value); } protected: HBUINT16 classFormat; /* Format identifier--format = 2 */ - SortedArray16Of<RangeRecord> + typename Types::template SortedArrayOf<RangeRecord<Types>> rangeRecord; /* Array of glyph ranges--ordered by * Start GlyphID */ public: - DEFINE_SIZE_ARRAY (4, rangeRecord); + DEFINE_SIZE_ARRAY (2 + Types::size, rangeRecord); }; struct ClassDef @@ -2404,12 +1916,16 @@ struct ClassDef switch (u.format) { case 1: return u.format1.get_class (glyph_id); case 2: return u.format2.get_class (glyph_id); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.get_class (glyph_id); + case 4: return u.format4.get_class (glyph_id); +#endif default:return 0; } } template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator it_with_class_zero) { TRACE_SERIALIZE (this); @@ -2418,10 +1934,11 @@ struct ClassDef auto it = + it_with_class_zero | hb_filter (hb_second); unsigned format = 2; + hb_codepoint_t glyph_max = 0; if (likely (it)) { hb_codepoint_t glyph_min = (*it).first; - hb_codepoint_t glyph_max = glyph_min; + glyph_max = glyph_min; unsigned num_glyphs = 0; unsigned num_ranges = 1; @@ -2446,12 +1963,22 @@ struct ClassDef if (num_glyphs && 1 + (glyph_max - glyph_min + 1) <= num_ranges * 3) format = 1; } + +#ifndef HB_NO_BEYOND_64K + if (glyph_max > 0xFFFFu) + format += 2; +#endif + u.format = format; switch (u.format) { case 1: return_trace (u.format1.serialize (c, it)); case 2: return_trace (u.format2.serialize (c, it)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.serialize (c, it)); + case 4: return_trace (u.format4.serialize (c, it)); +#endif default:return_trace (false); } } @@ -2466,6 +1993,10 @@ struct ClassDef switch (u.format) { case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 4: return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); +#endif default:return_trace (false); } } @@ -2477,6 +2008,10 @@ struct ClassDef switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.sanitize (c)); + case 4: return_trace (u.format4.sanitize (c)); +#endif default:return_trace (true); } } @@ -2486,6 +2021,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.cost (); case 2: return u.format2.cost (); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.cost (); + case 4: return u.format4.cost (); +#endif default:return 0u; } } @@ -2498,6 +2037,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.collect_coverage (glyphs); case 2: return u.format2.collect_coverage (glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.collect_coverage (glyphs); + case 4: return u.format4.collect_coverage (glyphs); +#endif default:return false; } } @@ -2510,6 +2053,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.collect_class (glyphs, klass); case 2: return u.format2.collect_class (glyphs, klass); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.collect_class (glyphs, klass); + case 4: return u.format4.collect_class (glyphs, klass); +#endif default:return false; } } @@ -2519,6 +2066,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.intersects (glyphs); case 2: return u.format2.intersects (glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersects (glyphs); + case 4: return u.format4.intersects (glyphs); +#endif default:return false; } } @@ -2527,6 +2078,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.intersects_class (glyphs, klass); case 2: return u.format2.intersects_class (glyphs, klass); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersects_class (glyphs, klass); + case 4: return u.format4.intersects_class (glyphs, klass); +#endif default:return false; } } @@ -2536,6 +2091,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 4: return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs); +#endif default:return; } } @@ -2545,6 +2104,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.intersected_classes (glyphs, intersect_classes); case 2: return u.format2.intersected_classes (glyphs, intersect_classes); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersected_classes (glyphs, intersect_classes); + case 4: return u.format4.intersected_classes (glyphs, intersect_classes); +#endif default:return; } } @@ -2552,9 +2115,13 @@ struct ClassDef protected: union { - HBUINT16 format; /* Format identifier */ - ClassDefFormat1 format1; - ClassDefFormat2 format2; + HBUINT16 format; /* Format identifier */ + ClassDefFormat1_3<SmallTypes> format1; + ClassDefFormat2_4<SmallTypes> format2; +#ifndef HB_NO_BEYOND_64K + ClassDefFormat1_3<MediumTypes>format3; + ClassDefFormat2_4<MediumTypes>format4; +#endif } u; public: DEFINE_SIZE_UNION (2, format); @@ -2940,6 +2507,9 @@ struct VariationStore cache_t *create_cache () const { +#ifdef HB_NO_VAR + return nullptr; +#endif auto &r = this+regions; unsigned count = r.regionCount; @@ -3000,6 +2570,10 @@ struct VariationStore const hb_array_t <hb_inc_bimap_t> &inner_maps) { TRACE_SERIALIZE (this); +#ifdef HB_NO_VAR + return_trace (false); +#endif + if (unlikely (!c->extend_min (this))) return_trace (false); unsigned int set_count = 0; @@ -3051,6 +2625,9 @@ struct VariationStore bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); +#ifdef HB_NO_VAR + return_trace (false); +#endif VariationStore *varstore_prime = c->serializer->start_embed<VariationStore> (); if (unlikely (!varstore_prime)) return_trace (false); @@ -3078,7 +2655,12 @@ struct VariationStore } unsigned int get_region_index_count (unsigned int major) const - { return (this+dataSets[major]).get_region_index_count (); } + { +#ifdef HB_NO_VAR + return 0; +#endif + return (this+dataSets[major]).get_region_index_count (); + } void get_region_scalars (unsigned int major, const int *coords, unsigned int coord_count, @@ -3096,7 +2678,13 @@ struct VariationStore &scalars[0], num_scalars); } - unsigned int get_sub_table_count () const { return dataSets.len; } + unsigned int get_sub_table_count () const + { +#ifdef HB_NO_VAR + return 0; +#endif + return dataSets.len; + } protected: HBUINT16 format; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh index 9d47bac2b9..5bc26d9182 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh @@ -510,6 +510,101 @@ struct MarkGlyphSets */ +template <typename Types> +struct GDEFVersion1_2 +{ + friend struct GDEF; + + protected: + FixedVersion<>version; /* Version of the GDEF table--currently + * 0x00010003u */ + typename Types::template OffsetTo<ClassDef> + glyphClassDef; /* Offset to class definition table + * for glyph type--from beginning of + * GDEF header (may be Null) */ + typename Types::template OffsetTo<AttachList> + attachList; /* Offset to list of glyphs with + * attachment points--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo<LigCaretList> + ligCaretList; /* Offset to list of positioning points + * for ligature carets--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo<ClassDef> + markAttachClassDef; /* Offset to class definition table for + * mark attachment type--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo<MarkGlyphSets> + markGlyphSetsDef; /* Offset to the table of mark set + * definitions--from beginning of GDEF + * header (may be NULL). Introduced + * in version 0x00010002. */ + Offset32To<VariationStore> + varStore; /* Offset to the table of Item Variation + * Store--from beginning of GDEF + * header (may be NULL). Introduced + * in version 0x00010003. */ + public: + DEFINE_SIZE_MIN (4 + 4 * Types::size); + + unsigned int get_size () const + { + return min_size + + (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) + + (version.to_int () >= 0x00010003u ? varStore.static_size : 0); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + glyphClassDef.sanitize (c, this) && + attachList.sanitize (c, this) && + ligCaretList.sanitize (c, this) && + markAttachClassDef.sanitize (c, this) && + (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && + (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); + bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); + bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); + + bool subset_markglyphsetsdef = false; + if (version.to_int () >= 0x00010002u) + { + subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); + } + + bool subset_varstore = false; + if (version.to_int () >= 0x00010003u) + { + subset_varstore = out->varStore.serialize_subset (c, varStore, this); + } + + if (subset_varstore) + { + out->version.minor = 3; + } else if (subset_markglyphsetsdef) { + out->version.minor = 2; + } else { + out->version.minor = 0; + } + + return_trace (subset_glyphclassdef || subset_attachlist || + subset_ligcaretlist || subset_markattachclassdef || + (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) || + (out->version.to_int () >= 0x00010003u && subset_varstore)); + } +}; + struct GDEF { static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF; @@ -522,42 +617,190 @@ struct GDEF ComponentGlyph = 4 }; - bool has_data () const { return version.to_int (); } - bool has_glyph_classes () const { return glyphClassDef != 0; } + unsigned int get_size () const + { + switch (u.version.major) { + case 1: return u.version1.get_size (); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.get_size (); +#endif + default: return u.version.static_size; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!u.version.sanitize (c))) return_trace (false); + switch (u.version.major) { + case 1: return_trace (u.version1.sanitize (c)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (u.version2.sanitize (c)); +#endif + default: return_trace (true); + } + } + + bool subset (hb_subset_context_t *c) const + { + switch (u.version.major) { + case 1: return u.version1.subset (c); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.subset (c); +#endif + default: return false; + } + } + + bool has_glyph_classes () const + { + switch (u.version.major) { + case 1: return u.version1.glyphClassDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.glyphClassDef != 0; +#endif + default: return false; + } + } + const ClassDef &get_glyph_class_def () const + { + switch (u.version.major) { + case 1: return this+u.version1.glyphClassDef; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.glyphClassDef; +#endif + default: return Null(ClassDef); + } + } + bool has_attach_list () const + { + switch (u.version.major) { + case 1: return u.version1.attachList != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.attachList != 0; +#endif + default: return false; + } + } + const AttachList &get_attach_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.attachList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.attachList; +#endif + default: return Null(AttachList); + } + } + bool has_lig_carets () const + { + switch (u.version.major) { + case 1: return u.version1.ligCaretList != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.ligCaretList != 0; +#endif + default: return false; + } + } + const LigCaretList &get_lig_caret_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.ligCaretList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.ligCaretList; +#endif + default: return Null(LigCaretList); + } + } + bool has_mark_attachment_types () const + { + switch (u.version.major) { + case 1: return u.version1.markAttachClassDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.markAttachClassDef != 0; +#endif + default: return false; + } + } + const ClassDef &get_mark_attach_class_def () const + { + switch (u.version.major) { + case 1: return this+u.version1.markAttachClassDef; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.markAttachClassDef; +#endif + default: return Null(ClassDef); + } + } + bool has_mark_glyph_sets () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.markGlyphSetsDef != 0; +#endif + default: return false; + } + } + const MarkGlyphSets &get_mark_glyph_sets () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets); +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.markGlyphSetsDef; +#endif + default: return Null(MarkGlyphSets); + } + } + bool has_var_store () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.varStore != 0; +#endif + default: return false; + } + } + const VariationStore &get_var_store () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore); +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.varStore; +#endif + default: return Null(VariationStore); + } + } + + + bool has_data () const { return u.version.to_int (); } unsigned int get_glyph_class (hb_codepoint_t glyph) const - { return (this+glyphClassDef).get_class (glyph); } + { return get_glyph_class_def ().get_class (glyph); } void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const - { (this+glyphClassDef).collect_class (glyphs, klass); } + { get_glyph_class_def ().collect_class (glyphs, klass); } - bool has_mark_attachment_types () const { return markAttachClassDef != 0; } unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const - { return (this+markAttachClassDef).get_class (glyph); } + { return get_mark_attach_class_def ().get_class (glyph); } - bool has_attach_points () const { return attachList != 0; } unsigned int get_attach_points (hb_codepoint_t glyph_id, unsigned int start_offset, unsigned int *point_count /* IN/OUT */, unsigned int *point_array /* OUT */) const - { return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); } + { return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); } - bool has_lig_carets () const { return ligCaretList != 0; } unsigned int get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const - { return (this+ligCaretList).get_lig_carets (font, - direction, glyph_id, get_var_store(), - start_offset, caret_count, caret_array); } + { return get_lig_caret_list ().get_lig_carets (font, + direction, glyph_id, get_var_store(), + start_offset, caret_count, caret_array); } - bool has_mark_sets () const { return version.to_int () >= 0x00010002u && markGlyphSetsDef != 0; } bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const - { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef).covers (set_index, glyph_id); } - - bool has_var_store () const { return version.to_int () >= 0x00010003u && varStore != 0; } - const VariationStore &get_var_store () const - { return version.to_int () >= 0x00010003u ? this+varStore : Null (VariationStore); } + { return get_mark_glyph_sets ().covers (set_index, glyph_id); } /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing * glyph class and other bits, and high 8-bit the mark attachment type (if any). @@ -599,20 +842,13 @@ struct GDEF hb_blob_ptr_t<GDEF> table; }; - unsigned int get_size () const - { - return min_size + - (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) + - (version.to_int () >= 0x00010003u ? varStore.static_size : 0); - } - void collect_variation_indices (hb_collect_variation_indices_context_t *c) const - { (this+ligCaretList).collect_variation_indices (c); } + { get_lig_caret_list ().collect_variation_indices (c); } void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, hb_map_t *layout_variation_idx_map /* OUT */) const { - if (version.to_int () < 0x00010003u || !varStore) return; + if (!has_var_store ()) return; if (layout_variation_indices->is_empty ()) return; unsigned new_major = 0, new_minor = 0; @@ -620,7 +856,7 @@ struct GDEF for (unsigned idx : layout_variation_indices->iter ()) { uint16_t major = idx >> 16; - if (major >= (this+varStore).get_sub_table_count ()) break; + if (major >= get_var_store ().get_sub_table_count ()) break; if (major != last_major) { new_minor = 0; @@ -634,84 +870,16 @@ struct GDEF } } - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - - bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); - bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); - bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); - bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); - - bool subset_markglyphsetsdef = true; - if (version.to_int () >= 0x00010002u) - { - subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); - if (!subset_markglyphsetsdef && - version.to_int () == 0x00010002u) - out->version.minor = 0; - } - - bool subset_varstore = true; - if (version.to_int () >= 0x00010003u) - { - subset_varstore = out->varStore.serialize_subset (c, varStore, this); - if (!subset_varstore && version.to_int () == 0x00010003u) - out->version.minor = 2; - } - - return_trace (subset_glyphclassdef || subset_attachlist || - subset_ligcaretlist || subset_markattachclassdef || - (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) || - (out->version.to_int () >= 0x00010003u && subset_varstore)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (version.sanitize (c) && - likely (version.major == 1) && - glyphClassDef.sanitize (c, this) && - attachList.sanitize (c, this) && - ligCaretList.sanitize (c, this) && - markAttachClassDef.sanitize (c, this) && - (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && - (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); - } - protected: - FixedVersion<>version; /* Version of the GDEF table--currently - * 0x00010003u */ - Offset16To<ClassDef> - glyphClassDef; /* Offset to class definition table - * for glyph type--from beginning of - * GDEF header (may be Null) */ - Offset16To<AttachList> - attachList; /* Offset to list of glyphs with - * attachment points--from beginning - * of GDEF header (may be Null) */ - Offset16To<LigCaretList> - ligCaretList; /* Offset to list of positioning points - * for ligature carets--from beginning - * of GDEF header (may be Null) */ - Offset16To<ClassDef> - markAttachClassDef; /* Offset to class definition table for - * mark attachment type--from beginning - * of GDEF header (may be Null) */ - Offset16To<MarkGlyphSets> - markGlyphSetsDef; /* Offset to the table of mark set - * definitions--from beginning of GDEF - * header (may be NULL). Introduced - * in version 0x00010002. */ - Offset32To<VariationStore> - varStore; /* Offset to the table of Item Variation - * Store--from beginning of GDEF - * header (may be NULL). Introduced - * in version 0x00010003. */ + union { + FixedVersion<> version; /* Version identifier */ + GDEFVersion1_2<SmallTypes> version1; +#ifndef HB_NO_BEYOND_64K + GDEFVersion1_2<MediumTypes> version2; +#endif + } u; public: - DEFINE_SIZE_MIN (12); + DEFINE_SIZE_MIN (4); }; struct GDEF_accelerator_t : GDEF::accelerator_t { diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh index 064d31cdff..8fe987fc50 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh @@ -29,11 +29,11 @@ #ifndef HB_OT_LAYOUT_GPOS_TABLE_HH #define HB_OT_LAYOUT_GPOS_TABLE_HH -#include "OT/Layout/GPOS.hh" +#include "OT/Layout/GPOS/GPOS.hh" namespace OT { - -using Layout::GPOS_impl::PosLookup; +namespace Layout { +namespace GPOS_impl { // TODO(garretrieger): Move into new layout directory. /* Out-of-class implementation for methods recursing */ @@ -68,6 +68,8 @@ inline bool PosLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply } #endif +} /* namespace GPOS_impl */ +} /* namespace Layout */ } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh index 462542025b..50301ff1d9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh @@ -32,9 +32,8 @@ #include "OT/Layout/GSUB/GSUB.hh" namespace OT { - -using Layout::GSUB::SubstLookup; -using Layout::GSUB::ExtensionSubst; +namespace Layout { +namespace GSUB_impl { // TODO(garretrieger): Move into the new layout directory. /* Out-of-class implementation for methods recursing */ @@ -82,7 +81,8 @@ inline bool SubstLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_app } #endif - +} /* namespace GSUB_impl */ +} /* namespace Layout */ } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index 31da498652..5acd228b83 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -150,7 +150,7 @@ struct hb_closure_context_t : bool pop_cur_done_glyphs () { - if (active_glyphs_stack.length < 1) + if (!active_glyphs_stack) return false; active_glyphs_stack.pop (); @@ -409,7 +409,7 @@ struct hb_ot_apply_context_t : match_func (nullptr), match_data (nullptr) {} - typedef bool (*match_func_t) (hb_glyph_info_t &info, const HBUINT16 &value, const void *data); + typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } @@ -428,14 +428,14 @@ struct hb_ot_apply_context_t : }; may_match_t may_match (hb_glyph_info_t &info, - const HBUINT16 *glyph_data) const + hb_codepoint_t glyph_data) const { if (!(info.mask & mask) || (syllable && syllable != info.syllable ())) return MATCH_NO; if (match_func) - return match_func (info, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; + return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; return MATCH_MAYBE; } @@ -476,7 +476,10 @@ struct hb_ot_apply_context_t : void init (hb_ot_apply_context_t *c_, bool context_match = false) { c = c_; - match_glyph_data = nullptr; + match_glyph_data16 = nullptr; +#ifndef HB_NO_BEYOND_64K + match_glyph_data24 = nullptr; +#endif matcher.set_match_func (nullptr, nullptr); matcher.set_lookup_props (c->lookup_props); /* Ignore ZWNJ if we are matching GPOS, or matching GSUB context and asked to. */ @@ -491,12 +494,24 @@ struct hb_ot_apply_context_t : matcher.set_lookup_props (lookup_props); } void set_match_func (matcher_t::match_func_t match_func_, - const void *match_data_, - const HBUINT16 glyph_data[]) + const void *match_data_) { matcher.set_match_func (match_func_, match_data_); - match_glyph_data = glyph_data; } + void set_glyph_data (const HBUINT16 glyph_data[]) + { + match_glyph_data16 = glyph_data; +#ifndef HB_NO_BEYOND_64K + match_glyph_data24 = nullptr; +#endif + } +#ifndef HB_NO_BEYOND_64K + void set_glyph_data (const HBUINT24 glyph_data[]) + { + match_glyph_data16 = nullptr; + match_glyph_data24 = glyph_data; + } +#endif void reset (unsigned int start_index_, unsigned int num_items_) @@ -510,7 +525,7 @@ struct hb_ot_apply_context_t : void reject () { num_items++; - if (match_glyph_data) match_glyph_data--; + backup_glyph_data (); } matcher_t::may_skip_t @@ -529,13 +544,13 @@ struct hb_ot_apply_context_t : if (unlikely (skip == matcher_t::SKIP_YES)) continue; - matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); + matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); if (match == matcher_t::MATCH_YES || (match == matcher_t::MATCH_MAYBE && skip == matcher_t::SKIP_NO)) { num_items--; - if (match_glyph_data) match_glyph_data++; + advance_glyph_data (); return true; } @@ -562,13 +577,13 @@ struct hb_ot_apply_context_t : if (unlikely (skip == matcher_t::SKIP_YES)) continue; - matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); + matcher_t::may_match_t match = matcher.may_match (info, get_glyph_data ()); if (match == matcher_t::MATCH_YES || (match == matcher_t::MATCH_MAYBE && skip == matcher_t::SKIP_NO)) { num_items--; - if (match_glyph_data) match_glyph_data++; + advance_glyph_data (); return true; } @@ -584,11 +599,43 @@ struct hb_ot_apply_context_t : return false; } + hb_codepoint_t + get_glyph_data () + { + if (match_glyph_data16) return *match_glyph_data16; +#ifndef HB_NO_BEYOND_64K + else + if (match_glyph_data24) return *match_glyph_data24; +#endif + return 0; + } + void + advance_glyph_data () + { + if (match_glyph_data16) match_glyph_data16++; +#ifndef HB_NO_BEYOND_64K + else + if (match_glyph_data24) match_glyph_data24++; +#endif + } + void + backup_glyph_data () + { + if (match_glyph_data16) match_glyph_data16--; +#ifndef HB_NO_BEYOND_64K + else + if (match_glyph_data24) match_glyph_data24--; +#endif + } + unsigned int idx; protected: hb_ot_apply_context_t *c; matcher_t matcher; - const HBUINT16 *match_glyph_data; + const HBUINT16 *match_glyph_data16; +#ifndef HB_NO_BEYOND_64K + const HBUINT24 *match_glyph_data24; +#endif unsigned int num_items; unsigned int end; @@ -941,10 +988,10 @@ struct hb_accelerate_subtables_context_t : }; -typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data); +typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data); typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs); -typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data); -typedef bool (*match_func_t) (hb_glyph_info_t &info, const HBUINT16 &value, const void *data); +typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, unsigned value, const void *data); +typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); struct ContextClosureFuncs { @@ -965,18 +1012,19 @@ struct ChainContextApplyFuncs }; -static inline bool intersects_glyph (const hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) +static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED) { return glyphs->has (value); } -static inline bool intersects_class (const hb_set_t *glyphs, const HBUINT16 &value, const void *data) +static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); return class_def.intersects_class (glyphs, value); } -static inline bool intersects_coverage (const hb_set_t *glyphs, const HBUINT16 &value, const void *data) +static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data) { - const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; + Offset16To<Coverage> coverage; + coverage = value; return (data+coverage).intersects (glyphs); } @@ -995,60 +1043,63 @@ static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const vo { Offset16To<Coverage> coverage; coverage = value; - (data+coverage).intersected_coverage_glyphs (glyphs, intersected_glyphs); + (data+coverage).intersect_set (*glyphs, *intersected_glyphs); } +template <typename HBUINT> static inline bool array_is_subset_of (const hb_set_t *glyphs, unsigned int count, - const HBUINT16 values[], + const HBUINT values[], intersects_func_t intersects_func, const void *intersects_data) { - for (const HBUINT16 &_ : + hb_iter (values, count)) + for (const auto &_ : + hb_iter (values, count)) if (!intersects_func (glyphs, _, intersects_data)) return false; return true; } -static inline void collect_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) +static inline void collect_glyph (hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED) { glyphs->add (value); } -static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data) +static inline void collect_class (hb_set_t *glyphs, unsigned value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); class_def.collect_class (glyphs, value); } -static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data) +static inline void collect_coverage (hb_set_t *glyphs, unsigned value, const void *data) { - const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; + Offset16To<Coverage> coverage; + coverage = value; (data+coverage).collect_coverage (glyphs); } +template <typename HBUINT> static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, hb_set_t *glyphs, unsigned int count, - const HBUINT16 values[], + const HBUINT values[], collect_glyphs_func_t collect_func, const void *collect_data) { return + hb_iter (values, count) - | hb_apply ([&] (const HBUINT16 &_) { collect_func (glyphs, _, collect_data); }) + | hb_apply ([&] (const HBUINT &_) { collect_func (glyphs, _, collect_data); }) ; } -static inline bool match_glyph (hb_glyph_info_t &info, const HBUINT16 &value, const void *data HB_UNUSED) +static inline bool match_glyph (hb_glyph_info_t &info, unsigned value, const void *data HB_UNUSED) { return info.codepoint == value; } -static inline bool match_class (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) +static inline bool match_class (hb_glyph_info_t &info, unsigned value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); return class_def.get_class (info.codepoint) == value; } -static inline bool match_class_cached (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) +static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) { unsigned klass = info.syllable(); if (klass < 255) @@ -1059,15 +1110,17 @@ static inline bool match_class_cached (hb_glyph_info_t &info, const HBUINT16 &va info.syllable() = klass; return klass == value; } -static inline bool match_coverage (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) +static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data) { - const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; + Offset16To<Coverage> coverage; + coverage = value; return (data+coverage).get_coverage (info.codepoint) != NOT_COVERED; } +template <typename HBUINT> static inline bool would_match_input (hb_would_apply_context_t *c, unsigned int count, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data) { @@ -1084,9 +1137,10 @@ static inline bool would_match_input (hb_would_apply_context_t *c, return true; } +template <typename HBUINT> static inline bool match_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data, unsigned int *end_position, @@ -1101,7 +1155,8 @@ static inline bool match_input (hb_ot_apply_context_t *c, hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, count - 1); - skippy_iter.set_match_func (match_func, match_data, input); + skippy_iter.set_match_func (match_func, match_data); + skippy_iter.set_glyph_data (input); /* * This is perhaps the trickiest part of OpenType... Remarks: @@ -1322,9 +1377,10 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, return_trace (true); } +template <typename HBUINT> static inline bool match_backtrack (hb_ot_apply_context_t *c, unsigned int count, - const HBUINT16 backtrack[], + const HBUINT backtrack[], match_func_t match_func, const void *match_data, unsigned int *match_start) @@ -1333,7 +1389,8 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c, hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->backtrack_len (), count); - skippy_iter.set_match_func (match_func, match_data, backtrack); + skippy_iter.set_match_func (match_func, match_data); + skippy_iter.set_glyph_data (backtrack); for (unsigned int i = 0; i < count; i++) { @@ -1349,9 +1406,10 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c, return_trace (true); } +template <typename HBUINT> static inline bool match_lookahead (hb_ot_apply_context_t *c, unsigned int count, - const HBUINT16 lookahead[], + const HBUINT lookahead[], match_func_t match_func, const void *match_data, unsigned int start_index, @@ -1361,7 +1419,8 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c, hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; skippy_iter.reset (start_index - 1, count); - skippy_iter.set_match_func (match_func, match_data, lookahead); + skippy_iter.set_match_func (match_func, match_data); + skippy_iter.set_glyph_data (lookahead); for (unsigned int i = 0; i < count; i++) { @@ -1425,8 +1484,9 @@ static unsigned serialize_lookuprecord_array (hb_serialize_context_t *c, enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 }; +template <typename HBUINT> static void context_closure_recurse_lookups (hb_closure_context_t *c, - unsigned inputCount, const HBUINT16 input[], + unsigned inputCount, const HBUINT input[], unsigned lookupCount, const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */, unsigned value, @@ -1645,9 +1705,10 @@ struct ContextApplyLookupContext const void *match_data; }; +template <typename HBUINT> static inline bool context_intersects (const hb_set_t *glyphs, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ ContextClosureLookupContext &lookup_context) { return array_is_subset_of (glyphs, @@ -1655,9 +1716,10 @@ static inline bool context_intersects (const hb_set_t *glyphs, lookup_context.funcs.intersects, lookup_context.intersects_data); } +template <typename HBUINT> static inline void context_closure_lookup (hb_closure_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], unsigned value, /* Index of first glyph in Coverage or Class value in ClassDef table */ @@ -1675,9 +1737,10 @@ static inline void context_closure_lookup (hb_closure_context_t *c, lookup_context.funcs.intersected_glyphs); } +template <typename HBUINT> static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextCollectGlyphsLookupContext &lookup_context) @@ -1689,9 +1752,10 @@ static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c lookupCount, lookupRecord); } +template <typename HBUINT> static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, ContextApplyLookupContext &lookup_context) @@ -1700,9 +1764,11 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data); } + +template <typename HBUINT> static inline bool context_apply_lookup (hb_ot_apply_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextApplyLookupContext &lookup_context) @@ -1728,6 +1794,7 @@ static inline bool context_apply_lookup (hb_ot_apply_context_t *c, } } +template <typename Types> struct Rule { bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const @@ -1741,8 +1808,8 @@ struct Rule { if (unlikely (c->lookup_limit_exceeded ())) return; - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); context_closure_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, @@ -1755,16 +1822,16 @@ struct Rule if (unlikely (c->lookup_limit_exceeded ())) return; if (!intersects (c->glyphs, lookup_context)) return; - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); recurse_lookups (c, lookupCount, lookupRecord.arrayZ); } void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const { - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); context_collect_glyphs_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, @@ -1774,8 +1841,8 @@ struct Rule bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); return context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, @@ -1786,8 +1853,8 @@ struct Rule ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } @@ -1800,7 +1867,7 @@ struct Rule if (unlikely (!c->extend_min (out))) return_trace (false); out->inputCount = inputCount; - const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1); + const auto input = inputZ.as_array (inputCount - 1); for (const auto org : input) { HBUINT16 d; @@ -1808,8 +1875,8 @@ struct Rule c->copy (d); } - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (lookupCount), lookup_map); return_trace (c->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); @@ -1821,7 +1888,7 @@ struct Rule { TRACE_SUBSET (this); if (unlikely (!inputCount)) return_trace (false); - const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1); + const auto input = inputZ.as_array (inputCount - 1); const hb_map_t *mapping = klass_map == nullptr ? c->plan->glyph_map : klass_map; if (!hb_all (input, mapping)) return_trace (false); @@ -1844,7 +1911,7 @@ struct Rule * glyph sequence--includes the first * glyph */ HBUINT16 lookupCount; /* Number of LookupRecords */ - UnsizedArrayOf<HBUINT16> + UnsizedArrayOf<typename Types::HBUINT> inputZ; /* Array of match inputs--start with * second glyph */ /*UnsizedArrayOf<LookupRecord> @@ -1854,8 +1921,11 @@ struct Rule DEFINE_SIZE_ARRAY (4, inputZ); }; +template <typename Types> struct RuleSet { + using Rule = OT::Rule<Types>; + bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const { @@ -1968,8 +2038,11 @@ struct RuleSet }; -struct ContextFormat1 +template <typename Types> +struct ContextFormat1_4 { + using RuleSet = OT::RuleSet<Types>; + bool intersects (const hb_set_t *glyphs) const { struct ContextClosureLookupContext lookup_context = { @@ -1993,9 +2066,8 @@ struct ContextFormat1 void closure (hb_closure_context_t *c) const { - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), - cur_active_glyphs); + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); struct ContextClosureLookupContext lookup_context = { {intersects_glyph, intersected_glyph}, @@ -2106,19 +2178,22 @@ struct ContextFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - Array16OfOffset16To<RuleSet> + Array16Of<typename Types::template OffsetTo<RuleSet>> ruleSet; /* Array of RuleSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, ruleSet); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, ruleSet); }; -struct ContextFormat2 +template <typename Types> +struct ContextFormat2_5 { + using RuleSet = OT::RuleSet<SmallTypes>; + bool intersects (const hb_set_t *glyphs) const { if (!(this+coverage).intersects (glyphs)) @@ -2133,7 +2208,7 @@ struct ContextFormat2 }; hb_set_t retained_coverage_glyphs; - (this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs); + (this+coverage).intersect_set (*glyphs, retained_coverage_glyphs); hb_set_t coverage_glyph_classes; class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); @@ -2159,8 +2234,8 @@ struct ContextFormat2 if (!(this+coverage).intersects (c->glyphs)) return; - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); const ClassDef &class_def = this+classDef; @@ -2175,7 +2250,7 @@ struct ContextFormat2 | hb_filter ([&] (unsigned _) { return class_def.intersects_class (&c->parent_active_glyphs (), _); }, hb_first) - | hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<RuleSet>&> _) + | hb_apply ([&] (const hb_pair_t<unsigned, const typename Types::template OffsetTo<RuleSet>&> _) { const RuleSet& rule_set = this+_.second; rule_set.closure (c, _.first, lookup_context); @@ -2305,7 +2380,7 @@ struct ContextFormat2 const hb_set_t* glyphset = c->plan->glyphset_gsub (); hb_set_t retained_coverage_glyphs; - (this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs); + (this+coverage).intersect_set (*glyphset, retained_coverage_glyphs); hb_set_t coverage_glyph_classes; (this+classDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); @@ -2351,22 +2426,24 @@ struct ContextFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> classDef; /* Offset to glyph ClassDef table--from * beginning of table */ - Array16OfOffset16To<RuleSet> + Array16Of<typename Types::template OffsetTo<RuleSet>> ruleSet; /* Array of RuleSet tables * ordered by class */ public: - DEFINE_SIZE_ARRAY (8, ruleSet); + DEFINE_SIZE_ARRAY (4 + 2 * Types::size, ruleSet); }; struct ContextFormat3 { + using RuleSet = OT::RuleSet<SmallTypes>; + bool intersects (const hb_set_t *glyphs) const { if (!(this+coverageZ[0]).intersects (glyphs)) @@ -2390,8 +2467,8 @@ struct ContextFormat3 if (!(this+coverageZ[0]).intersects (c->glyphs)) return; - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); @@ -2483,7 +2560,7 @@ struct ContextFormat3 if (!o->serialize_subset (c, offset, this)) return_trace (false); } - const UnsizedArrayOf<LookupRecord>& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount)); + const auto& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount)); const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; @@ -2530,16 +2607,24 @@ struct Context case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); + case 5: return_trace (c->dispatch (u.format5, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } protected: union { - HBUINT16 format; /* Format identifier */ - ContextFormat1 format1; - ContextFormat2 format2; - ContextFormat3 format3; + HBUINT16 format; /* Format identifier */ + ContextFormat1_4<SmallTypes> format1; + ContextFormat2_5<SmallTypes> format2; + ContextFormat3 format3; +#ifndef HB_NO_BEYOND_64K + ContextFormat1_4<MediumTypes> format4; + ContextFormat2_5<MediumTypes> format5; +#endif } u; }; @@ -2565,13 +2650,14 @@ struct ChainContextApplyLookupContext const void *match_data[3]; }; +template <typename HBUINT> static inline bool chain_context_intersects (const hb_set_t *glyphs, unsigned int backtrackCount, - const HBUINT16 backtrack[], + const HBUINT backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[], + const HBUINT lookahead[], ChainContextClosureLookupContext &lookup_context) { return array_is_subset_of (glyphs, @@ -2585,13 +2671,14 @@ static inline bool chain_context_intersects (const hb_set_t *glyphs, lookup_context.funcs.intersects, lookup_context.intersects_data[2]); } +template <typename HBUINT> static inline void chain_context_closure_lookup (hb_closure_context_t *c, unsigned int backtrackCount, - const HBUINT16 backtrack[], + const HBUINT backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[], + const HBUINT lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], unsigned value, @@ -2611,13 +2698,14 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, lookup_context.funcs.intersected_glyphs); } +template <typename HBUINT> static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int backtrackCount, - const HBUINT16 backtrack[], + const HBUINT backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[], + const HBUINT lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextCollectGlyphsLookupContext &lookup_context) @@ -2635,13 +2723,14 @@ static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_contex lookupCount, lookupRecord); } +template <typename HBUINT> static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, unsigned int backtrackCount, - const HBUINT16 backtrack[] HB_UNUSED, + const HBUINT backtrack[] HB_UNUSED, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[] HB_UNUSED, + const HBUINT lookahead[] HB_UNUSED, unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, ChainContextApplyLookupContext &lookup_context) @@ -2652,13 +2741,14 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c lookup_context.funcs.match[1], lookup_context.match_data[1]); } +template <typename HBUINT> static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, unsigned int backtrackCount, - const HBUINT16 backtrack[], + const HBUINT backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[], + const HBUINT lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextApplyLookupContext &lookup_context) @@ -2697,12 +2787,13 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, return true; } +template <typename Types> struct ChainRule { bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const { - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); return chain_context_intersects (glyphs, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2715,9 +2806,9 @@ struct ChainRule { if (unlikely (c->lookup_limit_exceeded ())) return; - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2733,18 +2824,18 @@ struct ChainRule if (unlikely (c->lookup_limit_exceeded ())) return; if (!intersects (c->glyphs, lookup_context)) return; - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); recurse_lookups (c, lookup.len, lookup.arrayZ); } void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const { - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2756,9 +2847,9 @@ struct ChainRule bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); return chain_context_would_apply_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2769,9 +2860,9 @@ struct ChainRule bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2804,22 +2895,22 @@ struct ChainRule serialize_array (c, backtrack.len, + backtrack.iter () | hb_map (mapping)); - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (input_map) mapping = input_map; serialize_array (c, input.lenP1, + input.iter () | hb_map (mapping)); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (lookahead_map) mapping = lookahead_map; serialize_array (c, lookahead.len, + lookahead.iter () | hb_map (mapping)); - const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); - HBUINT16* lookupCount = c->embed (&(lookupRecord.len)); + HBUINT16* lookupCount = c->embed (&(lookup.len)); if (!lookupCount) return_trace (false); - unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (), lookup_map); + unsigned count = serialize_lookuprecord_array (c, lookup.as_array (), lookup_map); return_trace (c->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } @@ -2831,8 +2922,8 @@ struct ChainRule { TRACE_SUBSET (this); - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (!backtrack_map) { @@ -2861,23 +2952,23 @@ struct ChainRule { TRACE_SANITIZE (this); if (!backtrack.sanitize (c)) return_trace (false); - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!input.sanitize (c)) return_trace (false); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (!lookahead.sanitize (c)) return_trace (false); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); return_trace (lookup.sanitize (c)); } protected: - Array16Of<HBUINT16> + Array16Of<typename Types::HBUINT> backtrack; /* Array of backtracking values * (to be matched before the input * sequence) */ - HeadlessArrayOf<HBUINT16> + HeadlessArrayOf<typename Types::HBUINT> inputX; /* Array of input values (start with * second glyph) */ - Array16Of<HBUINT16> + Array16Of<typename Types::HBUINT> lookaheadX; /* Array of lookahead values's (to be * matched after the input sequence) */ Array16Of<LookupRecord> @@ -2887,8 +2978,11 @@ struct ChainRule DEFINE_SIZE_MIN (8); }; +template <typename Types> struct ChainRuleSet { + using ChainRule = OT::ChainRule<Types>; + bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const { return @@ -3001,8 +3095,11 @@ struct ChainRuleSet DEFINE_SIZE_ARRAY (2, rule); }; -struct ChainContextFormat1 +template <typename Types> +struct ChainContextFormat1_4 { + using ChainRuleSet = OT::ChainRuleSet<Types>; + bool intersects (const hb_set_t *glyphs) const { struct ChainContextClosureLookupContext lookup_context = { @@ -3026,8 +3123,8 @@ struct ChainContextFormat1 void closure (hb_closure_context_t *c) const { - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); struct ChainContextClosureLookupContext lookup_context = { @@ -3138,18 +3235,21 @@ struct ChainContextFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - Array16OfOffset16To<ChainRuleSet> + Array16Of<typename Types::template OffsetTo<ChainRuleSet>> ruleSet; /* Array of ChainRuleSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, ruleSet); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, ruleSet); }; -struct ChainContextFormat2 +template <typename Types> +struct ChainContextFormat2_5 { + using ChainRuleSet = OT::ChainRuleSet<SmallTypes>; + bool intersects (const hb_set_t *glyphs) const { if (!(this+coverage).intersects (glyphs)) @@ -3168,7 +3268,7 @@ struct ChainContextFormat2 }; hb_set_t retained_coverage_glyphs; - (this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs); + (this+coverage).intersect_set (*glyphs, retained_coverage_glyphs); hb_set_t coverage_glyph_classes; input_class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); @@ -3193,8 +3293,8 @@ struct ChainContextFormat2 if (!(this+coverage).intersects (c->glyphs)) return; - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); @@ -3214,7 +3314,7 @@ struct ChainContextFormat2 | hb_filter ([&] (unsigned _) { return input_class_def.intersects_class (&c->parent_active_glyphs (), _); }, hb_first) - | hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<ChainRuleSet>&> _) + | hb_apply ([&] (const hb_pair_t<unsigned, const typename Types::template OffsetTo<ChainRuleSet>&> _) { const ChainRuleSet& chainrule_set = this+_.second; chainrule_set.closure (c, _.first, lookup_context); @@ -3330,7 +3430,7 @@ struct ChainContextFormat2 const ClassDef &input_class_def = this+inputClassDef; const ClassDef &lookahead_class_def = this+lookaheadClassDef; - /* For ChainContextFormat2 we cache the LookaheadClassDef instead of InputClassDef. + /* For ChainContextFormat2_5 we cache the LookaheadClassDef instead of InputClassDef. * The reason is that most heavy fonts want to identify a glyph in context and apply * a lookup to it. In this scenario, the length of the input sequence is one, whereas * the lookahead / backtrack are typically longer. The one glyph in input sequence is @@ -3378,7 +3478,7 @@ struct ChainContextFormat2 const hb_set_t* glyphset = c->plan->glyphset_gsub (); hb_set_t retained_coverage_glyphs; - (this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs); + (this+coverage).intersect_set (*glyphset, retained_coverage_glyphs); hb_set_t coverage_glyph_classes; (this+inputClassDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); @@ -3433,38 +3533,40 @@ struct ChainContextFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> backtrackClassDef; /* Offset to glyph ClassDef table * containing backtrack sequence * data--from beginning of table */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> inputClassDef; /* Offset to glyph ClassDef * table containing input sequence * data--from beginning of table */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> lookaheadClassDef; /* Offset to glyph ClassDef table * containing lookahead sequence * data--from beginning of table */ - Array16OfOffset16To<ChainRuleSet> + Array16Of<typename Types::template OffsetTo<ChainRuleSet>> ruleSet; /* Array of ChainRuleSet tables * ordered by class */ public: - DEFINE_SIZE_ARRAY (12, ruleSet); + DEFINE_SIZE_ARRAY (4 + 4 * Types::size, ruleSet); }; struct ChainContextFormat3 { + using RuleSet = OT::RuleSet<SmallTypes>; + bool intersects (const hb_set_t *glyphs) const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!(this+input[0]).intersects (glyphs)) return false; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); struct ChainContextClosureLookupContext lookup_context = { {intersects_coverage, intersected_coverage_glyphs}, ContextFormat::CoverageBasedContext, @@ -3482,18 +3584,18 @@ struct ChainContextFormat3 void closure (hb_closure_context_t *c) const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!(this+input[0]).intersects (c->glyphs)) return; - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); struct ChainContextClosureLookupContext lookup_context = { {intersects_coverage, intersected_coverage_glyphs}, ContextFormat::CoverageBasedContext, @@ -3514,9 +3616,9 @@ struct ChainContextFormat3 if (!intersects (c->glyphs)) return; - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); recurse_lookups (c, lookup.len, lookup.arrayZ); } @@ -3524,12 +3626,13 @@ struct ChainContextFormat3 void collect_glyphs (hb_collect_glyphs_context_t *c) const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); (this+input[0]).collect_coverage (c->input); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); + struct ChainContextCollectGlyphsLookupContext lookup_context = { {collect_coverage}, {this, this, this} @@ -3544,9 +3647,9 @@ struct ChainContextFormat3 bool would_apply (hb_would_apply_context_t *c) const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); struct ChainContextApplyLookupContext lookup_context = { {{match_coverage, match_coverage, match_coverage}}, {this, this, this} @@ -3560,20 +3663,20 @@ struct ChainContextFormat3 const Coverage &get_coverage () const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); return this+input[0]; } bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); struct ChainContextApplyLookupContext lookup_context = { {{match_coverage, match_coverage, match_coverage}}, {this, this, this} @@ -3615,21 +3718,21 @@ struct ChainContextFormat3 if (!serialize_coverage_offsets (c, backtrack.iter (), this)) return_trace (false); - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!serialize_coverage_offsets (c, input.iter (), this)) return_trace (false); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (!serialize_coverage_offsets (c, lookahead.iter (), this)) return_trace (false); - const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; - HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookupRecord.len); + HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookup.len); if (!lookupCount) return_trace (false); - unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (), lookup_map); + unsigned count = serialize_lookuprecord_array (c->serializer, lookup.as_array (), lookup_map); return_trace (c->serializer->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } @@ -3637,12 +3740,12 @@ struct ChainContextFormat3 { TRACE_SANITIZE (this); if (!backtrack.sanitize (c, this)) return_trace (false); - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!input.sanitize (c, this)) return_trace (false); if (!input.len) return_trace (false); /* To be consistent with Context. */ - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (!lookahead.sanitize (c, this)) return_trace (false); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); return_trace (lookup.sanitize (c)); } @@ -3678,16 +3781,24 @@ struct ChainContext case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); + case 5: return_trace (c->dispatch (u.format5, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } protected: union { - HBUINT16 format; /* Format identifier */ - ChainContextFormat1 format1; - ChainContextFormat2 format2; - ChainContextFormat3 format3; + HBUINT16 format; /* Format identifier */ + ChainContextFormat1_4<SmallTypes> format1; + ChainContextFormat2_5<SmallTypes> format2; + ChainContextFormat3 format3; +#ifndef HB_NO_BEYOND_64K + ChainContextFormat1_4<MediumTypes> format4; + ChainContextFormat2_5<MediumTypes> format5; +#endif } u; }; @@ -3871,39 +3982,209 @@ struct hb_ot_layout_lookup_accelerator_t #endif }; +template <typename Types> +struct GSUBGPOSVersion1_2 +{ + friend struct GSUBGPOS; + + protected: + FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set + * to 0x00010000u */ + typename Types:: template OffsetTo<ScriptList> + scriptList; /* ScriptList table */ + typename Types::template OffsetTo<FeatureList> + featureList; /* FeatureList table */ + typename Types::template OffsetTo<LookupList<Types>> + lookupList; /* LookupList table */ + Offset32To<FeatureVariations> + featureVars; /* Offset to Feature Variations + table--from beginning of table + * (may be NULL). Introduced + * in version 0x00010001. */ + public: + DEFINE_SIZE_MIN (4 + 3 * Types::size); + + unsigned int get_size () const + { + return min_size + + (version.to_int () >= 0x00010001u ? featureVars.static_size : 0); + } + + template <typename TLookup> + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + typedef List16OfOffsetTo<TLookup, typename Types::HBUINT> TLookupList; + if (unlikely (!(scriptList.sanitize (c, this) && + featureList.sanitize (c, this) && + reinterpret_cast<const typename Types::template OffsetTo<TLookupList> &> (lookupList).sanitize (c, this)))) + return_trace (false); + +#ifndef HB_NO_VAR + if (unlikely (!(version.to_int () < 0x00010001u || featureVars.sanitize (c, this)))) + return_trace (false); +#endif + + return_trace (true); + } + + template <typename TLookup> + bool subset (hb_subset_layout_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->subset_context->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + typedef LookupOffsetList<TLookup, typename Types::HBUINT> TLookupList; + reinterpret_cast<typename Types::template OffsetTo<TLookupList> &> (out->lookupList) + .serialize_subset (c->subset_context, + reinterpret_cast<const typename Types::template OffsetTo<TLookupList> &> (lookupList), + this, + c); + + reinterpret_cast<typename Types::template OffsetTo<RecordListOfFeature> &> (out->featureList) + .serialize_subset (c->subset_context, + reinterpret_cast<const typename Types::template OffsetTo<RecordListOfFeature> &> (featureList), + this, + c); + + out->scriptList.serialize_subset (c->subset_context, + scriptList, + this, + c); + +#ifndef HB_NO_VAR + if (version.to_int () >= 0x00010001u) + { + bool ret = out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); + if (!ret && version.major == 1) + { + out->version.major = 1; + out->version.minor = 0; + } + } +#endif + + return_trace (true); + } +}; + struct GSUBGPOS { - bool has_data () const { return version.to_int (); } + unsigned int get_size () const + { + switch (u.version.major) { + case 1: return u.version1.get_size (); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.get_size (); +#endif + default: return u.version.static_size; + } + } + + template <typename TLookup> + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!u.version.sanitize (c))) return_trace (false); + switch (u.version.major) { + case 1: return_trace (u.version1.sanitize<TLookup> (c)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (u.version2.sanitize<TLookup> (c)); +#endif + default: return_trace (true); + } + } + + template <typename TLookup> + bool subset (hb_subset_layout_context_t *c) const + { + switch (u.version.major) { + case 1: return u.version1.subset<TLookup> (c); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.subset<TLookup> (c); +#endif + default: return false; + } + } + + const ScriptList &get_script_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.scriptList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.scriptList; +#endif + default: return Null (ScriptList); + } + } + const FeatureList &get_feature_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.featureList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.featureList; +#endif + default: return Null (FeatureList); + } + } + unsigned int get_lookup_count () const + { + switch (u.version.major) { + case 1: return (this+u.version1.lookupList).len; +#ifndef HB_NO_BEYOND_64K + case 2: return (this+u.version2.lookupList).len; +#endif + default: return 0; + } + } + const Lookup& get_lookup (unsigned int i) const + { + switch (u.version.major) { + case 1: return (this+u.version1.lookupList)[i]; +#ifndef HB_NO_BEYOND_64K + case 2: return (this+u.version2.lookupList)[i]; +#endif + default: return Null (Lookup); + } + } + const FeatureVariations &get_feature_variations () const + { + switch (u.version.major) { + case 1: return (u.version.to_int () >= 0x00010001u ? this+u.version1.featureVars : Null (FeatureVariations)); +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.featureVars; +#endif + default: return Null (FeatureVariations); + } + } + + bool has_data () const { return u.version.to_int (); } unsigned int get_script_count () const - { return (this+scriptList).len; } + { return get_script_list ().len; } const Tag& get_script_tag (unsigned int i) const - { return (this+scriptList).get_tag (i); } + { return get_script_list ().get_tag (i); } unsigned int get_script_tags (unsigned int start_offset, unsigned int *script_count /* IN/OUT */, hb_tag_t *script_tags /* OUT */) const - { return (this+scriptList).get_tags (start_offset, script_count, script_tags); } + { return get_script_list ().get_tags (start_offset, script_count, script_tags); } const Script& get_script (unsigned int i) const - { return (this+scriptList)[i]; } + { return get_script_list ()[i]; } bool find_script_index (hb_tag_t tag, unsigned int *index) const - { return (this+scriptList).find_index (tag, index); } + { return get_script_list ().find_index (tag, index); } unsigned int get_feature_count () const - { return (this+featureList).len; } + { return get_feature_list ().len; } hb_tag_t get_feature_tag (unsigned int i) const - { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); } + { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : get_feature_list ().get_tag (i); } unsigned int get_feature_tags (unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, hb_tag_t *feature_tags /* OUT */) const - { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); } + { return get_feature_list ().get_tags (start_offset, feature_count, feature_tags); } const Feature& get_feature (unsigned int i) const - { return (this+featureList)[i]; } + { return get_feature_list ()[i]; } bool find_feature_index (hb_tag_t tag, unsigned int *index) const - { return (this+featureList).find_index (tag, index); } - - unsigned int get_lookup_count () const - { return (this+lookupList).len; } - const Lookup& get_lookup (unsigned int i) const - { return (this+lookupList)[i]; } + { return get_feature_list ().find_index (tag, index); } bool find_variations_index (const int *coords, unsigned int num_coords, unsigned int *index) const @@ -3912,18 +4193,17 @@ struct GSUBGPOS *index = FeatureVariations::NOT_FOUND_INDEX; return false; #endif - return (version.to_int () >= 0x00010001u ? this+featureVars : Null (FeatureVariations)) - .find_index (coords, num_coords, index); + return get_feature_variations ().find_index (coords, num_coords, index); } const Feature& get_feature_variation (unsigned int feature_index, unsigned int variations_index) const { #ifndef HB_NO_VAR if (FeatureVariations::NOT_FOUND_INDEX != variations_index && - version.to_int () >= 0x00010001u) + u.version.to_int () >= 0x00010001u) { - const Feature *feature = (this+featureVars).find_substitute (variations_index, - feature_index); + const Feature *feature = get_feature_variations ().find_substitute (variations_index, + feature_index); if (feature) return *feature; } @@ -3935,8 +4215,7 @@ struct GSUBGPOS hb_set_t *lookup_indexes /* OUT */) const { #ifndef HB_NO_VAR - if (version.to_int () >= 0x00010001u) - (this+featureVars).collect_lookups (feature_indexes, lookup_indexes); + get_feature_variations ().collect_lookups (feature_indexes, lookup_indexes); #endif } @@ -3971,108 +4250,6 @@ struct GSUBGPOS } } - template <typename TLookup> - bool subset (hb_subset_layout_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->subset_context->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - - typedef LookupOffsetList<TLookup> TLookupList; - reinterpret_cast<Offset16To<TLookupList> &> (out->lookupList) - .serialize_subset (c->subset_context, - reinterpret_cast<const Offset16To<TLookupList> &> (lookupList), - this, - c); - - reinterpret_cast<Offset16To<RecordListOfFeature> &> (out->featureList) - .serialize_subset (c->subset_context, - reinterpret_cast<const Offset16To<RecordListOfFeature> &> (featureList), - this, - c); - - out->scriptList.serialize_subset (c->subset_context, - scriptList, - this, - c); - -#ifndef HB_NO_VAR - if (version.to_int () >= 0x00010001u) - { - bool ret = out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); - if (!ret) - { - out->version.major = 1; - out->version.minor = 0; - } - } -#endif - - return_trace (true); - } - - void find_duplicate_features (const hb_map_t *lookup_indices, - const hb_set_t *feature_indices, - hb_map_t *duplicate_feature_map /* OUT */) const - { - if (feature_indices->is_empty ()) return; - hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_set_t>> unique_features; - //find out duplicate features after subset - for (unsigned i : feature_indices->iter ()) - { - hb_tag_t t = get_feature_tag (i); - if (t == HB_MAP_VALUE_INVALID) continue; - if (!unique_features.has (t)) - { - if (unlikely (!unique_features.set (t, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) - return; - if (unique_features.has (t)) - unique_features.get (t)->add (i); - duplicate_feature_map->set (i, i); - continue; - } - - bool found = false; - - hb_set_t* same_tag_features = unique_features.get (t); - for (unsigned other_f_index : same_tag_features->iter ()) - { - const Feature& f = get_feature (i); - const Feature& other_f = get_feature (other_f_index); - - auto f_iter = - + hb_iter (f.lookupIndex) - | hb_filter (lookup_indices) - ; - - auto other_f_iter = - + hb_iter (other_f.lookupIndex) - | hb_filter (lookup_indices) - ; - - bool is_equal = true; - for (; f_iter && other_f_iter; f_iter++, other_f_iter++) - { - unsigned a = *f_iter; - unsigned b = *other_f_iter; - if (a != b) { is_equal = false; break; } - } - - if (is_equal == false || f_iter || other_f_iter) continue; - - found = true; - duplicate_feature_map->set (i, other_f_index); - break; - } - - if (found == false) - { - same_tag_features->add (i); - duplicate_feature_map->set (i, i); - } - } - } - void prune_features (const hb_map_t *lookup_indices, /* IN */ hb_set_t *feature_indices /* IN/OUT */) const { @@ -4081,8 +4258,7 @@ struct GSUBGPOS // if the FeatureVariation's table and the alternate version(s) intersect the // set of lookup indices. hb_set_t alternate_feature_indices; - if (version.to_int () >= 0x00010001u) - (this+featureVars).closure_features (lookup_indices, &alternate_feature_indices); + get_feature_variations ().closure_features (lookup_indices, &alternate_feature_indices); if (unlikely (alternate_feature_indices.in_error())) { feature_indices->err (); @@ -4115,32 +4291,6 @@ struct GSUBGPOS } } - unsigned int get_size () const - { - return min_size + - (version.to_int () >= 0x00010001u ? featureVars.static_size : 0); - } - - template <typename TLookup> - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - typedef List16OfOffset16To<TLookup> TLookupList; - if (unlikely (!(version.sanitize (c) && - likely (version.major == 1) && - scriptList.sanitize (c, this) && - featureList.sanitize (c, this) && - reinterpret_cast<const Offset16To<TLookupList> &> (lookupList).sanitize (c, this)))) - return_trace (false); - -#ifndef HB_NO_VAR - if (unlikely (!(version.to_int () < 0x00010001u || featureVars.sanitize (c, this)))) - return_trace (false); -#endif - - return_trace (true); - } - template <typename T> struct accelerator_t { @@ -4180,21 +4330,15 @@ struct GSUBGPOS }; protected: - FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set - * to 0x00010000u */ - Offset16To<ScriptList> - scriptList; /* ScriptList table */ - Offset16To<FeatureList> - featureList; /* FeatureList table */ - Offset16To<LookupList> - lookupList; /* LookupList table */ - Offset32To<FeatureVariations> - featureVars; /* Offset to Feature Variations - table--from beginning of table - * (may be NULL). Introduced - * in version 0x00010001. */ + union { + FixedVersion<> version; /* Version identifier */ + GSUBGPOSVersion1_2<SmallTypes> version1; +#ifndef HB_NO_BEYOND_64K + GSUBGPOSVersion1_2<MediumTypes> version2; +#endif + } u; public: - DEFINE_SIZE_MIN (10); + DEFINE_SIZE_MIN (4); }; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index 142c843dad..f9c0daa486 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -54,7 +54,7 @@ #include "hb-aat-layout-morx-table.hh" #include "hb-aat-layout-opbd-table.hh" // Just so we compile it; unused otherwise. -using OT::Layout::GSUB::GSUB; +using OT::Layout::GSUB; using OT::Layout::GPOS; /** @@ -79,7 +79,7 @@ using OT::Layout::GPOS; * Tests whether a face includes any kerning data in the 'kern' table. * Does NOT test for kerning lookups in the GPOS table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ bool @@ -95,7 +95,7 @@ hb_ot_layout_has_kerning (hb_face_t *face) * Tests whether a face includes any state-machine kerning in the 'kern' table. * Does NOT examine the GPOS table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ bool @@ -115,7 +115,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face) * * Does NOT examine the GPOS table. * - * Return value: %true is data found, %false otherwise + * Return value: `true` is data found, `false` otherwise * **/ bool @@ -272,7 +272,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, * * Tests whether a face has any glyph classes defined in its GDEF table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ hb_bool_t @@ -461,7 +461,7 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face, * Fetches the index if a given script tag in the specified face's GSUB table * or GPOS table. * - * Return value: %true if the script is found, %false otherwise + * Return value: `true` if the script is found, `false` otherwise * **/ hb_bool_t @@ -535,7 +535,7 @@ hb_ot_layout_table_choose_script (hb_face_t *face, * #HB_OT_LAYOUT_NO_SCRIPT_INDEX. * * Return value: - * %true if one of the requested scripts is selected, %false if a fallback + * `true` if one of the requested scripts is selected, `false` if a fallback * script is selected or if no scripts are selected. * * Since: 2.0.0 @@ -628,7 +628,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, * Fetches the index for a given feature tag in the specified face's GSUB table * or GPOS table. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise **/ bool hb_ot_layout_table_find_feature (hb_face_t *face, @@ -695,7 +695,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, * Fetches the index of a given language tag in the specified face's GSUB table * or GPOS table, underneath the specified script tag. * - * Return value: %true if the language tag is found, %false otherwise + * Return value: `true` if the language tag is found, `false` otherwise * * Since: 0.6.0 * Deprecated: 2.0.0 @@ -730,10 +730,10 @@ hb_ot_layout_script_find_language (hb_face_t *face, * in the specified face's GSUB or GPOS table, underneath the specified script * index. * - * If none of the given language tags is found, %false is returned and + * If none of the given language tags is found, `false` is returned and * @language_index is set to the default language index. * - * Return value: %true if one of the given language tags is found, %false otherwise + * Return value: `true` if one of the given language tags is found, `false` otherwise * * Since: 2.0.0 **/ @@ -776,7 +776,7 @@ hb_ot_layout_script_select_language (hb_face_t *face, * Fetches the index of a requested feature in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise * **/ hb_bool_t @@ -807,7 +807,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise * * Since: 0.9.30 **/ @@ -917,7 +917,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, * Fetches the index of a given feature tag in the specified face's GSUB table * or GPOS table, underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise * **/ hb_bool_t @@ -1314,7 +1314,7 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, * Fetches a list of feature variations in the specified face's GSUB table * or GPOS table, at the specified variation coordinates. * - * Return value: %true if feature variations were found, %false otherwise. + * Return value: `true` if feature variations were found, `false` otherwise. * **/ hb_bool_t @@ -1377,7 +1377,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, * * Tests whether the specified face includes any GSUB substitutions. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ hb_bool_t @@ -1399,7 +1399,7 @@ hb_ot_layout_has_substitution (hb_face_t *face) * Tests whether a specified lookup in the specified face would * trigger a substitution on the given glyph sequence. * - * Return value: %true if a substitution would be triggered, %false otherwise + * Return value: `true` if a substitution would be triggered, `false` otherwise * * Since: 0.9.7 **/ @@ -1561,7 +1561,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, * * Tests whether the specified face includes any GPOS positioning. * - * Return value: %true if the face has GPOS data, %false otherwise + * Return value: `true` if the face has GPOS data, `false` otherwise * **/ hb_bool_t @@ -1634,7 +1634,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) * For more information on this distinction, see the [`size` feature documentation]( * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.10 **/ @@ -1698,7 +1698,7 @@ hb_ot_layout_get_size_params (hb_face_t *face, * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or * "Character Variant" ('cvXX') features. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.0.0 **/ @@ -2051,7 +2051,7 @@ hb_ot_layout_get_horizontal_baseline_tag_for_script (hb_script_t script) * * Fetches a baseline value from the face. * - * Return value: %true if found baseline value in the font. + * Return value: `true` if found baseline value in the font. * * Since: 2.6.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh index 6395f06670..de06610cb5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -110,7 +110,7 @@ namespace OT { struct hb_ot_apply_context_t; struct hb_ot_layout_lookup_accelerator_t; namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SubstLookup; } } @@ -118,7 +118,7 @@ namespace GSUB { HB_INTERNAL void hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, - const OT::Layout::GSUB::SubstLookup &lookup, + const OT::Layout::GSUB_impl::SubstLookup &lookup, const OT::hb_ot_layout_lookup_accelerator_t &accel); diff --git a/thirdparty/harfbuzz/src/hb-ot-map.cc b/thirdparty/harfbuzz/src/hb-ot-map.cc index f085c78ff8..39215b335f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.cc +++ b/thirdparty/harfbuzz/src/hb-ot-map.cc @@ -43,7 +43,7 @@ void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_o hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, - const hb_segment_properties_t *props_) + const hb_segment_properties_t &props_) { memset (this, 0, sizeof (*this)); @@ -52,7 +52,7 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, stages[table_index].init (); face = face_; - props = *props_; + props = props_; /* Fetch script/language indices for GSUB/GPOS. We need these later to skip * features not available in either table and not waste precious bits for them. */ @@ -109,6 +109,21 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, info->stage[1] = current_stage[1]; } +bool hb_ot_map_builder_t::has_feature (hb_tag_t tag) +{ + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + if (hb_ot_layout_language_find_feature (face, + table_tags[table_index], + script_index[table_index], + language_index[table_index], + tag, + nullptr)) + return true; + } + return false; +} + void hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, unsigned int table_index, diff --git a/thirdparty/harfbuzz/src/hb-ot-map.hh b/thirdparty/harfbuzz/src/hb-ot-map.hh index f1cbf752fc..a7b5eec30d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.hh +++ b/thirdparty/harfbuzz/src/hb-ot-map.hh @@ -139,19 +139,15 @@ struct hb_ot_map_t return map ? map->stage[table_index] : UINT_MAX; } - void get_stage_lookups (unsigned int table_index, unsigned int stage, - const struct lookup_map_t **plookups, unsigned int *lookup_count) const + hb_array_t<const hb_ot_map_t::lookup_map_t> + get_stage_lookups (unsigned int table_index, unsigned int stage) const { if (unlikely (stage > stages[table_index].length)) - { - *plookups = nullptr; - *lookup_count = 0; - return; - } + return hb_array<const hb_ot_map_t::lookup_map_t> (nullptr, 0); + unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0; unsigned int end = stage < stages[table_index].length ? stages[table_index][stage].last_lookup : lookups[table_index].length; - *plookups = end == start ? nullptr : &lookups[table_index][start]; - *lookup_count = end - start; + return lookups[table_index].as_array ().sub_array (start, end - start); } HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const; @@ -167,7 +163,7 @@ struct hb_ot_map_t private: - hb_mask_t global_mask; + hb_mask_t global_mask = 0; hb_sorted_vector_t<feature_map_t> features; hb_vector_t<lookup_map_t> lookups[2]; /* GSUB/GPOS */ @@ -204,7 +200,7 @@ struct hb_ot_map_builder_t public: HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_, - const hb_segment_properties_t *props_); + const hb_segment_properties_t &props_); HB_INTERNAL ~hb_ot_map_builder_t (); @@ -212,6 +208,8 @@ struct hb_ot_map_builder_t hb_ot_map_feature_flags_t flags=F_NONE, unsigned int value=1); + HB_INTERNAL bool has_feature (hb_tag_t tag); + void add_feature (const hb_ot_map_feature_t &feat) { add_feature (feat.tag, feat.flags); } diff --git a/thirdparty/harfbuzz/src/hb-ot-math.cc b/thirdparty/harfbuzz/src/hb-ot-math.cc index f44ac35849..c515867bdf 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math.cc +++ b/thirdparty/harfbuzz/src/hb-ot-math.cc @@ -56,7 +56,7 @@ * * Tests whether a face has a `MATH` table. * - * Return value: %true if the table is found, %false otherwise + * Return value: `true` if the table is found, `false` otherwise * * Since: 1.3.3 **/ @@ -142,7 +142,7 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, * * Tests whether the given glyph index is an extended shape in the face. * - * Return value: %true if the glyph is an extended shape, %false otherwise + * Return value: `true` if the glyph is an extended shape, `false` otherwise * * Since: 1.3.3 **/ diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.cc b/thirdparty/harfbuzz/src/hb-ot-metrics.cc index f9c4b96fff..5b12482b97 100644 --- a/thirdparty/harfbuzz/src/hb-ot-metrics.cc +++ b/thirdparty/harfbuzz/src/hb-ot-metrics.cc @@ -71,12 +71,12 @@ _hb_ot_metrics_get_position_common (hb_font_t *font, #endif #define GET_METRIC_X(TABLE, ATTR) \ (face->table.TABLE->has_data () && \ - (position && (*position = font->em_scalef_x (_fix_ascender_descender ( \ - face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true)) + ((void) (position && (*position = font->em_scalef_x (_fix_ascender_descender ( \ + face->table.TABLE->ATTR + GET_VAR, metrics_tag)))), true)) #define GET_METRIC_Y(TABLE, ATTR) \ (face->table.TABLE->has_data () && \ - (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \ - face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true)) + ((void) (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \ + face->table.TABLE->ATTR + GET_VAR, metrics_tag)))), true)) case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER: return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) || @@ -154,10 +154,10 @@ hb_ot_metrics_get_position (hb_font_t *font, #endif #define GET_METRIC_X(TABLE, ATTR) \ (face->table.TABLE->has_data () && \ - (position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR)), true)) + ((void) (position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR))), true)) #define GET_METRIC_Y(TABLE, ATTR) \ (face->table.TABLE->has_data () && \ - (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true)) + ((void) (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR))), true)) case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent); case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent); diff --git a/thirdparty/harfbuzz/src/hb-ot-name-table.hh b/thirdparty/harfbuzz/src/hb-ot-name-table.hh index 01107aad67..1f2131ffcc 100644 --- a/thirdparty/harfbuzz/src/hb-ot-name-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-name-table.hh @@ -175,15 +175,11 @@ _hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact) signed c = strcmp (astr, bstr); - if (!exact && c) - { - unsigned la = strlen (astr); - unsigned lb = strlen (bstr); - // 'a' is the user request, and 'b' is string in the font. - // If eg. user asks for "en-us" and font has "en", approve. - if (la > lb && astr[lb] == '-' && !strncmp (astr, bstr, lb)) - return 0; - } + // 'a' is the user request, and 'b' is string in the font. + // If eg. user asks for "en-us" and font has "en", approve. + if (!exact && c && + hb_language_matches (b->language, a->language)) + return 0; return c; } diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table.hh b/thirdparty/harfbuzz/src/hb-ot-post-table.hh index a4844e94bc..a4c0c4aa17 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table.hh @@ -263,10 +263,10 @@ struct post bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (version.to_int () == 0x00010000 || - (version.to_int () == 0x00020000 && v2X.sanitize (c)) || - version.to_int () == 0x00030000))); + return_trace (c->check_struct (this) && + (version.to_int () == 0x00010000 || + (version.to_int () == 0x00020000 && v2X.sanitize (c)) || + version.to_int () == 0x00030000)); } public: diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 0806abb7dd..2ada84b8a3 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -53,11 +53,11 @@ _hb_codepoint_is_regional_indicator (hb_codepoint_t u) #ifndef HB_NO_AAT_SHAPE static inline bool -_hb_apply_morx (hb_face_t *face, const hb_segment_properties_t *props) +_hb_apply_morx (hb_face_t *face, const hb_segment_properties_t &props) { /* https://github.com/harfbuzz/harfbuzz/issues/2124 */ return hb_aat_layout_has_substitution (face) && - (HB_DIRECTION_IS_HORIZONTAL (props->direction) || !hb_ot_layout_has_substitution (face)); + (HB_DIRECTION_IS_HORIZONTAL (props.direction) || !hb_ot_layout_has_substitution (face)); } #endif @@ -77,9 +77,9 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, unsigned int num_user_features); hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *face, - const hb_segment_properties_t *props) : + const hb_segment_properties_t &props) : face (face), - props (*props), + props (props), map (face, props), aat_map (face, props) #ifndef HB_NO_AAT_SHAPE @@ -225,7 +225,7 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face, #endif hb_ot_shape_planner_t planner (face, - &key->props); + key->props); hb_ot_shape_collect_features (&planner, key->user_features, diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.hh b/thirdparty/harfbuzz/src/hb-ot-shape.hh index 17fa58b337..cd6f15cbe2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape.hh @@ -60,6 +60,8 @@ struct hb_shape_plan_key_t; struct hb_ot_shape_plan_t { + ~hb_ot_shape_plan_t () { fini (); } + hb_segment_properties_t props; const struct hb_ot_shaper_t *shaper; hb_ot_map_t map; @@ -161,7 +163,7 @@ struct hb_ot_shape_planner_t const struct hb_ot_shaper_t *shaper; HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, - const hb_segment_properties_t *props); + const hb_segment_properties_t &props); HB_INTERNAL void compile (hb_ot_shape_plan_t &plan, const hb_ot_shape_plan_key_t &key); diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc index e869d78509..b331a048b6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc @@ -201,24 +201,21 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) * work. However, testing shows that rlig and calt are applied * together for Mongolian in Uniscribe. As such, we only add a * pause for Arabic, not other scripts. - * - * A pause after calt is required to make KFGQPC Uthmanic Script HAFS - * work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505 */ map->enable_feature (HB_TAG('s','t','c','h')); map->add_gsub_pause (record_stch); - map->enable_feature (HB_TAG('c','c','m','p')); - map->enable_feature (HB_TAG('l','o','c','l')); + map->enable_feature (HB_TAG('c','c','m','p'), F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('l','o','c','l'), F_MANUAL_ZWJ); map->add_gsub_pause (nullptr); for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) { bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]); - map->add_feature (arabic_features[i], has_fallback ? F_HAS_FALLBACK : F_NONE); + map->add_feature (arabic_features[i], F_MANUAL_ZWJ | (has_fallback ? F_HAS_FALLBACK : F_NONE)); map->add_gsub_pause (nullptr); } map->add_gsub_pause (deallocate_buffer_var); @@ -232,10 +229,16 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) if (plan->props.script == HB_SCRIPT_ARABIC) map->add_gsub_pause (arabic_fallback_shape); - /* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */ - map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ); - map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ); - map->add_gsub_pause (nullptr); + map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ); + /* https://github.com/harfbuzz/harfbuzz/issues/1573 */ + if (!map->has_feature (HB_TAG('r','c','l','t'))) + { + map->add_gsub_pause (nullptr); + map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ); + } + + map->enable_feature (HB_TAG('l','i','g','a'), F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('c','l','i','g'), F_MANUAL_ZWJ); /* The spec includes 'cswh'. Earlier versions of Windows * used to enable this by default, but testing suggests @@ -245,8 +248,8 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) * Note that IranNastaliq uses this feature extensively * to fixup broken glyph sequences. Oh well... * Test case: U+0643,U+0640,U+0631. */ - //map->enable_feature (HB_TAG('c','s','w','h')); - map->enable_feature (HB_TAG('m','s','e','t')); + //map->enable_feature (HB_TAG('c','s','w','h'), F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('m','s','e','t'), F_MANUAL_ZWJ); } #include "hb-ot-shaper-arabic-fallback.hh" @@ -735,12 +738,12 @@ const hb_ot_shaper_t _hb_ot_shaper_arabic = data_destroy_arabic, nullptr, /* preprocess_text */ postprocess_glyphs_arabic, - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ nullptr, /* compose */ setup_masks_arabic, - HB_TAG_NONE, /* gpos_tag */ reorder_marks_arabic, + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc index 25716aa81f..2f6f499eec 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc @@ -39,12 +39,12 @@ const hb_ot_shaper_t _hb_ot_shaper_default = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; @@ -59,12 +59,12 @@ const hb_ot_shaper_t _hb_ot_shaper_dumber = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc index aa507c75ca..c90476bc46 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc @@ -422,12 +422,12 @@ const hb_ot_shaper_t _hb_ot_shaper_hangul = data_destroy_hangul, preprocess_text_hangul, nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_NONE, nullptr, /* decompose */ nullptr, /* compose */ setup_masks_hangul, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_NONE, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc index f3b6cde179..e18edd6b3f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc @@ -89,7 +89,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, found = true; } break; - case 0x05B7u: /* patah */ + case 0x05B7u: /* PATAH */ if (a == 0x05F2u) { /* YIDDISH YOD YOD */ *ab = 0xFB1Fu; found = true; @@ -162,6 +162,32 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, return found; } +static void +reorder_marks_hebrew (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_buffer_t *buffer, + unsigned int start, + unsigned int end) +{ + hb_glyph_info_t *info = buffer->info; + + for (unsigned i = start + 2; i < end; i++) + { + unsigned c0 = info_cc (info[i - 2]); + unsigned c1 = info_cc (info[i - 1]); + unsigned c2 = info_cc (info[i - 0]); + + if ((c0 == HB_MODIFIED_COMBINING_CLASS_CCC17 || c0 == HB_MODIFIED_COMBINING_CLASS_CCC18) /* patach or qamats */ && + (c1 == HB_MODIFIED_COMBINING_CLASS_CCC10 || c1 == HB_MODIFIED_COMBINING_CLASS_CCC14) /* sheva or hiriq */ && + (c2 == HB_MODIFIED_COMBINING_CLASS_CCC22 || c2 == HB_UNICODE_COMBINING_CLASS_BELOW) /* meteg or below */) + { + buffer->merge_clusters (i - 1, i + 1); + hb_swap (info[i - 1], info[i]); + break; + } + } + + +} const hb_ot_shaper_t _hb_ot_shaper_hebrew = { @@ -171,12 +197,12 @@ const hb_ot_shaper_t _hb_ot_shaper_hebrew = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ compose_hebrew, nullptr, /* setup_masks */ + reorder_marks_hebrew, HB_TAG ('h','e','b','r'), /* gpos_tag. https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368 */ - nullptr, /* reorder_marks */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh index d52b13f616..d3a7cce3de 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh @@ -53,7 +53,7 @@ enum indic_syllable_type_t { }; -#line 57 "hb-ot-shaper-indic-machine.hh" +#line 54 "hb-ot-shaper-indic-machine.hh" #define indic_syllable_machine_ex_A 9u #define indic_syllable_machine_ex_C 1u #define indic_syllable_machine_ex_CM 16u @@ -75,7 +75,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 79 "hb-ot-shaper-indic-machine.hh" +#line 74 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 12u, 4u, 12u, 8u, 8u, 5u, 7u, @@ -422,7 +422,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 426 "hb-ot-shaper-indic-machine.hh" +#line 415 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -438,7 +438,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 442 "hb-ot-shaper-indic-machine.hh" +#line 427 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -452,7 +452,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 456 "hb-ot-shaper-indic-machine.hh" +#line 439 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -555,7 +555,7 @@ _eof_trans: #line 113 "hb-ot-shaper-indic-machine.rl" {act = 6;} break; -#line 559 "hb-ot-shaper-indic-machine.hh" +#line 521 "hb-ot-shaper-indic-machine.hh" } _again: @@ -564,7 +564,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 568 "hb-ot-shaper-indic-machine.hh" +#line 528 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc index 48a3c74463..6eb400ab16 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc @@ -92,24 +92,22 @@ struct hb_indic_would_substitute_feature_t void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_) { zero_context = zero_context_; - map->get_stage_lookups (0/*GSUB*/, - map->get_feature_stage (0/*GSUB*/, feature_tag), - &lookups, &count); + lookups = map->get_stage_lookups (0/*GSUB*/, + map->get_feature_stage (0/*GSUB*/, feature_tag)); } bool would_substitute (const hb_codepoint_t *glyphs, unsigned int glyphs_count, hb_face_t *face) const { - for (unsigned int i = 0; i < count; i++) - if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context)) + for (const auto &lookup : lookups) + if (hb_ot_layout_lookup_would_substitute (face, lookup.index, glyphs, glyphs_count, zero_context)) return true; return false; } private: - const hb_ot_map_t::lookup_map_t *lookups; - unsigned int count; + hb_array_t<const hb_ot_map_t::lookup_map_t> lookups; bool zero_context; }; @@ -1528,12 +1526,12 @@ const hb_ot_shaper_t _hb_ot_shaper_indic = data_destroy_indic, preprocess_text_indic, nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, decompose_indic, compose_indic, setup_masks_indic, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh index e18bd75ef1..2c40663bdd 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh @@ -48,7 +48,7 @@ enum khmer_syllable_type_t { }; -#line 52 "hb-ot-shaper-khmer-machine.hh" +#line 49 "hb-ot-shaper-khmer-machine.hh" #define khmer_syllable_machine_ex_C 1u #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u #define khmer_syllable_machine_ex_H 4u @@ -66,7 +66,7 @@ enum khmer_syllable_type_t { #define khmer_syllable_machine_ex_ZWNJ 5u -#line 70 "hb-ot-shaper-khmer-machine.hh" +#line 65 "hb-ot-shaper-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, @@ -294,7 +294,7 @@ find_syllables_khmer (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 298 "hb-ot-shaper-khmer-machine.hh" +#line 287 "hb-ot-shaper-khmer-machine.hh" { cs = khmer_syllable_machine_start; ts = 0; @@ -310,7 +310,7 @@ find_syllables_khmer (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 314 "hb-ot-shaper-khmer-machine.hh" +#line 299 "hb-ot-shaper-khmer-machine.hh" { int _slen; int _trans; @@ -324,7 +324,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 328 "hb-ot-shaper-khmer-machine.hh" +#line 311 "hb-ot-shaper-khmer-machine.hh" } _keys = _khmer_syllable_machine_trans_keys + (cs<<1); @@ -394,7 +394,7 @@ _eof_trans: #line 98 "hb-ot-shaper-khmer-machine.rl" {act = 3;} break; -#line 398 "hb-ot-shaper-khmer-machine.hh" +#line 368 "hb-ot-shaper-khmer-machine.hh" } _again: @@ -403,7 +403,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 407 "hb-ot-shaper-khmer-machine.hh" +#line 375 "hb-ot-shaper-khmer-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc index e04d633195..d9795589fa 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc @@ -368,12 +368,12 @@ const hb_ot_shaper_t _hb_ot_shaper_khmer = data_destroy_khmer, nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, decompose_khmer, compose_khmer, setup_masks_khmer, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh index b109708937..464cf796d4 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh @@ -50,7 +50,7 @@ enum myanmar_syllable_type_t { }; -#line 54 "hb-ot-shaper-myanmar-machine.hh" +#line 51 "hb-ot-shaper-myanmar-machine.hh" #define myanmar_syllable_machine_ex_A 9u #define myanmar_syllable_machine_ex_As 32u #define myanmar_syllable_machine_ex_C 1u @@ -77,7 +77,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 81 "hb-ot-shaper-myanmar-machine.hh" +#line 76 "hb-ot-shaper-myanmar-machine.hh" static const unsigned char _myanmar_syllable_machine_trans_keys[] = { 1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u, 5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u, @@ -443,7 +443,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 447 "hb-ot-shaper-myanmar-machine.hh" +#line 436 "hb-ot-shaper-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -459,7 +459,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 463 "hb-ot-shaper-myanmar-machine.hh" +#line 448 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -473,7 +473,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 477 "hb-ot-shaper-myanmar-machine.hh" +#line 460 "hb-ot-shaper-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -519,7 +519,7 @@ _eof_trans: #line 113 "hb-ot-shaper-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 523 "hb-ot-shaper-myanmar-machine.hh" +#line 498 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -528,7 +528,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 532 "hb-ot-shaper-myanmar-machine.hh" +#line 505 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc index 1ccafbca7e..78bd8de524 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc @@ -320,12 +320,12 @@ const hb_ot_shaper_t _hb_ot_shaper_myanmar = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, nullptr, /* decompose */ nullptr, /* compose */ setup_masks_myanmar, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ }; @@ -342,12 +342,12 @@ const hb_ot_shaper_t _hb_ot_shaper_myanmar_zawgyi = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_NONE, nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_NONE, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc index 1280e7ed17..15349b1e64 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc @@ -379,12 +379,12 @@ const hb_ot_shaper_t _hb_ot_shaper_thai = nullptr, /* data_destroy */ preprocess_text_thai, nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, false,/* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh index 65e65ff39d..5b3ec05616 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh @@ -53,7 +53,7 @@ enum use_syllable_type_t { }; -#line 57 "hb-ot-shaper-use-machine.hh" +#line 54 "hb-ot-shaper-use-machine.hh" #define use_syllable_machine_ex_B 1u #define use_syllable_machine_ex_CGJ 6u #define use_syllable_machine_ex_CMAbv 31u @@ -97,7 +97,7 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 101 "hb-ot-shaper-use-machine.hh" +#line 96 "hb-ot-shaper-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 53u, @@ -780,7 +780,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 784 "hb-ot-shaper-use-machine.hh" +#line 773 "hb-ot-shaper-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -793,7 +793,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 797 "hb-ot-shaper-use-machine.hh" +#line 782 "hb-ot-shaper-use-machine.hh" { int _slen; int _trans; @@ -807,7 +807,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 811 "hb-ot-shaper-use-machine.hh" +#line 794 "hb-ot-shaper-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -897,7 +897,7 @@ _eof_trans: #line 171 "hb-ot-shaper-use-machine.rl" {act = 2;} break; -#line 901 "hb-ot-shaper-use-machine.hh" +#line 866 "hb-ot-shaper-use-machine.hh" } _again: @@ -906,7 +906,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 910 "hb-ot-shaper-use-machine.hh" +#line 873 "hb-ot-shaper-use-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh index 5aa025fb4c..4f09fa805e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh @@ -89,1440 +89,264 @@ #define VMPre USE(VMPre) #pragma GCC diagnostic pop -static const uint8_t use_table[] = { - - -#define use_offset_0x0028u 0 - - - /* Basic Latin */ - O, O, O, O, O, GB, O, O, - /* 0030 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - -#define use_offset_0x00a0u 24 - - - /* Latin-1 Supplement */ - - /* 00A0 */ GB, O, O, O, O, O, O, O, O, O, O, O, O, WJ, O, O, - /* 00B0 */ O, O, FMPst, FMPst, O, O, O, O, O, O, O, O, O, O, O, O, - /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 00D0 */ O, O, O, O, O, O, O, GB, - -#define use_offset_0x0348u 80 - - - /* Combining Diacritical Marks */ - O, O, O, O, O, O, O, CGJ, - -#define use_offset_0x0640u 88 - - - /* Arabic */ - - /* 0640 */ B, O, O, O, O, O, O, O, - -#define use_offset_0x07c8u 96 - - - /* NKo */ - O, O, B, B, B, B, B, B, - /* 07D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 07E0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, - /* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, O, O, O, B, WJ, WJ, VMAbv, O, O, - -#define use_offset_0x0840u 152 - - - /* Mandaic */ - - /* 0840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0850 */ B, B, B, B, B, B, B, B, B, CMBlw, CMBlw, CMBlw, WJ, WJ, O, WJ, - -#define use_offset_0x0900u 184 - - - /* Devanagari */ - - /* 0900 */ VMAbv, VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0930 */ B, B, B, B, B, B, B, B, B, B, VAbv, VPst, CMBlw, B, VPst, VPre, - /* 0940 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst, - /* 0950 */ O, VMAbv, VMBlw, O, O, VAbv, VBlw, VBlw, B, B, B, B, B, B, B, B, - /* 0960 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0970 */ O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - - /* Bengali */ - - /* 0980 */ GB, VMAbv, VMPst, VMPst, WJ, B, B, B, B, B, B, B, B, WJ, WJ, B, - /* 0990 */ B, WJ, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 09A0 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 09B0 */ B, WJ, B, WJ, WJ, WJ, B, B, B, B, WJ, WJ, CMBlw, B, VPst, VPre, - /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, WJ, WJ, VPre, VPre, WJ, WJ, VPre, VPre, H, O, WJ, - /* 09D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, VPst, WJ, WJ, WJ, WJ, B, B, WJ, B, - /* 09E0 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FMAbv, WJ, - - /* Gurmukhi */ - - /* 0A00 */ WJ, VMAbv, VMAbv, VMPst, WJ, B, B, B, B, B, B, WJ, WJ, WJ, WJ, B, - /* 0A10 */ B, WJ, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0A20 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0A30 */ B, WJ, B, B, WJ, B, B, WJ, B, B, WJ, WJ, CMBlw, WJ, VPst, VPre, - /* 0A40 */ VPst, VBlw, VBlw, WJ, WJ, WJ, WJ, VAbv, VAbv, WJ, WJ, VAbv, VAbv, H, WJ, WJ, - /* 0A50 */ WJ, VMBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, WJ, B, WJ, - /* 0A60 */ WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0A70 */ VMAbv, CMAbv, GB, GB, O, MBlw, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Gujarati */ - - /* 0A80 */ WJ, VMAbv, VMAbv, VMPst, WJ, B, B, B, B, B, B, B, B, B, WJ, B, - /* 0A90 */ B, B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0AA0 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0AB0 */ B, WJ, B, B, WJ, B, B, B, B, B, WJ, WJ, CMBlw, B, VPst, VPre, - /* 0AC0 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, WJ, VAbv, VAbv, VAbv, WJ, VPst, VPst, H, WJ, WJ, - /* 0AD0 */ O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 0AE0 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0AF0 */ O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, VMAbv, VMAbv, VMAbv, CMAbv, CMAbv, CMAbv, - - /* Oriya */ - - /* 0B00 */ WJ, VMAbv, VMPst, VMPst, WJ, B, B, B, B, B, B, B, B, WJ, WJ, B, - /* 0B10 */ B, WJ, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0B20 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0B30 */ B, WJ, B, B, WJ, B, B, B, B, B, WJ, WJ, CMBlw, B, VPst, VAbv, - /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, WJ, WJ, VPre, VPre, WJ, WJ, VPre, VPre, H, WJ, WJ, - /* 0B50 */ WJ, WJ, WJ, WJ, WJ, VAbv, VAbv, VAbv, WJ, WJ, WJ, WJ, B, B, WJ, B, - /* 0B60 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0B70 */ O, B, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Tamil */ - - /* 0B80 */ WJ, WJ, VMAbv, O, WJ, B, B, B, B, B, B, WJ, WJ, WJ, B, B, - /* 0B90 */ B, WJ, B, B, B, B, WJ, WJ, WJ, B, B, WJ, B, WJ, B, B, - /* 0BA0 */ WJ, WJ, WJ, B, B, WJ, WJ, WJ, B, B, B, WJ, WJ, WJ, B, B, - /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, VPst, VPst, - /* 0BC0 */ VAbv, VPst, VPst, WJ, WJ, WJ, VPre, VPre, VPre, WJ, VPre, VPre, VPre, H, WJ, WJ, - /* 0BD0 */ O, WJ, WJ, WJ, WJ, WJ, WJ, VPst, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 0BE0 */ WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, - - /* Telugu */ - - /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, VMAbv, B, B, B, B, B, B, B, B, WJ, B, B, - /* 0C10 */ B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0C20 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0C30 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, CMBlw, B, VAbv, VAbv, - /* 0C40 */ VAbv, VPst, VPst, VPst, VPst, WJ, VAbv, VAbv, VAbv, WJ, VAbv, VAbv, VAbv, H, WJ, WJ, - /* 0C50 */ WJ, WJ, WJ, WJ, WJ, VAbv, VBlw, WJ, B, B, B, WJ, WJ, O, WJ, WJ, - /* 0C60 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0C70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, O, O, O, O, O, - - /* Kannada */ - - /* 0C80 */ B, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, WJ, B, B, - /* 0C90 */ B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0CA0 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0CB0 */ B, B, B, B, WJ, B, B, B, B, B, WJ, WJ, CMBlw, B, VPst, VAbv, - /* 0CC0 */ VAbv, VPst, VPst, VPst, VPst, WJ, VAbv, VAbv, VAbv, WJ, VAbv, VAbv, VAbv, H, WJ, WJ, - /* 0CD0 */ WJ, WJ, WJ, WJ, WJ, VPst, VPst, WJ, WJ, WJ, WJ, WJ, WJ, O, B, WJ, - /* 0CE0 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0CF0 */ WJ, CS, CS, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Malayalam */ - - /* 0D00 */ VMAbv, VMAbv, VMPst, VMPst, B, B, B, B, B, B, B, B, B, WJ, B, B, - /* 0D10 */ B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst, - /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, WJ, VPre, VPre, VPre, WJ, VPre, VPre, VPre, H, R, O, - /* 0D50 */ WJ, WJ, WJ, WJ, O, O, O, VPst, O, O, O, O, O, O, O, B, - /* 0D60 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - - /* Sinhala */ - - /* 0D80 */ WJ, VMAbv, VMPst, VMPst, WJ, B, B, B, B, B, B, B, B, B, B, B, - /* 0D90 */ B, B, B, B, B, B, B, WJ, WJ, WJ, B, B, B, B, B, B, - /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0DB0 */ B, B, WJ, B, B, B, B, B, B, B, B, B, WJ, B, WJ, WJ, - /* 0DC0 */ B, B, B, B, B, B, B, WJ, WJ, WJ, HVM, WJ, WJ, WJ, WJ, VPst, - /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, WJ, VBlw, WJ, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, - /* 0DE0 */ WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0DF0 */ WJ, WJ, VPst, VPst, O, WJ, WJ, WJ, - -#define use_offset_0x0f00u 1456 - - - /* Tibetan */ - - /* 0F00 */ B, B, O, O, B, B, B, O, O, O, O, O, O, O, O, O, - /* 0F10 */ O, O, O, O, O, O, O, O, VBlw, VBlw, O, O, O, O, O, O, - /* 0F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0F30 */ B, B, B, B, O, FBlw, O, FBlw, O, CMAbv, O, O, O, O, VPst, VPre, - /* 0F40 */ B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, B, - /* 0F50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0F60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - /* 0F70 */ WJ, CMBlw, VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, O, - /* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, O, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB, - /* 0F90 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, WJ, SUB, SUB, SUB, SUB, SUB, SUB, SUB, - /* 0FA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, - /* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, WJ, O, O, - /* 0FC0 */ O, O, O, O, O, O, FBlw, O, - -#define use_offset_0x1000u 1656 - - - /* Myanmar */ - - /* 1000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1020 */ B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VAbv, VAbv, VBlw, - /* 1030 */ VBlw, VPre, VAbv, VAbv, VAbv, VAbv, VMAbv, VMBlw, VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, - /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, GB, O, O, GB, O, - /* 1050 */ B, B, B, B, B, B, VPst, VPst, VBlw, VBlw, B, B, B, B, MBlw, MBlw, - /* 1060 */ MBlw, B, VPst, VMPst, VMPst, B, B, VPst, VPst, VMPst, VMPst, VMPst, VMPst, VMPst, B, B, - /* 1070 */ B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, B, B, B, B, B, B, - /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, - /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, - -#define use_offset_0x1700u 1816 - - - /* Tagalog */ - - /* 1700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1710 */ B, B, VAbv, VBlw, VBlw, VPst, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, - - /* Hanunoo */ - - /* 1720 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1730 */ B, B, VAbv, VBlw, VPst, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Buhid */ - - /* 1740 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1750 */ B, B, VAbv, VBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Tagbanwa */ - - /* 1760 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, B, B, - /* 1770 */ B, WJ, VAbv, VBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Khmer */ - - /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17B0 */ B, B, B, B, CGJ, CGJ, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, - /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, VMAbv, - /* 17D0 */ FMAbv, VAbv, IS, FMAbv, O, O, O, O, O, O, O, O, B, FMAbv, WJ, WJ, - /* 17E0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 17F0 */ O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Mongolian */ - - /* 1800 */ B, O, O, O, O, O, O, B, O, O, B, CGJ, CGJ, CGJ, WJ, CGJ, - /* 1810 */ O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - /* 1820 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1830 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1870 */ B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 1880 */ GB, GB, GB, GB, GB, CMAbv, CMAbv, B, B, B, B, B, B, B, B, B, - /* 1890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18A0 */ B, B, B, B, B, B, B, B, B, CMBlw, B, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x1900u 2248 - - - /* Limbu */ - - /* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, - /* 1920 */ VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, WJ, WJ, WJ, WJ, - /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VMAbv, FMBlw, WJ, WJ, WJ, WJ, - /* 1940 */ O, WJ, WJ, WJ, O, O, B, B, B, B, B, B, B, B, B, B, - - /* Tai Le */ - - /* 1950 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1960 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, - /* 1970 */ B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* New Tai Lue */ - - /* 1980 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 19A0 */ B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, - /* 19B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 19C0 */ B, B, B, B, B, B, B, B, VMPst, VMPst, WJ, WJ, WJ, WJ, WJ, WJ, - /* 19D0 */ B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, O, O, - /* 19E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 19F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - - /* Buginese */ - - /* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A10 */ B, B, B, B, B, B, B, VAbv, VAbv, VPre, VPst, VAbv, WJ, WJ, O, O, - - /* Tai Tham */ - - /* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, WJ, - /* 1A60 */ Sk, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, - /* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, VMAbv, VMAbv, WJ, WJ, VMBlw, - /* 1A80 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 1A90 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x1b00u 2664 - - - /* Balinese */ - - /* 1B00 */ VMAbv, VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, - /* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, - /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, - /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, WJ, - - /* Sundanese */ - - /* 1B80 */ VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BA0 */ B, SUB, SUB, SUB, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, IS, SUB, SUB, B, B, - /* 1BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - - /* Batak */ - - /* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BE0 */ B, B, B, B, B, B, CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, - /* 1BF0 */ FAbv, FAbv, CMBlw, CMBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, - - /* Lepcha */ - - /* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv, - /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, WJ, WJ, WJ, O, O, O, O, O, - /* 1C40 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, B, B, B, - -#define use_offset_0x1cd0u 3000 - - - /* Vedic Extensions */ - - /* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw, - /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, - /* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x1df8u 3048 - - - /* Combining Diacritical Marks Supplement */ - O, O, O, FMAbv, O, O, O, O, - -#define use_offset_0x2008u 3056 - - - /* General Punctuation */ - O, O, O, WJ, ZWNJ, CGJ, WJ, WJ, - /* 2010 */ GB, GB, GB, GB, GB, O, O, O, O, O, O, O, O, O, O, O, - /* 2020 */ O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, O, - /* 2030 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 2040 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 2050 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 2060 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Superscripts and Subscripts */ - - /* 2070 */ O, O, WJ, WJ, FMPst, O, O, O, O, O, O, O, O, O, O, O, - /* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O, - -#define use_offset_0x20f0u 3184 - - - /* Combining Diacritical Marks for Symbols */ - - /* 20F0 */ VMAbv, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x25c8u 3192 - - - /* Geometric Shapes */ - O, O, O, O, B, O, O, O, - -#define use_offset_0x2d30u 3200 - - - /* Tifinagh */ - - /* 2D30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 2D40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 2D50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 2D60 */ B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, - /* 2D70 */ O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, H, - -#define use_offset_0xa800u 3280 - - - /* Syloti Nagri */ - - /* A800 */ B, B, VAbv, B, B, B, H, B, B, B, B, VMAbv, B, B, B, B, - /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A820 */ B, B, B, VPst, VPst, VBlw, VAbv, VPst, O, O, O, O, VBlw, WJ, WJ, WJ, - /* A830 */ O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Phags-pa */ - - /* A840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A870 */ B, B, B, B, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Saurashtra */ - - /* A880 */ VMPst, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A8A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A8B0 */ B, B, B, B, MPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, - /* A8C0 */ VPst, VPst, VPst, VPst, H, VMAbv, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, - /* A8D0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Devanagari Extended */ - - /* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, - /* A8F0 */ VMAbv, VMAbv, B, B, O, O, O, O, O, O, O, O, O, O, B, VAbv, - - /* Kayah Li */ - - /* A900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A920 */ B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VAbv, VMBlw, VMBlw, VMBlw, O, O, - - /* Rejang */ - - /* A930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A940 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VBlw, VBlw, VBlw, VBlw, FAbv, - /* A950 */ FAbv, FAbv, FPst, VPst, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, - /* A960 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* A970 */ O, O, O, O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, - - /* Javanese */ - - /* A980 */ VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, - /* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, MBlw, MPst, MBlw, - /* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, WJ, O, - /* A9D0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, O, O, - - /* Myanmar Extended-B */ - - /* A9E0 */ B, B, B, B, B, VAbv, O, B, B, B, B, B, B, B, B, B, - /* A9F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, - - /* Cham */ - - /* AA00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA20 */ B, B, B, B, B, B, B, B, B, VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, - /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MAbv, MBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* AA40 */ B, B, B, FAbv, B, B, B, B, B, B, B, B, FAbv, FPst, WJ, WJ, - /* AA50 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, O, O, O, O, - - /* Myanmar Extended-A */ - - /* AA60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA70 */ O, B, B, B, GB, GB, GB, O, O, O, B, VMPst, VMAbv, VMPst, B, B, - - /* Tai Viet */ - - /* AA80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AAA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AAB0 */ VAbv, B, VAbv, VAbv, VBlw, B, B, VAbv, VAbv, B, B, B, B, B, VAbv, VMAbv, - /* AAC0 */ B, VMAbv, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* AAD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, O, - - /* Meetei Mayek Extensions */ - - /* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, - /* AAF0 */ O, O, O, O, O, VMPst, IS, WJ, - -#define use_offset_0xabc0u 4040 - - - /* Meetei Mayek */ - - /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* ABD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, WJ, WJ, - /* ABF0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0xfe00u 4104 - - - /* Variation Selectors */ - - /* FE00 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - -#define use_offset_0xfef8u 4120 - - - /* Arabic Presentation Forms-B */ - O, O, O, O, O, WJ, WJ, WJ, - -#define use_offset_0xfff0u 4128 - - - /* Specials */ - - /* FFF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, O, WJ, WJ, - -#define use_offset_0x10570u 4144 - - - /* Vithkuqi */ - - /* 10570 */ B, B, B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, - /* 10580 */ B, B, B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, - /* 10590 */ B, B, B, WJ, B, B, WJ, B, B, B, B, B, B, B, B, B, - /* 105A0 */ B, B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 105B0 */ B, B, WJ, B, B, B, B, B, B, B, WJ, B, B, WJ, WJ, WJ, - -#define use_offset_0x10a00u 4224 - - - /* Kharoshthi */ - - /* 10A00 */ B, VBlw, VBlw, VBlw, WJ, VAbv, VBlw, WJ, WJ, WJ, WJ, WJ, VPst, VMBlw, VMBlw, VMAbv, - /* 10A10 */ B, B, B, B, WJ, B, B, B, WJ, B, B, B, B, B, B, B, - /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10A30 */ B, B, B, B, B, B, WJ, WJ, CMBlw, CMBlw, CMBlw, WJ, WJ, WJ, WJ, IS, - /* 10A40 */ B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x10ac0u 4304 - - - /* Manichaean */ - - /* 10AC0 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B, - /* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, WJ, WJ, WJ, WJ, B, B, B, B, B, - -#define use_offset_0x10b80u 4352 - - - /* Psalter Pahlavi */ - - /* 10B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10B90 */ B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, WJ, WJ, WJ, - /* 10BA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, O, - -#define use_offset_0x10d00u 4400 - - - /* Hanifi Rohingya */ - - /* 10D00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10D30 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x10e80u 4464 - - - /* Yezidi */ - - /* 10E80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10E90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10EA0 */ B, B, B, B, B, B, B, B, B, B, WJ, VAbv, VAbv, O, WJ, WJ, - /* 10EB0 */ B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x10f30u 4520 - - - /* Sogdian */ - - /* 10F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, - /* 10F50 */ VMBlw, B, B, B, B, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10F60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Old Uyghur */ - - /* 10F70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10F80 */ B, B, CMBlw, CMBlw, CMBlw, CMBlw, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10F90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10FA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Chorasmian */ - - /* 10FB0 */ B, O, B, B, B, B, B, O, B, B, B, B, B, B, B, B, - /* 10FC0 */ O, B, B, B, B, O, O, O, O, B, B, B, WJ, WJ, WJ, WJ, - /* 10FD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10FE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 10FF0 */ O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Brahmi */ - - /* 11000 */ VMPst, VMAbv, VMPst, CS, CS, B, B, B, B, B, B, B, B, B, B, B, - /* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, - /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, WJ, WJ, - /* 11050 */ WJ, WJ, N, N, N, N, N, N, N, N, N, N, N, N, N, N, - /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, - /* 11070 */ VAbv, B, B, VAbv, VAbv, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, HN, - - /* Kaithi */ - - /* 11080 */ VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, - /* 110C0 */ O, O, VBlw, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x11100u 4928 - - - /* Chakma */ - - /* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11120 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VBlw, VAbv, VAbv, - /* 11130 */ VBlw, VAbv, VAbv, IS, CMAbv, WJ, B, B, B, B, B, B, B, B, B, B, - /* 11140 */ O, O, O, O, B, VPst, VPst, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Mahajani */ - - /* 11150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11170 */ B, B, B, CMBlw, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Sharada */ - - /* 11180 */ VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, - /* 111C0 */ H, B, R, R, O, O, O, O, O, FMBlw, CMBlw, VAbv, VBlw, O, VPre, VMAbv, - /* 111D0 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, - - /* Sinhala Archaic Numbers */ - - /* 111E0 */ WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111F0 */ B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Khojki */ - - /* 11200 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11210 */ B, B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, - /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, WJ, - -#define use_offset_0x11280u 5248 - - - /* Multani */ - - /* 11280 */ B, B, B, B, B, B, B, WJ, B, WJ, B, B, B, B, WJ, B, - /* 11290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, B, - /* 112A0 */ B, B, B, B, B, B, B, B, B, O, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Khudawadi */ - - /* 112B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 112C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 112D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, - /* 112E0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, CMBlw, VBlw, WJ, WJ, WJ, WJ, WJ, - /* 112F0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Grantha */ - - /* 11300 */ VMAbv, VMAbv, VMAbv, VMAbv, WJ, B, B, B, B, B, B, B, B, WJ, WJ, B, - /* 11310 */ B, WJ, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11320 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 11330 */ B, WJ, B, B, WJ, B, B, B, B, B, WJ, CMBlw, CMBlw, B, VPst, VPst, - /* 11340 */ VAbv, VPst, VPst, VPst, VPst, WJ, WJ, VPre, VPre, WJ, WJ, VPre, VPre, H, WJ, WJ, - /* 11350 */ O, WJ, WJ, WJ, WJ, WJ, WJ, VPst, WJ, WJ, WJ, WJ, WJ, O, B, B, - /* 11360 */ B, B, VPst, VPst, WJ, WJ, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, WJ, WJ, WJ, - /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, WJ, WJ, WJ, - -#define use_offset_0x11400u 5496 - - - /* Newa */ - - /* 11400 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11410 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11430 */ B, B, B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, - /* 11440 */ VPst, VPst, H, VMAbv, VMAbv, VMPst, CMBlw, B, O, O, O, O, O, O, O, O, - /* 11450 */ B, B, B, B, B, B, B, B, B, B, O, O, WJ, O, FMAbv, B, - /* 11460 */ CS, CS, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11470 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Tirhuta */ - - /* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv, - /* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 114D0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x11580u 5720 - - - /* Siddham */ - - /* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, - /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, WJ, WJ, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H, - /* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, WJ, WJ, - /* 115E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 115F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Modi */ - - /* 11600 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11610 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11620 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11630 */ VPst, VPst, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPst, VPst, VMAbv, VMPst, H, - /* 11640 */ VAbv, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11650 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11660 */ O, O, O, O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, - /* 11670 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Takri */ - - /* 11680 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11690 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 116A0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMPst, VAbv, VPre, VPst, - /* 116B0 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, CMBlw, B, O, WJ, WJ, WJ, WJ, WJ, WJ, - /* 116C0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 116D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 116E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 116F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Ahom */ - - /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11710 */ B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, MBlw, MPre, MAbv, - /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, WJ, WJ, WJ, WJ, - /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, - /* 11740 */ B, B, B, B, B, B, B, WJ, - -#define use_offset_0x11800u 6176 - - - /* Dogra */ - - /* 11800 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw, - /* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, WJ, WJ, WJ, WJ, - -#define use_offset_0x11900u 6240 - - - /* Dives Akuru */ - - /* 11900 */ B, B, B, B, B, B, B, WJ, WJ, B, WJ, WJ, B, B, B, B, - /* 11910 */ B, B, B, B, WJ, B, B, WJ, B, B, B, B, B, B, B, B, - /* 11920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11930 */ VPst, VPst, VPst, VPst, VPst, VPre, WJ, VPre, VPre, WJ, WJ, VMAbv, VMAbv, VPst, IS, R, - /* 11940 */ MPst, R, MPst, CMBlw, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11950 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x119a0u 6336 - - - /* Nandinagari */ - - /* 119A0 */ B, B, B, B, B, B, B, B, WJ, WJ, B, B, B, B, B, B, - /* 119B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 119C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 119D0 */ B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, WJ, WJ, VAbv, VAbv, VPst, VPst, VMPst, VMPst, - /* 119E0 */ H, B, O, O, VPre, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 119F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Zanabazar Square */ - - /* 11A00 */ B, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VAbv, VAbv, VBlw, B, B, B, B, B, - /* 11A10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11A30 */ B, B, B, FMBlw, VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst, R, MBlw, MBlw, MBlw, MBlw, GB, - /* 11A40 */ O, O, O, O, O, GB, O, IS, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Soyombo */ - - /* 11A50 */ B, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VBlw, VBlw, VBlw, B, B, B, B, - /* 11A60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11A70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, - /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, IS, O, O, O, B, O, O, - -#define use_offset_0x11c00u 6592 - - - /* Bhaiksuki */ - - /* 11C00 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 11C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, - /* 11C30 */ VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VBlw, WJ, VAbv, VAbv, VAbv, VAbv, VMAbv, VMAbv, VMPst, H, - /* 11C40 */ B, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - - /* Marchen */ - - /* 11C70 */ O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11C90 */ WJ, WJ, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, - /* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, WJ, SUB, SUB, SUB, SUB, SUB, SUB, SUB, - /* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, WJ, - -#define use_offset_0x11d00u 6776 - - - /* Masaram Gondi */ - - /* 11D00 */ B, B, B, B, B, B, B, WJ, B, B, WJ, B, B, B, B, B, - /* 11D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11D30 */ B, VAbv, VAbv, VAbv, VAbv, VAbv, VBlw, WJ, WJ, WJ, VAbv, WJ, VAbv, VAbv, WJ, VAbv, - /* 11D40 */ VMAbv, VMAbv, CMBlw, VAbv, VBlw, IS, R, MBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11D50 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Gunjala Gondi */ - - /* 11D60 */ B, B, B, B, B, B, WJ, B, B, WJ, B, B, B, B, B, B, - /* 11D70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11D80 */ B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VPst, VPst, WJ, - /* 11D90 */ VAbv, VAbv, WJ, VPst, VPst, VMAbv, VMPst, IS, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11DA0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x11ee0u 6952 - - - /* Makasar */ - - /* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O, - -#define use_offset_0x13000u 6976 - - - /* Egyptian Hieroglyphs */ - - /* 13000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13030 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13040 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13050 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13060 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13070 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13080 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13130 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13140 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13170 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13180 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13200 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13210 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13220 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13230 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13240 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13250 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13260 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13270 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13280 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13300 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13310 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13320 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13330 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13340 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13350 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13360 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13370 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13380 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13390 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13400 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13410 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, - - /* Egyptian Hieroglyph Format Controls */ - - /* 13430 */ H, H, H, H, H, H, H, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x16ac0u 8064 - - - /* Tangsa */ - - /* 16AC0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 16AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 16AE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, WJ, WJ, - /* 16AF0 */ O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Pahawh Hmong */ - - /* 16B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, - -#define use_offset_0x16f00u 8184 - - - /* Miao */ - - /* 16F00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16F10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16F40 */ B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, CMBlw, - /* 16F50 */ O, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, - /* 16F60 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, - /* 16F70 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, - /* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, VMBlw, - /* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O, - -#define use_offset_0x16fe0u 8336 - - - /* Ideographic Symbols and Punctuation */ - - /* 16FE0 */ O, O, O, O, B, WJ, WJ, WJ, - -#define use_offset_0x18b00u 8344 - - - /* Khitan Small Script */ - - /* 18B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BF0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18CA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18CB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18CD0 */ B, B, B, B, B, B, WJ, WJ, - -#define use_offset_0x1bc00u 8816 - - - /* Duployan */ - - /* 1BC00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC60 */ B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, - /* 1BC70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - /* 1BC80 */ B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 1BC90 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, O, CMBlw, CMBlw, O, - -#define use_offset_0x1d170u 8976 - - - /* Musical Symbols */ - - /* 1D170 */ O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, O, - -#define use_offset_0x1e100u 8992 - - - /* Nyiakeng Puachue Hmong */ - - /* 1E100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, WJ, WJ, - /* 1E140 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, B, B, - -#define use_offset_0x1e290u 9072 - - - /* Toto */ - - /* 1E290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E2A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, WJ, - /* 1E2B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Wancho */ - - /* 1E2C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E2D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, - /* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, O, - -#define use_offset_0x1e900u 9184 - - - /* Adlam */ - - /* 1E900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, WJ, WJ, WJ, WJ, - /* 1E950 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, O, O, - -#define use_offset_0xe0000u 9280 - - - /* Tags */ - - /* E0000 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0010 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0020 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0030 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0040 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0050 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0060 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0070 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* No_Block */ - - /* E0080 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0090 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Variation Selectors Supplement */ - - /* E0100 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0110 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0120 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0130 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0140 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0150 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0160 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0170 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0180 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0190 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01A0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01B0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01C0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01D0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01E0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - - /* No_Block */ - - /* E01F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0200 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0210 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0220 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0230 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0240 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0250 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0260 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0270 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0280 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0290 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0300 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0310 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0320 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0330 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0340 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0350 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0360 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0370 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0380 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0390 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0400 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0410 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0420 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0430 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0440 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0450 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0460 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0470 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0480 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0490 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0500 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0510 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0520 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0530 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0540 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0550 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0560 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0570 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0580 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0590 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0600 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0610 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0620 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0630 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0640 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0650 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0660 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0670 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0680 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0690 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0700 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0710 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0720 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0730 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0740 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0750 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0760 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0770 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0780 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0790 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0800 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0810 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0820 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0830 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0840 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0850 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0860 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0870 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0880 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0890 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0900 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0910 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0920 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0930 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0940 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0950 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0960 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0970 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0980 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0990 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0ED0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - -}; /* Table items: 13376; occupancy: 84% */ - -static inline uint8_t -hb_use_get_category (hb_glyph_info_t info) +static const uint8_t +hb_use_u8[1842] = { - hb_codepoint_t u = info.codepoint; - switch (u >> 12) - { - case 0x0u: - if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; - if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u]; - if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0F00u, 0x0FC7u)) return use_table[u - 0x0F00u + use_offset_0x0f00u]; - break; - - case 0x1u: - if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x18AFu)) return use_table[u - 0x1700u + use_offset_0x1700u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1DF8u, 0x1DFFu)) return use_table[u - 0x1DF8u + use_offset_0x1df8u]; - break; - - case 0x2u: - if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2087u)) return use_table[u - 0x2008u + use_offset_0x2008u]; - if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u]; - if (hb_in_range<hb_codepoint_t> (u, 0x2D30u, 0x2D7Fu)) return use_table[u - 0x2D30u + use_offset_0x2d30u]; - break; - - case 0xAu: - if (hb_in_range<hb_codepoint_t> (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u]; - if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; - break; - - case 0xFu: - if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u]; - if (hb_in_range<hb_codepoint_t> (u, 0xFEF8u, 0xFEFFu)) return use_table[u - 0xFEF8u + use_offset_0xfef8u]; - if (hb_in_range<hb_codepoint_t> (u, 0xFFF0u, 0xFFFFu)) return use_table[u - 0xFFF0u + use_offset_0xfff0u]; - break; - - case 0x10u: - if (hb_in_range<hb_codepoint_t> (u, 0xFFF0u, 0xFFFFu)) return use_table[u - 0xFFF0u + use_offset_0xfff0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10570u, 0x105BFu)) return use_table[u - 0x10570u + use_offset_0x10570u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; - break; - - case 0x11u: - if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x11747u)) return use_table[u - 0x11580u + use_offset_0x11580u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11800u, 0x1183Fu)) return use_table[u - 0x11800u + use_offset_0x11800u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11900u, 0x1195Fu)) return use_table[u - 0x11900u + use_offset_0x11900u]; - if (hb_in_range<hb_codepoint_t> (u, 0x119A0u, 0x11A9Fu)) return use_table[u - 0x119A0u + use_offset_0x119a0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11DAFu)) return use_table[u - 0x11D00u + use_offset_0x11d00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11EE0u, 0x11EF7u)) return use_table[u - 0x11EE0u + use_offset_0x11ee0u]; - break; - - case 0x13u: - if (hb_in_range<hb_codepoint_t> (u, 0x13000u, 0x1343Fu)) return use_table[u - 0x13000u + use_offset_0x13000u]; - break; - - case 0x16u: - if (hb_in_range<hb_codepoint_t> (u, 0x16AC0u, 0x16B37u)) return use_table[u - 0x16AC0u + use_offset_0x16ac0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u]; - break; - - case 0x18u: - if (hb_in_range<hb_codepoint_t> (u, 0x18B00u, 0x18CD7u)) return use_table[u - 0x18B00u + use_offset_0x18b00u]; - break; - - case 0x1Bu: - if (hb_in_range<hb_codepoint_t> (u, 0x1BC00u, 0x1BC9Fu)) return use_table[u - 0x1BC00u + use_offset_0x1bc00u]; - break; - - case 0x1Du: - if (hb_in_range<hb_codepoint_t> (u, 0x1D170u, 0x1D17Fu)) return use_table[u - 0x1D170u + use_offset_0x1d170u]; - break; - - case 0x1Eu: - if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1E290u, 0x1E2FFu)) return use_table[u - 0x1E290u + use_offset_0x1e290u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u]; - break; - - case 0xE0u: - if (hb_in_range<hb_codepoint_t> (u, 0xE0000u, 0xE0FFFu)) return use_table[u - 0xE0000u + use_offset_0xe0000u]; - break; - - case 0xE1u: - if (hb_in_range<hb_codepoint_t> (u, 0xE0000u, 0xE0FFFu)) return use_table[u - 0xE0000u + use_offset_0xe0000u]; - break; - - default: - break; - } - if (_hb_glyph_info_get_general_category (&info) == HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) - return WJ; - return O; + 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 5, + 6, 7, 3, 8, 3, 3, 9, 3, 10, 3, 3, 11, 3, 12, 13, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 14, 0, 0, 1, 1, 2, 1, 1, 3, 4, 5, 6, 7, 8, 9, 10, + 1, 11, 12, 1, 1, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 19, + 1, 1, 20, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 22, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 25, 26, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 27, 28, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 30, 31, 1, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 46, 47, + 48, 1, 49, 49, 49, 49, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 51, 52, 1, 1, + 1, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 49, 54, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 1, + 1, 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 57, 58, 1, 1, 1, 1, 1, 1, 59, 1, 1, 1, 1, + 1, 1, 60, 61, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, O, O, O, O, O, GB, O, O, B, B, B, B, B, B, + O, O, GB, O, O, O, O, WJ, O, O, O, O,FMPst,FMPst, O, O, + O, GB, O, O, O, CGJ, B, O, O, O, O, O, B, B, B, B, + B,VMAbv,VMAbv,VMAbv,VMAbv,VMAbv, O, O, B, O, O,VMAbv, O, O, B,CMBlw, + CMBlw,CMBlw,VMAbv,VMAbv,VMAbv,VMPst, B, B, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, + VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst, O,VMAbv, + VMBlw, O, O, VAbv, VBlw, VBlw, B, B, VBlw, VBlw, GB,VMAbv,VMPst,VMPst, O, B, + B, B, B, O, O, B, B, O, B, B, B, O, B, O, VBlw, O, + O, VPre, VPre, O, O, VPre, VPre, H, O, O, O, O, O, VPst, B, B, + O, B, B, O,FMAbv, O, O,VMAbv,VMAbv,VMPst, B, B, B, O, O, O, + O, B, O, B, B, O,CMBlw, O, VPst, VPre, VPst, VBlw, VBlw, O, O, O, + O, VAbv, VAbv, O, O, VAbv, VAbv, H, O, O, O,VMBlw, O, O,VMAbv,CMAbv, + GB, GB, O, MBlw, O, O, VBlw, VAbv, O, VAbv, VAbv, VAbv, O, VPst, VPst, H, + O, O, O, B,VMAbv,VMAbv,VMAbv,CMAbv,CMAbv,CMAbv, O,VMAbv,VMPst,VMPst,CMBlw, B, + VPst, VAbv, O, VAbv, VAbv, VAbv, O, B, O, O, O, O,VMAbv, O, O, O, + VPst, VPst, VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre,VMAbv,VMPst, + VMPst,VMPst,VMAbv, B, B, B,CMBlw, B, VAbv, VAbv, VPst, O, VAbv, VAbv, VAbv, O, + VAbv, VAbv, O, VAbv, VBlw, O, B,VMAbv,VMPst,VMPst, O, VPst, VPst, O, O, CS, + CS, O,VMAbv,VMAbv,VMPst,VMPst, B, B, B, VAbv, VAbv, B, VPst, VPst, VPst, VPst, + VPst, VBlw, VBlw, O, VPre, VPre, VPre, H, R, O, O, O, HVM, O, VPst, VPst, + VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, VBlw, VBlw, + O, O, O, FBlw, O, FBlw, O,CMAbv, O, O, O, O, VPst, VPre, O,CMBlw, + VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw,VMAbv, O, VBlw, VAbv, + VMAbv,VMAbv, VBlw, O,VMAbv,VMAbv, B, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, + SUB, SUB, SUB, O, O, O, O, O, FBlw, O, B, B, B, VPst, VPst, VAbv, + VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv, VAbv,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, + MBlw, B, B, B, O, GB, O, O, GB, O, B, B, VPst, VPst, VBlw, VBlw, + B, B, B, B, MBlw, MBlw, MBlw, B, VPst,VMPst,VMPst, B, B, VPst, VPst,VMPst, + VMPst,VMPst,VMPst,VMPst, B, B, B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, + MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMPst,VMPst,VMPst,VMPst,VMBlw, B,VMPst, B, B, + VMPst,VMPst, VPst, VAbv, O, O, B, B, VAbv, VBlw, VBlw, VPst, O, O, VPst, O, + O, O, B, O, VAbv, VBlw, CGJ, CGJ, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, + VPre, VPre, VPre, VPre, VPre, VPre, VPre, VPre,VMAbv,VMPst, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv, + FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, O, O, O, O, B, CGJ, CGJ, CGJ, + WJ, CGJ, GB, GB, GB, GB, GB,CMAbv,CMAbv, B, B,CMBlw, B, O, GB, B, + B, B, VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, FPst, FPst, + VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw,VMAbv,FMBlw,VMPst,VMPst, O, O, VAbv, VPre, + VPst, VAbv, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, O, Sk, VPst, + VAbv, VPst, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, VPre, VPre, VPre, VAbv,VMAbv,VMAbv, + VAbv,VMAbv,VMAbv, O, O,VMBlw,VMAbv,VMAbv,VMAbv, FAbv,VMPst, B, B, B,CMAbv, VPst, + VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, VPre, VPre, VAbv, VAbv, H, B, + B, B, O, O, O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,VMAbv, FAbv, + VMPst, B, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, IS, SUB, SUB, B, B, B, B, + CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, FAbv, FAbv,CMBlw,CMBlw, SUB, SUB, + VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv, FAbv, FAbv, FAbv, FAbv,VMPre,VMPre, + FMAbv,CMBlw,VMAbv,VMAbv,VMAbv, O,VMBlw,VMBlw,VMBlw,VMBlw,VMBlw,VMBlw,VMAbv,VMAbv,VMAbv,VMPst, + VMBlw,VMBlw,VMBlw, O, O, O,VMAbv, CS, CS,VMPst,VMAbv,VMAbv, GB, O, O, O, + O,FMAbv, O, O, O, WJ, ZWNJ, CGJ, WJ, WJ, O, O, WJ, WJ, WJ, WJ, + WJ, O, WJ, WJ, WJ, WJ,FMPst, O, O, O,VMAbv, O, O, O, O, O, + O, H, B, B, VAbv, B, B, B, H, B, VPst, VBlw, VAbv, VPst, VBlw, O, + O, O, MPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, H,VMAbv, O, O,VMAbv,VMAbv, + B, B, O, O, B, VAbv, B, B, VAbv, VAbv, VAbv, VAbv, VAbv,VMBlw,VMBlw,VMBlw, + O, O, B, B, B, VBlw, VBlw, VBlw, VAbv, VBlw, VBlw, VBlw, VBlw, FAbv, FAbv, FAbv, + FPst, VPst,VMAbv,VMAbv, FAbv,VMPst, B, B, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, + O, O, B, VAbv, O, B, B,VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, VPre, VAbv, + VBlw, MPst, MPre, MAbv, MBlw, O, B, B, B, FAbv, FAbv, FPst, O, O, GB, GB, + GB, O, O, O, B,VMPst,VMAbv,VMPst, B, B, VAbv, B, VAbv, VAbv, VBlw, B, + B, VAbv, B, B, VAbv,VMAbv, B,VMAbv, B, O, B, B, B, VPre, VBlw, VAbv, + VPre, VPst, O,VMPst, IS, O, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O,VMPst, VBlw, + O, O, CGJ, CGJ, CGJ, CGJ, WJ, O, O, O, B, VBlw, VBlw, VBlw, VPst,VMBlw, + VMBlw,VMAbv,CMBlw,CMBlw,CMBlw, O, O, O, O, IS, B,CMBlw,CMBlw, O,VMAbv,VMAbv, + VMAbv,CMAbv, B, B, O, VAbv, VAbv, O, O, O, B, B,VMBlw,VMBlw,VMBlw, B, + B, B, B, B,CMBlw,CMBlw,CMBlw,CMBlw, O, O,VMPst,VMAbv,VMPst, CS, CS, B, + B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, + N, N, N, N, N, N, N, N, B, B, VAbv, B, B, VAbv, VAbv, B, + O, O, O, O, O, HN,VMAbv,VMAbv,VMPst, B, VPst, VPre, VPst, VBlw, VBlw, VAbv, + VAbv, VPst, VPst, H,CMBlw, O, O, O, VBlw, O,VMAbv,VMAbv,VMAbv, B, VPre, VBlw, + VAbv, VAbv, VBlw, VAbv, VAbv, IS,CMAbv, O, B, B, B, VPst, VPst, B, B, B, + B,CMBlw, VPre, VPst, VBlw, VBlw, H, B, R, R, O,FMBlw,CMBlw, VAbv, VBlw, O, + VPre,VMAbv,VMAbv, H,CMAbv,CMAbv, VAbv,CMBlw, VBlw, O, B, B, O,CMBlw,CMBlw, B, + VPst, VPst, VPst, O, O, VPre, O, O,VMAbv,VMAbv, B, VPst, VPre, VPst, VPst, VPst, + H,VMAbv,VMAbv,VMPst,CMBlw, B, O, O,FMAbv, B, CS, CS, O, O, VBlw, VPre, + VAbv, VPre, VPre, VPst, VPre,VMAbv,VMAbv,VMAbv, H,CMBlw,VMAbv,VMAbv,VMPst, H,CMBlw, O, + O, O, VPst,VMAbv,VMPst, H,VMPst, VAbv, VPre, VPst, VAbv, VAbv, H,CMBlw, O, MBlw, + MPre, MAbv, VBlw, VBlw, VPre, VAbv, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv,VMAbv,VMPst, H, + CMBlw, O, VPst, VPre, O, VPre, VPre, O, O,VMAbv,VMAbv, VPst, IS, R, MPst, R, + MPst,CMBlw, O, O, VAbv, VAbv, VPst, VPst,VMPst,VMPst, H, B, O, O, VPre, O, + O, O, B, VAbv, VBlw, VBlw, VAbv, VAbv, VBlw, B, B, B, B,FMBlw, VBlw,VMAbv, + VMAbv,VMAbv,VMAbv,VMPst, R, MBlw, MBlw, MBlw, MBlw, GB, O, GB, O, IS, VAbv, VAbv, + VAbv, VPst, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, + VMAbv,VMPst,CMAbv, IS, O, O, VBlw, VBlw, VBlw, O, O, O, SUB, SUB, VBlw, VPre, + VBlw, VAbv, VPst,VMAbv,VMAbv, O, VAbv, VAbv, VBlw, O, O, O, VAbv, O, VAbv, VAbv, + O, VAbv,VMAbv,VMAbv,CMBlw, VAbv, VBlw, IS, R, MBlw, VPst, VPst, VPst, O, VPst,VMAbv, + VMPst, IS, B, B, GB, VAbv, VBlw, VPre, VPst, O, H, H, H, H, H, H, + H, B, O, O, O,CMBlw, O, VBlw, VBlw, VBlw, O, O, O,VMBlw,VMBlw,VMBlw, + VMBlw, O, O,CMBlw,CMBlw, O, B, B,VMAbv, O,CMAbv,CMAbv,CMAbv,CMAbv,CMAbv,CMAbv, + CMAbv, B, +}; +static const uint16_t +hb_use_u16[2056] = +{ + 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 11, + 0, 0, 0, 0, 9, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 9, 9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 17, 25, + 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35, 0, 17, 36, + 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46, 30, 0, + 47, 48, 21, 49, 50, 51, 17, 0, 52, 48, 21, 53, 50, 54, 17, 55, + 56, 48, 9, 57, 58, 59, 17, 0, 60, 61, 9, 62, 63, 64, 30, 65, + 66, 67, 9, 68, 69, 9, 70, 71, 72, 73, 74, 75, 76, 0, 0, 0, + 9, 9, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 0, 0, 0, 0, + 9, 85, 9, 86, 9, 87, 88, 89, 9, 9, 9, 90, 91, 92, 2, 0, + 93, 0, 9, 9, 9, 9, 9, 94, 95, 9, 96, 0, 0, 0, 0, 0, + 97, 98, 99,100, 30, 9,101,102, 9, 9,103, 9,104,105, 0, 0, + 9,106, 9, 9, 9,107,108,109, 2, 2, 0, 0, 0, 0, 0, 0, + 110, 9, 9,111,112, 2,113,114,115, 9,116, 9, 9, 9,117,118, + 9, 9,119,120,121, 0, 0, 0, 0, 0, 0, 0, 0,122,123,124, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,125, + 126,127,128, 0, 0, 0,129,130,131, 0, 0, 0, 0, 0, 0,132, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,133, 0, 0, 0, + 0, 0, 0, 9, 9, 9,134,135, 0, 0, 0, 0, 0, 0, 0, 0, + 136, 9,137, 0, 9, 9, 9,138,139, 9, 9,140,141, 2,142,143, + 9, 9,144, 9,145,146, 0, 0,147, 9, 9,148,149, 2,150, 98, + 9, 9,151,152,153, 2, 9,154, 9, 9, 9,155,156, 0,157,158, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,159, 2, + 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, + 0, 0, 0, 0, 0, 0, 0,163,163,164, 33,165, 0, 0, 0, 0, + 166,167, 9,168, 94, 0, 0, 0, 0, 0, 0, 0, 69, 9,169, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9,170,171, 0, 0, 0, 0, 0, + 9, 9,172, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,173,170, 0, 0, 0, 0, + 0, 0, 0, 9,174,175, 0, 9,176, 0, 0,177,178, 0, 0, 0, + 179, 9, 9,180,181,182,183,184,185, 9, 9,186,187, 0, 0, 0, + 188, 9,189,190,191, 9, 9,192,185, 9, 9,193,194,105,195,102, + 9, 33,196,197, 0, 0, 0, 0,198,199, 94, 9, 9,200,201, 2, + 202, 20, 21,203,204,205,206,207, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9,208,209,210,211, 0,195, 9, 9,212,213, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,214,215,216,217, 0, 0, + 9, 9, 9,218,219, 2, 0, 0, 9, 9,220,221, 2, 0, 0, 0, + 9,222,223,103,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9,225,226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 227,228, 9,229,230, 2, 0, 0, 0, 0,231, 9, 9,232,233, 0, + 234, 9, 9,235,236,237, 9, 9,238,239, 0, 0, 0, 0, 0, 0, + 21, 9,214,240, 7, 9, 70, 18, 9,241, 73,242, 0, 0, 0, 0, + 243, 9, 9,244,245, 2,246, 9,247,248, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,249, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 98,250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 9, 9, 9,251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9,252,253,254,254,255,256, 0, 0, 0, 0,257, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,258, 0, 0, + 9, 9, 9, 9, 9, 9,105, 70, 94,259, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,260, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 70,261,262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,263, 0, 9, 9,264, 2, + 9, 9, 9, 9,265, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, + 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,129, + 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 0, 5, + 6, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, + 0, 0, 10, 2, 2, 2, 2, 2, 2, 2, 11, 12, 12, 0, 13, 14, + 2, 2, 15, 0, 16, 2, 2, 2, 2, 2, 17, 18, 19, 20, 21, 22, + 23, 24, 2, 2, 25, 10, 2, 2, 10, 2, 2, 2, 26, 27, 2, 28, + 28, 2, 2, 2, 2, 2, 29, 2, 30, 10, 3, 18, 19, 31, 32, 33, + 0, 34, 0, 35, 3, 0, 0, 36, 37, 27, 38, 39, 29, 40, 3, 41, + 42, 43, 44, 45, 46, 0, 27, 30, 0, 10, 2, 2, 47, 48, 0, 0, + 37, 27, 2, 35, 35, 2, 2, 2, 29, 27, 3, 18, 19, 49, 50, 51, + 0, 0, 52, 53, 54, 27, 2, 28, 29, 27, 3, 55, 0, 56, 0, 35, + 57, 0, 0, 0, 58, 27, 38, 10, 29, 3, 40, 29, 39, 9, 38, 10, + 2, 2, 3, 59, 60, 61, 62, 33, 0, 34, 0, 0, 63, 64, 2, 29, + 29, 2, 2, 2, 2, 2, 3, 65, 21, 66, 67, 45, 0, 68, 38, 0, + 69, 27, 2, 29, 2, 27, 3, 55, 0, 70, 0, 13, 71, 0, 0, 0, + 72, 2, 2, 29, 2, 2, 73, 74, 75, 76, 62, 77, 0, 34, 0, 39, + 54, 27, 2, 2, 2, 38, 10, 2, 35, 2, 2, 57, 2, 38, 78, 34, + 79, 80, 81, 82, 59, 0, 0, 0, 3, 38, 0, 0, 0, 0, 83, 0, + 2, 84, 85, 86, 2, 2, 27, 2, 2, 2, 2, 9, 87, 88, 89, 90, + 91, 92, 2, 93, 94, 94, 95, 94, 94, 94, 94, 94, 94, 94, 94, 96, + 0, 97, 0, 0, 2, 2, 98, 99,100,101,102,103, 2, 2,104,105, + 2,106,107,108,109,110,111,112,113,114, 2, 2,115,116,117,118, + 2, 2,119,120,121,122, 0, 39,121,123, 0, 0,121, 0, 0, 0, + 2, 2, 2, 29,124, 0, 0, 0, 2,125,126,127,128,129,130,131, + 132, 0, 0,133, 9, 39,134,135, 2, 2, 9, 0,136,137, 2, 2, + 2, 2,138, 0,139, 2, 2, 2, 2, 2, 2, 38,140,141,142, 0, + 143,144,145, 0, 2, 2, 2, 3, 2, 9, 0, 0, 2, 2, 2, 0, + 2, 2,146, 0, 2, 2, 38, 0, 2, 73,147, 0, 2,148,149,150, + 151,141,152,153,154, 12,155,156,157,158, 2, 2, 2,159,160,161, + 162,163, 2, 9, 0, 0,164,165,166, 0, 0, 0,167, 2, 2, 2, + 93,168,169,170, 2,171,172,173,174, 0, 0, 0, 2,175,176,177, + 178,179, 0, 0, 2, 2, 3, 27,180,181,182,181,183,181,184, 46, + 0,185,186, 0, 0, 0,187, 0, 0, 0,188,189,136, 4, 0, 0, + 0, 0,190,191,192,192,192,192, 0,193, 0, 0, 6,193, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 9, 2, 2, 0, 39, 0, 0, 0,195, + 196,197, 11, 2, 98,198, 0,199, 2, 0, 0, 0,112, 2, 2, 2, + 2,200,201,201,201,202, 0, 0, 12, 12, 12, 12,203, 0, 0,204, + 2,205,206,207, 2,208,209,210,211, 0, 0, 0,212, 2, 2, 2, + 213, 79,127,214,215, 0, 0, 0, 2,216, 2, 2, 2, 2,217,218, + 219,220, 0, 0,221, 2, 2,222, 27,223,224,225,226,227,114,228, + 229, 0, 0, 0, 2, 2,230,231, 0,232, 0, 0, 98,233,234,235, + 236,236,236,236, 0, 0, 0,188,192,192,237, 0, 2, 2, 38, 2, + 38, 35, 2, 2, 35, 2, 35, 9,238, 68, 0,239, 2, 27, 27, 2, + 2, 3,240,241, 2,242, 39, 2, 3, 0, 0, 0, 0, 0, 27, 38, + 2,243, 0, 0, 2, 2,244,245, 2,246,181,181,247, 9, 0, 0, + 248,249, 0, 0, 29, 38, 2, 2, 27, 9, 27, 0,250,251, 2, 2, + 2, 2,252,160,253,254, 0, 0,255,256,256,256,256,257, 2, 2, + 258,259, 0,260,261, 2, 2, 2,262,263,264, 0,265, 0, 0, 0, + 266, 2, 2, 2, 2,208,253,267,268,269, 2, 2, 0,270, 0, 0, + 271, 0, 0, 0, 98,272,160,252,273, 0,274,275, 27, 2, 2, 2, + 2, 2, 2, 75,252,276, 0, 58, 2, 38, 29, 35, 2, 2, 2, 35, + 2, 2, 2, 11,262, 20,277, 0, 12, 27, 2, 28, 29, 27,278,279, + 21,280, 32, 33, 0, 34, 0, 10,106,281, 12,194, 12,194, 0, 0, + 2,282,160,253,283,284, 0, 0, 2, 2, 3,285,286, 0, 0, 0, + 262,160,287,288,289, 9, 0, 0, 2, 2, 2, 98,272, 83,128,290, + 291, 0, 0, 0, 0, 0, 2, 83, 75,160,263,292,245, 0, 0, 0, + 2, 2, 11,293,253,294, 9, 0, 2, 2, 38,295, 79,296, 20, 0, + 2, 38, 0, 0, 2, 2, 2,262,297,298,299, 0, 2, 38, 57, 2, + 2, 40, 2, 2,201,300,301,302,303, 0, 0, 0, 2, 2, 10, 2, + 282,160,304,305,306,307, 0, 0,308,252,309, 2,310,311,312,313, + 0,314, 0, 0,308,315, 19, 2, 2,316,317,318,318,319,320, 57, + 89,321,252,290,322, 94, 94, 94,323,324, 0, 0, 2, 38, 35, 2, + 113,325,326,327,328,329, 0, 0, 2, 35, 29, 2, 2, 2,106,330, + 50,331, 0, 0,332,333, 0, 0,334,335, 9, 0, 12,180, 0, 0, + 2, 2, 38,336,337,160,160,160,160,160,160,160,160,160, 0,338, + 339, 0, 0, 0, 0, 9, 0, 0, 2, 3, 0, 0, 2, 2, 3,340, + 188,192,191, 0, 12,266, 2, 3, 2, 2, 3, 10, 2, 2, 2,341, + 2, 2, 2, 12, 2,342,343, 0, +}; + +static inline uint_fast8_t +hb_use_get_category (unsigned u) +{ + return u<921600u?hb_use_u8[466+(((hb_use_u16[992+(((hb_use_u16[((hb_use_u8[226+(((hb_use_u8[u>>2>>2>>4>>4])<<4)+((u>>2>>2>>4)&15u))])<<4)+((u>>2>>2)&15u)])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:O; } #undef B diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc index 60394ed4d8..c40ec52f9c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc @@ -206,7 +206,7 @@ setup_masks_use (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - info[i].use_category() = hb_use_get_category (info[i]); + info[i].use_category() = hb_use_get_category (info[i].codepoint); } static void @@ -490,12 +490,12 @@ const hb_ot_shaper_t _hb_ot_shaper_use = data_destroy_use, preprocess_text_use, nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, nullptr, /* decompose */ compose_use, setup_masks_use, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper.hh b/thirdparty/harfbuzz/src/hb-ot-shaper.hh index b823bf003c..e160987f83 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper.hh @@ -117,8 +117,6 @@ struct hb_ot_shaper_t hb_font_t *font); - hb_ot_shape_normalization_mode_t normalization_preference; - /* decompose() * Called during shape()'s normalization. * May be NULL. @@ -147,12 +145,6 @@ struct hb_ot_shaper_t hb_buffer_t *buffer, hb_font_t *font); - /* gpos_tag() - * If not HB_TAG_NONE, then must match found GPOS script tag for - * GPOS to be applied. Otherwise, fallback positioning will be used. - */ - hb_tag_t gpos_tag; - /* reorder_marks() * Called during shape(). * Shapers can use to modify ordering of combining marks. @@ -163,6 +155,14 @@ struct hb_ot_shaper_t unsigned int start, unsigned int end); + /* gpos_tag() + * If not HB_TAG_NONE, then must match found GPOS script tag for + * GPOS to be applied. Otherwise, fallback positioning will be used. + */ + hb_tag_t gpos_tag; + + hb_ot_shape_normalization_mode_t normalization_preference; + hb_ot_shape_zero_width_marks_type_t zero_width_marks; bool fallback_position; diff --git a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh index 41d1734b39..d83bf14219 100644 --- a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh @@ -57,6 +57,31 @@ enum // Reserved = 0xFFFC /* Reserved for future use — set to zero. */ }; +struct StatAxisRecord +{ + int cmp (hb_tag_t key) const { return tag.cmp (key); } + + hb_ot_name_id_t get_name_id () const { return nameID; } + + hb_tag_t get_axis_tag () const { return tag; } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + Tag tag; /* A tag identifying the axis of design variation. */ + NameID nameID; /* The name ID for entries in the 'name' table that + * provide a display string for this axis. */ + HBUINT16 ordering; /* A value that applications can use to determine + * primary sorting of face names, or for ordering + * of descriptors when composing family or face names. */ + public: + DEFINE_SIZE_STATIC (8); +}; + struct AxisValueFormat1 { unsigned int get_axis_index () const { return axisIndex; } @@ -64,10 +89,41 @@ struct AxisValueFormat1 hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const + { + unsigned axis_idx = get_axis_index (); + return axis_records[axis_idx].get_axis_tag (); + } + + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + hb_tag_t axis_tag = get_axis_tag (axis_records); + float axis_value = get_value (); + + if (!user_axes_location->has (axis_tag) || + fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) + return true; + + return false; + } + + bool subset (hb_subset_context_t *c, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + const hb_hashmap_t<hb_tag_t, float>* user_axes_location = c->plan->user_axes_location; + + if (keep_axis_value (axis_records, user_axes_location)) + return_trace (c->serializer->embed (this)); + + return_trace (false); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -92,10 +148,41 @@ struct AxisValueFormat2 hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const + { + unsigned axis_idx = get_axis_index (); + return axis_records[axis_idx].get_axis_tag (); + } + + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + hb_tag_t axis_tag = get_axis_tag (axis_records); + float axis_value = get_value (); + + if (!user_axes_location->has (axis_tag) || + fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) + return true; + + return false; + } + + bool subset (hb_subset_context_t *c, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + const hb_hashmap_t<hb_tag_t, float>* user_axes_location = c->plan->user_axes_location; + + if (keep_axis_value (axis_records, user_axes_location)) + return_trace (c->serializer->embed (this)); + + return_trace (false); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -124,10 +211,41 @@ struct AxisValueFormat3 hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const + { + unsigned axis_idx = get_axis_index (); + return axis_records[axis_idx].get_axis_tag (); + } + + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + hb_tag_t axis_tag = get_axis_tag (axis_records); + float axis_value = get_value (); + + if (!user_axes_location->has (axis_tag) || + fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) + return true; + + return false; + } + + bool subset (hb_subset_context_t *c, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + const hb_hashmap_t<hb_tag_t, float>* user_axes_location = c->plan->user_axes_location; + + if (keep_axis_value (axis_records, user_axes_location)) + return_trace (c->serializer->embed (this)); + + return_trace (false); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -155,7 +273,7 @@ struct AxisValueRecord bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -172,12 +290,47 @@ struct AxisValueFormat4 const AxisValueRecord &get_axis_record (unsigned int axis_index) const { return axisValues.as_array (axisCount)[axis_index]; } + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + hb_array_t<const AxisValueRecord> axis_value_records = axisValues.as_array (axisCount); + + for (const auto& rec : axis_value_records) + { + unsigned axis_idx = rec.get_axis_index (); + float axis_value = rec.get_value (); + hb_tag_t axis_tag = axis_records[axis_idx].get_axis_tag (); + + if (user_axes_location->has (axis_tag) && + fabsf(axis_value - user_axes_location->get (axis_tag)) > 0.001f) + return false; + } + + return true; + } + + bool subset (hb_subset_context_t *c, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + const hb_hashmap_t<hb_tag_t, float> *user_axes_location = c->plan->user_axes_location; + if (!keep_axis_value (axis_records, user_axes_location)) + return_trace (false); + + unsigned total_size = min_size + axisCount * AxisValueRecord::static_size; + auto *out = c->serializer->allocate_size<AxisValueFormat4> (total_size); + if (unlikely (!out)) return_trace (false); + memcpy (out, this, total_size); + return_trace (true); + } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (likely (c->check_struct (this) && + axisValues.sanitize (c, axisCount))); } protected: @@ -234,6 +387,33 @@ struct AxisValue } } + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); + switch (u.format) { + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + switch (u.format) + { + case 1: return u.format1.keep_axis_value (axis_records, user_axes_location); + case 2: return u.format2.keep_axis_value (axis_records, user_axes_location); + case 3: return u.format3.keep_axis_value (axis_records, user_axes_location); + case 4: return u.format4.keep_axis_value (axis_records, user_axes_location); + default:return false; + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -263,27 +443,35 @@ struct AxisValue DEFINE_SIZE_UNION (2, format); }; -struct StatAxisRecord +struct AxisValueOffsetArray: UnsizedArrayOf<Offset16To<AxisValue>> { - int cmp (hb_tag_t key) const { return tag.cmp (key); } + bool subset (hb_subset_context_t *c, + unsigned axisValueCount, + unsigned& count, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (this); + if (unlikely (!out)) return_trace (false); - hb_ot_name_id_t get_name_id () const { return nameID; } + auto axisValueOffsets = as_array (axisValueCount); + count = 0; + for (const auto& offset : axisValueOffsets) + { + if (!offset) continue; + auto o_snap = c->serializer->snapshot (); + auto *o = c->serializer->embed (offset); + if (!o) return_trace (false); + if (!o->serialize_subset (c, offset, this, axis_records)) + { + c->serializer->revert (o_snap); + continue; + } + count++; + } - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (count); } - - protected: - Tag tag; /* A tag identifying the axis of design variation. */ - NameID nameID; /* The name ID for entries in the 'name' table that - * provide a display string for this axis. */ - HBUINT16 ordering; /* A value that applications can use to determine - * primary sorting of face names, or for ordering - * of descriptors when composing family or face names. */ - public: - DEFINE_SIZE_STATIC (8); }; struct STAT @@ -329,7 +517,8 @@ struct STAT return axis_value.get_value_name_id (); } - void collect_name_ids (hb_set_t *nameids_to_retain) const + void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location, + hb_set_t *nameids_to_retain /* OUT */) const { if (!has_data ()) return; @@ -338,13 +527,38 @@ struct STAT | hb_sink (nameids_to_retain) ; + auto designAxes = get_design_axes (); + + get_axis_value_offsets () | hb_map (hb_add (&(this + offsetToAxisValueOffsets))) + | hb_filter ([&] (const AxisValue& _) + { return _.keep_axis_value (designAxes, user_axes_location); }) | hb_map (&AxisValue::get_value_name_id) | hb_sink (nameids_to_retain) ; } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + STAT *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + auto designAxes = get_design_axes (); + for (unsigned i = 0; i < (unsigned)designAxisCount; i++) + if (unlikely (!c->serializer->embed (designAxes[i]))) + return_trace (false); + + if (designAxisCount) + c->serializer->check_assign (out->designAxesOffset, this->get_size (), + HB_SERIALIZE_ERROR_INT_OVERFLOW); + + unsigned count = 0; + out->offsetToAxisValueOffsets.serialize_subset (c, offsetToAxisValueOffsets, this, + axisValueCount, count, designAxes); + return_trace (c->serializer->check_assign (out->axisValueCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -381,7 +595,7 @@ struct STAT * set to zero; if designAxisCount is greater * than zero, must be greater than zero. */ HBUINT16 axisValueCount; /* The number of axis value tables. */ - NNOffset32To<UnsizedArrayOf<Offset16To<AxisValue>>> + NNOffset32To<AxisValueOffsetArray> offsetToAxisValueOffsets; /* Offset in bytes from the beginning of * the STAT table to the start of the design diff --git a/thirdparty/harfbuzz/src/hb-ot-tag.cc b/thirdparty/harfbuzz/src/hb-ot-tag.cc index ce5cdce98b..ceb3bf6df5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag.cc +++ b/thirdparty/harfbuzz/src/hb-ot-tag.cc @@ -214,6 +214,8 @@ lang_matches (const char *lang_str, const char *spec, unsigned spec_len) { + /* Same as hb_language_matches(); duplicated. */ + if (likely ((unsigned) (limit - lang_str) < spec_len)) return false; diff --git a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh index 65f26c1d22..5946aef635 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh @@ -28,6 +28,8 @@ #define HB_OT_VAR_AVAR_TABLE_HH #include "hb-open-type.hh" +#include "hb-ot-var-common.hh" + /* * avar -- Axis Variations @@ -40,6 +42,28 @@ namespace OT { +/* "Spec": https://github.com/be-fonts/boring-expansion-spec/issues/14 */ +struct avarV2Tail +{ + friend struct avar; + + bool sanitize (hb_sanitize_context_t *c, + const void *base) const + { + TRACE_SANITIZE (this); + return_trace (varIdxMap.sanitize (c, base) && + varStore.sanitize (c, base)); + } + + protected: + Offset32To<DeltaSetIndexMap> varIdxMap; /* Offset from the beginning of 'avar' table. */ + Offset32To<VariationStore> varStore; /* Offset from the beginning of 'avar' table. */ + + public: + DEFINE_SIZE_STATIC (8); +}; + + struct AxisValueMap { bool sanitize (hb_sanitize_context_t *c) const @@ -106,12 +130,24 @@ struct avar { static constexpr hb_tag_t tableTag = HB_OT_TAG_avar; + bool has_data () const { return version.to_int (); } + + const SegmentMaps* get_segment_maps () const + { return &firstAxisSegmentMaps; } + + unsigned get_axis_count () const + { return axisCount; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!(version.sanitize (c) && - version.major == 1 && - c->check_struct (this)))) + if (!(version.sanitize (c) && + (version.major == 1 +#ifndef HB_NO_VARIATIONS2 + || version.major == 2 +#endif + ) && + c->check_struct (this))) return_trace (false); const SegmentMaps *map = &firstAxisSegmentMaps; @@ -123,6 +159,15 @@ struct avar map = &StructAfter<SegmentMaps> (*map); } +#ifndef HB_NO_VARIATIONS2 + if (version.major < 2) + return_trace (true); + + const auto &v2 = * (const avarV2Tail *) map; + if (unlikely (!v2.sanitize (c, this))) + return_trace (false); +#endif + return_trace (true); } @@ -136,6 +181,37 @@ struct avar coords[i] = map->map (coords[i]); map = &StructAfter<SegmentMaps> (*map); } + +#ifndef HB_NO_VARIATIONS2 + if (version.major < 2) + return; + + for (; count < axisCount; count++) + map = &StructAfter<SegmentMaps> (*map); + + const auto &v2 = * (const avarV2Tail *) map; + + const auto &varidx_map = this+v2.varIdxMap; + const auto &var_store = this+v2.varStore; + auto *var_store_cache = var_store.create_cache (); + + hb_vector_t<int> out; + out.alloc (coords_length); + for (unsigned i = 0; i < coords_length; i++) + { + int v = coords[i]; + uint32_t varidx = varidx_map.map (i); + float delta = var_store.get_delta (varidx, coords, coords_length, var_store_cache); + v += roundf (delta); + v = hb_clamp (v, -(1<<14), +(1<<14)); + out.push (v); + } + + OT::VariationStore::destroy_cache (var_store_cache); + + for (unsigned i = 0; i < coords_length; i++) + coords[i] = out[i]; +#endif } void unmap_coords (int *coords, unsigned int coords_length) const diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh index 0eafb949d5..1d29e3e4f9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh @@ -31,12 +31,13 @@ namespace OT { -struct DeltaSetIndexMapFormat0 +template <typename MapCountT> +struct DeltaSetIndexMapFormat01 { friend struct DeltaSetIndexMap; private: - DeltaSetIndexMapFormat0* copy (hb_serialize_context_t *c) const + DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); @@ -128,56 +129,12 @@ struct DeltaSetIndexMapFormat0 HBUINT8 format; /* Format identifier--format = 0 */ HBUINT8 entryFormat; /* A packed field that describes the compressed * representation of delta-set indices. */ - HBUINT16 mapCount; /* The number of mapping entries. */ + MapCountT mapCount; /* The number of mapping entries. */ UnsizedArrayOf<HBUINT8> mapDataZ; /* The delta-set index mapping data. */ public: - DEFINE_SIZE_ARRAY (4, mapDataZ); -}; - -struct DeltaSetIndexMapFormat1 -{ - friend struct DeltaSetIndexMap; - - private: - DeltaSetIndexMapFormat1* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - auto *out = c->start_embed (this); - if (unlikely (!out)) return_trace (nullptr); - - unsigned total_size = min_size + mapCount * get_width (); - HBUINT8 *p = c->allocate_size<HBUINT8> (total_size); - if (unlikely (!p)) return_trace (nullptr); - - memcpy (p, this, HBUINT8::static_size * total_size); - return_trace (out); - } - - unsigned get_map_count () const { return mapCount; } - unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } - unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - c->check_range (mapDataZ.arrayZ, - mapCount, - get_width ())); - } - - protected: - HBUINT8 format; /* Format identifier--format = 1 */ - HBUINT8 entryFormat; /* A packed field that describes the compressed - * representation of delta-set indices. */ - HBUINT32 mapCount; /* The number of mapping entries. */ - UnsizedArrayOf<HBUINT8> - mapDataZ; /* The delta-set index mapping data. */ - - public: - DEFINE_SIZE_ARRAY (6, mapDataZ); + DEFINE_SIZE_ARRAY (2+MapCountT::static_size, mapDataZ); }; struct DeltaSetIndexMap @@ -186,8 +143,11 @@ struct DeltaSetIndexMap bool serialize (hb_serialize_context_t *c, const T &plan) { TRACE_SERIALIZE (this); + unsigned length = plan.get_output_map ().length; + u.format = length <= 0xFFFF ? 0 : 1; switch (u.format) { case 0: return_trace (u.format0.serialize (c, plan)); + case 1: return_trace (u.format1.serialize (c, plan)); default:return_trace (false); } } @@ -196,6 +156,7 @@ struct DeltaSetIndexMap { switch (u.format) { case 0: return (u.format0.map (v)); + case 1: return (u.format1.map (v)); default:return v; } } @@ -250,9 +211,9 @@ struct DeltaSetIndexMap protected: union { - HBUINT8 format; /* Format identifier */ - DeltaSetIndexMapFormat0 format0; - DeltaSetIndexMapFormat1 format1; + HBUINT8 format; /* Format identifier */ + DeltaSetIndexMapFormat01<HBUINT16> format0; + DeltaSetIndexMapFormat01<HBUINT32> format1; } u; public: DEFINE_SIZE_UNION (1, format); diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh index c5c476bc0e..b9b49f2287 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh @@ -96,6 +96,8 @@ struct AxisRecord info->reserved = 0; } + hb_tag_t get_axis_tag () const { return axisTag; } + int normalize_axis_value (float v) const { float min_value, default_value, max_value; @@ -133,7 +135,6 @@ struct AxisRecord return_trace (c->check_struct (this)); } - protected: void get_coordinates (float &min, float &default_, float &max) const { default_ = defaultValue / 65536.f; @@ -142,6 +143,11 @@ struct AxisRecord max = hb_max (default_, maxValue / 65536.f); } + float get_default () const + { + return defaultValue / 65536.f; + } + public: Tag axisTag; /* Tag identifying the design variation for the axis. */ protected: @@ -270,24 +276,49 @@ struct fvar return axisCount; } - void collect_name_ids (hb_set_t *nameids) const + void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location, + hb_set_t *nameids /* IN/OUT */) const { if (!has_data ()) return; + hb_map_t pinned_axes; - + get_axes () - | hb_map (&AxisRecord::get_name_id) - | hb_sink (nameids) - ; - - + hb_range ((unsigned) instanceCount) - | hb_map ([this] (const unsigned _) { return get_instance_subfamily_name_id (_); }) - | hb_sink (nameids) - ; + auto axis_records = get_axes (); + for (unsigned i = 0 ; i < (unsigned)axisCount; i++) + { + hb_tag_t axis_tag = axis_records[i].get_axis_tag (); + if (user_axes_location->has (axis_tag)) + { + pinned_axes.set (i, axis_tag); + continue; + } + + nameids->add (axis_records[i].get_name_id ()); + } - + hb_range ((unsigned) instanceCount) - | hb_map ([this] (const unsigned _) { return get_instance_postscript_name_id (_); }) - | hb_sink (nameids) - ; + for (unsigned i = 0 ; i < (unsigned)instanceCount; i++) + { + const InstanceRecord *instance = get_instance (i); + + if (hb_any (+ hb_zip (instance->get_coordinates (axisCount), hb_range ((unsigned)axisCount)) + | hb_filter (pinned_axes, hb_second) + | hb_map ([&] (const hb_pair_t<const HBFixed&, unsigned>& _) + { + hb_tag_t axis_tag = pinned_axes.get (_.second); + float location = user_axes_location->get (axis_tag); + if (fabs ((double)location - (double)_.first.to_float ()) > 0.001) return true; + return false; + }) + )) + continue; + + nameids->add (instance->subfamilyNameID); + + if (instanceSize >= axisCount * 4 + 6) + { + unsigned post_script_name_id = StructAfter<NameID> (instance->get_coordinates (axisCount)); + if (post_script_name_id != HB_OT_NAME_ID_INVALID) nameids->add (post_script_name_id); + } + } } public: diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh index 56efcdbee9..53355c5077 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh @@ -319,27 +319,26 @@ struct HVARVVAR hvar_plan.index_map_plans.as_array ())); } - float get_advance_var (hb_codepoint_t glyph, - hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + float get_advance_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + VariationStore::cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, - font->coords, - font->num_coords, + coords, coord_count, store_cache); } - float get_side_bearing_var (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count) const + bool get_lsb_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + float *lsb) const { - if (!has_side_bearing_deltas ()) return 0.f; + if (!lsbMap) return false; uint32_t varidx = (this+lsbMap).map (glyph); - return (this+varStore).get_delta (varidx, coords, coord_count); + *lsb = (this+varStore).get_delta (varidx, coords, coord_count); + return true; } - bool has_side_bearing_deltas () const { return lsbMap && rsbMap; } - public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ @@ -392,6 +391,16 @@ struct VVAR : HVARVVAR { bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<VVAR> (c); } + bool get_vorg_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + float *delta) const + { + if (!vorgMap) return false; + uint32_t varidx = (this+vorgMap).map (glyph); + *delta = (this+varStore).get_delta (varidx, coords, coord_count); + return true; + } + protected: Offset32To<DeltaSetIndexMap> vorgMap; /* Offset to vertical-origin var-idx mapping. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var.cc b/thirdparty/harfbuzz/src/hb-ot-var.cc index 0376e26b4a..f000f27263 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var.cc +++ b/thirdparty/harfbuzz/src/hb-ot-var.cc @@ -56,7 +56,7 @@ * * Tests whether a face includes any OpenType variation data in the `fvar` table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.4.2 **/ @@ -162,7 +162,7 @@ hb_ot_var_get_axis_infos (hb_face_t *face, * Fetches the variation-axis information corresponding to the specified axis tag * in the specified face. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.2.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index 683a441ec3..173fe4a2fb 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -172,7 +172,7 @@ hb_resolve_overflows (const T& packed, && will_overflow) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs."); - if (sorted_graph.assign_32bit_spaces ()) + if (sorted_graph.assign_spaces ()) sorted_graph.sort_shortest_distance (); } @@ -181,7 +181,7 @@ hb_resolve_overflows (const T& packed, // TODO(garretrieger): select a good limit for max rounds. while (!sorted_graph.in_error () && graph::will_overflow (sorted_graph, &overflows) - && round++ < max_rounds) { + && round < max_rounds) { DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Overflow resolution round %d ===", round); print_overflows (sorted_graph, overflows); @@ -189,6 +189,9 @@ hb_resolve_overflows (const T& packed, if (!_try_isolating_subgraphs (overflows, sorted_graph)) { + // Don't count space isolation towards round limit. Only increment + // round counter if space isolation made no changes. + round++; if (!_process_overflows (overflows, priority_bumped_parents, sorted_graph)) { DEBUG_MSG (SUBSET_REPACK, nullptr, "No resolution available :("); diff --git a/thirdparty/harfbuzz/src/hb-set.cc b/thirdparty/harfbuzz/src/hb-set.cc index 2d458294f8..5bf9d7c8cd 100644 --- a/thirdparty/harfbuzz/src/hb-set.cc +++ b/thirdparty/harfbuzz/src/hb-set.cc @@ -56,8 +56,6 @@ hb_set_create () if (!(set = hb_object_create<hb_set_t> ())) return hb_set_get_empty (); - set->init_shallow (); - return set; } @@ -107,8 +105,6 @@ hb_set_destroy (hb_set_t *set) { if (!hb_object_destroy (set)) return; - set->fini_shallow (); - hb_free (set); } @@ -122,7 +118,7 @@ hb_set_destroy (hb_set_t *set) * * Attaches a user-data key/data pair to the specified set. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -162,7 +158,7 @@ hb_set_get_user_data (hb_set_t *set, * * Tests whether memory allocation for a set was successful. * - * Return value: %true if allocation succeeded, %false otherwise + * Return value: `true` if allocation succeeded, `false` otherwise * * Since: 0.9.2 **/ @@ -212,7 +208,7 @@ hb_set_clear (hb_set_t *set) * * Tests whether a set is empty (contains no elements). * - * Return value: %true if @set is empty + * Return value: `true` if @set is empty * * Since: 0.9.7 **/ @@ -229,7 +225,7 @@ hb_set_is_empty (const hb_set_t *set) * * Tests whether @codepoint belongs to @set. * - * Return value: %true if @codepoint is in @set, %false otherwise + * Return value: `true` if @codepoint is in @set, `false` otherwise * * Since: 0.9.2 **/ @@ -348,7 +344,7 @@ hb_set_del_range (hb_set_t *set, * Tests whether @set and @other are equal (contain the same * elements). * - * Return value: %true if the two sets are equal, %false otherwise. + * Return value: `true` if the two sets are equal, `false` otherwise. * * Since: 0.9.7 **/ @@ -383,7 +379,7 @@ hb_set_hash (const hb_set_t *set) * * Tests whether @set is a subset of @larger_set. * - * Return value: %true if the @set is a subset of (or equal to) @larger_set, %false otherwise. + * Return value: `true` if the @set is a subset of (or equal to) @larger_set, `false` otherwise. * * Since: 1.8.1 **/ @@ -553,7 +549,7 @@ hb_set_get_max (const hb_set_t *set) * * Set @codepoint to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a next value, %false otherwise + * Return value: `true` if there was a next value, `false` otherwise * * Since: 0.9.2 **/ @@ -574,7 +570,7 @@ hb_set_next (const hb_set_t *set, * * Set @codepoint to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a previous value, %false otherwise + * Return value: `true` if there was a previous value, `false` otherwise * * Since: 1.8.0 **/ @@ -597,7 +593,7 @@ hb_set_previous (const hb_set_t *set, * * Set @last to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a next range, %false otherwise + * Return value: `true` if there was a next range, `false` otherwise * * Since: 0.9.7 **/ @@ -621,7 +617,7 @@ hb_set_next_range (const hb_set_t *set, * * Set @first to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a previous range, %false otherwise + * Return value: `true` if there was a previous range, `false` otherwise * * Since: 1.8.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh index 7eb5e19a2a..5d5576cb9e 100644 --- a/thirdparty/harfbuzz/src/hb-set.hh +++ b/thirdparty/harfbuzz/src/hb-set.hh @@ -59,17 +59,15 @@ struct hb_sparseset_t hb_copy (o, *this); } - void init_shallow () { s.init (); } void init () { hb_object_init (this); - init_shallow (); + s.init (); } - void fini_shallow () { s.fini (); } void fini () { hb_object_fini (this); - fini_shallow (); + s.fini (); } explicit operator bool () const { return !is_empty (); } diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.cc b/thirdparty/harfbuzz/src/hb-shape-plan.cc index 0af07825fc..8dbb661cd2 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.cc +++ b/thirdparty/harfbuzz/src/hb-shape-plan.cc @@ -117,7 +117,7 @@ hb_shape_plan_key_t::init (bool copy, } else { - const hb_shaper_entry_t *shapers = _hb_shapers_get (); + const HB_UNUSED hb_shaper_entry_t *shapers = _hb_shapers_get (); for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) if (false) ; @@ -318,10 +318,6 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) { if (!hb_object_destroy (shape_plan)) return; -#ifndef HB_NO_OT_SHAPE - shape_plan->ot.fini (); -#endif - shape_plan->key.fini (); hb_free (shape_plan); } @@ -335,7 +331,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) * * Attaches a user-data key/data pair to the given shaping plan. * - * Return value: %true if success, %false otherwise. + * Return value: `true` if success, `false` otherwise. * * Since: 0.9.7 **/ @@ -440,7 +436,7 @@ _hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan, * Executes the given shaping plan on the specified buffer, using * the given @font and @features. * - * Return value: %true if success, %false otherwise. + * Return value: `true` if success, `false` otherwise. * * Since: 0.9.7 **/ diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.hh b/thirdparty/harfbuzz/src/hb-shape-plan.hh index 8cb4ddb927..6fc73939b3 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.hh +++ b/thirdparty/harfbuzz/src/hb-shape-plan.hh @@ -55,7 +55,7 @@ struct hb_shape_plan_key_t unsigned int num_coords, const char * const *shaper_list); - HB_INTERNAL void fini () { hb_free ((void *) user_features); } + HB_INTERNAL void fini () { hb_free ((void *) user_features); user_features = nullptr; } HB_INTERNAL bool user_features_match (const hb_shape_plan_key_t *other); @@ -64,6 +64,7 @@ struct hb_shape_plan_key_t struct hb_shape_plan_t { + ~hb_shape_plan_t () { key.fini (); } hb_object_header_t header; hb_face_t *face_unsafe; /* We don't carry a reference to face. */ hb_shape_plan_key_t key; diff --git a/thirdparty/harfbuzz/src/hb-shape.cc b/thirdparty/harfbuzz/src/hb-shape.cc index 14ec92828f..547d0afc47 100644 --- a/thirdparty/harfbuzz/src/hb-shape.cc +++ b/thirdparty/harfbuzz/src/hb-shape.cc @@ -106,12 +106,12 @@ hb_shape_list_shapers () * @font: an #hb_font_t to use for shaping * @buffer: an #hb_buffer_t to shape * @features: (array length=num_features) (nullable): an array of user - * specified #hb_feature_t or %NULL + * specified #hb_feature_t or `NULL` * @num_features: the length of @features array - * @shaper_list: (array zero-terminated=1) (nullable): a %NULL-terminated - * array of shapers to use or %NULL + * @shaper_list: (array zero-terminated=1) (nullable): a `NULL`-terminated + * array of shapers to use or `NULL` * - * See hb_shape() for details. If @shaper_list is not %NULL, the specified + * See hb_shape() for details. If @shaper_list is not `NULL`, the specified * shapers will be used in the given order, otherwise the default shapers list * will be used. * @@ -173,11 +173,11 @@ hb_shape_full (hb_font_t *font, * @font: an #hb_font_t to use for shaping * @buffer: an #hb_buffer_t to shape * @features: (array length=num_features) (nullable): an array of user - * specified #hb_feature_t or %NULL + * specified #hb_feature_t or `NULL` * @num_features: the length of @features array * * Shapes @buffer using @font turning its Unicode characters content to - * positioned glyphs. If @features is not %NULL, it will be used to control the + * positioned glyphs. If @features is not `NULL`, it will be used to control the * features applied during shaping. If two @features have the same tag but * overlapping ranges the value of the feature with the higher index takes * precedence. diff --git a/thirdparty/harfbuzz/src/hb-shaper.cc b/thirdparty/harfbuzz/src/hb-shaper.cc index da4253ed64..a900ac6991 100644 --- a/thirdparty/harfbuzz/src/hb-shaper.cc +++ b/thirdparty/harfbuzz/src/hb-shaper.cc @@ -64,7 +64,7 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<hb_shaper_entry_t, if (!end) end = p + strlen (p); - for (unsigned int j = i; j < ARRAY_LENGTH (_hb_all_shapers); j++) + for (unsigned int j = i; j < ARRAY_LENGTH_CONST (_hb_all_shapers); j++) if (end - p == (int) strlen (shapers[j].name) && 0 == strncmp (shapers[j].name, p, end - p)) { diff --git a/thirdparty/harfbuzz/src/hb-static.cc b/thirdparty/harfbuzz/src/hb-static.cc index 5c5ecce880..af95615c16 100644 --- a/thirdparty/harfbuzz/src/hb-static.cc +++ b/thirdparty/harfbuzz/src/hb-static.cc @@ -46,11 +46,10 @@ uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, VarIdx) = {0xFF,0xFF,0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00}; -DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x00}; +DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x01}; DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF}; -/* Hand-coded because Lookup is a template. Sad. */ -const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF}; +DEFINE_NULL_NAMESPACE_BYTES (AAT, Lookup) = {0xFF,0xFF}; /* hb_map_t */ @@ -59,7 +58,7 @@ const hb_codepoint_t minus_1 = -1; /* hb_face_t */ -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K static inline unsigned load_num_glyphs_from_loca (const hb_face_t *face) { @@ -89,7 +88,7 @@ hb_face_t::load_num_glyphs () const { unsigned ret = 0; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K ret = hb_max (ret, load_num_glyphs_from_loca (this)); #endif diff --git a/thirdparty/harfbuzz/src/hb-subset-input.cc b/thirdparty/harfbuzz/src/hb-subset-input.cc index 028ddf9035..7d19496275 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.cc +++ b/thirdparty/harfbuzz/src/hb-subset-input.cc @@ -32,7 +32,7 @@ * * Creates a new subset input object. * - * Return value: (transfer full): New subset input, or %NULL if failed. Destroy + * Return value: (transfer full): New subset input, or `NULL` if failed. Destroy * with hb_subset_input_destroy(). * * Since: 1.8.0 @@ -48,7 +48,9 @@ hb_subset_input_create_or_fail (void) for (auto& set : input->sets_iter ()) set = hb_set_create (); - if (input->in_error ()) + input->axes_location = hb_hashmap_create<hb_tag_t, float> (); + + if (!input->axes_location || input->in_error ()) { hb_subset_input_destroy (input); return nullptr; @@ -96,7 +98,6 @@ hb_subset_input_create_or_fail (void) HB_TAG ('D', 'S', 'I', 'G'), HB_TAG ('M', 'V', 'A', 'R'), HB_TAG ('c', 'v', 'a', 'r'), - HB_TAG ('S', 'T', 'A', 'T'), }; input->sets.no_subset_tables->add_array (default_no_subset_tables, ARRAY_LENGTH (default_no_subset_tables)); @@ -203,6 +204,8 @@ hb_subset_input_create_or_fail (void) input->sets.layout_features->add_array (default_layout_features, ARRAY_LENGTH (default_layout_features)); + input->sets.layout_scripts->invert (); // Default to all scripts. + if (input->in_error ()) { hb_subset_input_destroy (input); @@ -244,6 +247,8 @@ hb_subset_input_destroy (hb_subset_input_t *input) for (hb_set_t* set : input->sets_iter ()) hb_set_destroy (set); + hb_hashmap_destroy (input->axes_location); + hb_free (input); } @@ -342,7 +347,7 @@ hb_subset_input_set_flags (hb_subset_input_t *input, * * Attaches a user-data key/data pair to the given subset input object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 2.9.0 **/ @@ -374,3 +379,56 @@ hb_subset_input_get_user_data (const hb_subset_input_t *input, { return hb_object_get_user_data (input, key); } + +#ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_VAR +/** + * hb_subset_input_pin_axis_to_default: (skip) + * @input: a #hb_subset_input_t object. + * @axis_tag: Tag of the axis to be pinned + * + * Pin an axis to its default location in the given subset input object. + * + * Return value: `true` if success, `false` otherwise + * + * Since: REPLACEME + **/ +hb_bool_t +hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag) +{ + hb_ot_var_axis_info_t axis_info; + if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) + return false; + + return input->axes_location->set (axis_tag, axis_info.default_value); +} + +/** + * hb_subset_input_pin_axis_location: (skip) + * @input: a #hb_subset_input_t object. + * @axis_tag: Tag of the axis to be pinned + * @axis_value: Location on the axis to be pinned at + * + * Pin an axis to a fixed location in the given subset input object. + * + * Return value: `true` if success, `false` otherwise + * + * Since: REPLACEME + **/ +hb_bool_t +hb_subset_input_pin_axis_location (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag, + float axis_value) +{ + hb_ot_var_axis_info_t axis_info; + if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) + return false; + + float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value); + return input->axes_location->set (axis_tag, val); +} +#endif +#endif diff --git a/thirdparty/harfbuzz/src/hb-subset-input.hh b/thirdparty/harfbuzz/src/hb-subset-input.hh index 07c0e22676..2335f0634f 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.hh +++ b/thirdparty/harfbuzz/src/hb-subset-input.hh @@ -50,6 +50,7 @@ struct hb_subset_input_t hb_set_t *name_ids; hb_set_t *name_languages; hb_set_t *layout_features; + hb_set_t *layout_scripts; }; union { @@ -58,6 +59,7 @@ struct hb_subset_input_t }; unsigned flags; + hb_hashmap_t<hb_tag_t, float> *axes_location; inline unsigned num_sets () const { @@ -76,7 +78,8 @@ struct hb_subset_input_t if (unlikely (set_ptrs[i]->in_error ())) return true; } - return false; + + return axes_location->in_error (); } }; diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 4e3bb1d477..7ff66333a8 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -37,10 +37,11 @@ #include "hb-ot-color-colr-table.hh" #include "hb-ot-color-colrv1-closure.hh" #include "hb-ot-var-fvar-table.hh" +#include "hb-ot-var-avar-table.hh" #include "hb-ot-stat-table.hh" #include "hb-ot-math-table.hh" -using OT::Layout::GSUB::GSUB; +using OT::Layout::GSUB; using OT::Layout::GPOS; typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map; @@ -91,100 +92,171 @@ _remap_indexes (const hb_set_t *indexes, typedef void (*layout_collect_func_t) (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *scripts, const hb_tag_t *languages, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */); +/* + * Removes all tags from 'tags' that are not in filter. Additionally eliminates any duplicates. + * Returns true if anything was removed (not including duplicates). + */ +static bool _filter_tag_list(hb_vector_t<hb_tag_t>* tags, /* IN/OUT */ + const hb_set_t* filter) +{ + hb_vector_t<hb_tag_t> out; + out.alloc (tags->get_size() + 1); // +1 is to allocate room for the null terminator. + + bool removed = false; + hb_set_t visited; + + for (hb_tag_t tag : *tags) + { + if (!tag) continue; + if (visited.has (tag)) continue; + + if (!filter->has (tag)) + { + removed = true; + continue; + } + + visited.add (tag); + out.push (tag); + } + + // The collect function needs a null element to signal end of the array. + out.push (HB_TAG_NONE); + + hb_swap (out, *tags); + return removed; +} + template <typename T> -static void _collect_layout_indices (hb_face_t *face, +static void _collect_layout_indices (hb_subset_plan_t *plan, const T& table, - const hb_set_t *layout_features_to_retain, layout_collect_func_t layout_collect_func, hb_set_t *indices /* OUT */) { + unsigned num_features = table.get_feature_count (); hb_vector_t<hb_tag_t> features; - if (!features.alloc (table.get_feature_count () + 1)) + if (!plan->check_success (features.resize (num_features))) return; + table.get_feature_tags (0, &num_features, features.arrayZ); + bool retain_all_features = !_filter_tag_list (&features, plan->layout_features); + + unsigned num_scripts = table.get_script_count (); + hb_vector_t<hb_tag_t> scripts; + if (!plan->check_success (scripts.resize (num_scripts))) return; + table.get_script_tags (0, &num_scripts, scripts.arrayZ); + bool retain_all_scripts = !_filter_tag_list (&scripts, plan->layout_scripts); + + if (!plan->check_success (!features.in_error ()) || !features + || !plan->check_success (!scripts.in_error ()) || !scripts) return; - hb_set_t visited_features; - bool retain_all_features = true; - for (unsigned i = 0; i < table.get_feature_count (); i++) + layout_collect_func (plan->source, + T::tableTag, + retain_all_scripts ? nullptr : scripts.arrayZ, + nullptr, + retain_all_features ? nullptr : features.arrayZ, + indices); +} + + +static inline void +_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g, + const hb_map_t *lookup_indices, + const hb_set_t *feature_indices, + hb_map_t *duplicate_feature_map /* OUT */) +{ + if (feature_indices->is_empty ()) return; + hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_set_t>> unique_features; + //find out duplicate features after subset + for (unsigned i : feature_indices->iter ()) { - hb_tag_t tag = table.get_feature_tag (i); - if (!tag) continue; - if (!layout_features_to_retain->has (tag)) + hb_tag_t t = g.get_feature_tag (i); + if (t == HB_MAP_VALUE_INVALID) continue; + if (!unique_features.has (t)) { - retain_all_features = false; + if (unlikely (!unique_features.set (t, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) + return; + if (unique_features.has (t)) + unique_features.get (t)->add (i); + duplicate_feature_map->set (i, i); continue; } - if (visited_features.has (tag)) - continue; + bool found = false; - features.push (tag); - visited_features.add (tag); - } + hb_set_t* same_tag_features = unique_features.get (t); + for (unsigned other_f_index : same_tag_features->iter ()) + { + const OT::Feature& f = g.get_feature (i); + const OT::Feature& other_f = g.get_feature (other_f_index); - if (!features) - return; + auto f_iter = + + hb_iter (f.lookupIndex) + | hb_filter (lookup_indices) + ; - // The collect function needs a null element to signal end of the array. - features.push (0); + auto other_f_iter = + + hb_iter (other_f.lookupIndex) + | hb_filter (lookup_indices) + ; - if (retain_all_features) - { - // Looking for all features, trigger the faster collection method. - layout_collect_func (face, - T::tableTag, - nullptr, - nullptr, - nullptr, - indices); - return; - } + bool is_equal = true; + for (; f_iter && other_f_iter; f_iter++, other_f_iter++) + { + unsigned a = *f_iter; + unsigned b = *other_f_iter; + if (a != b) { is_equal = false; break; } + } - layout_collect_func (face, - T::tableTag, - nullptr, - nullptr, - features.arrayZ, - indices); + if (is_equal == false || f_iter || other_f_iter) continue; + + found = true; + duplicate_feature_map->set (i, other_f_index); + break; + } + + if (found == false) + { + same_tag_features->add (i); + duplicate_feature_map->set (i, i); + } + } } template <typename T> static inline void -_closure_glyphs_lookups_features (hb_face_t *face, +_closure_glyphs_lookups_features (hb_subset_plan_t *plan, hb_set_t *gids_to_retain, - const hb_set_t *layout_features_to_retain, hb_map_t *lookups, hb_map_t *features, script_langsys_map *langsys_map) { - hb_blob_ptr_t<T> table = hb_sanitize_context_t ().reference_table<T> (face); + hb_blob_ptr_t<T> table = plan->source_table<T> (); hb_tag_t table_tag = table->tableTag; hb_set_t lookup_indices; - _collect_layout_indices<T> (face, + _collect_layout_indices<T> (plan, *table, - layout_features_to_retain, hb_ot_layout_collect_lookups, &lookup_indices); if (table_tag == HB_OT_TAG_GSUB) - hb_ot_layout_lookups_substitute_closure (face, - &lookup_indices, + hb_ot_layout_lookups_substitute_closure (plan->source, + &lookup_indices, gids_to_retain); - table->closure_lookups (face, + table->closure_lookups (plan->source, gids_to_retain, - &lookup_indices); + &lookup_indices); _remap_indexes (&lookup_indices, lookups); // Collect and prune features hb_set_t feature_indices; - _collect_layout_indices<T> (face, + _collect_layout_indices<T> (plan, *table, - layout_features_to_retain, hb_ot_layout_collect_features, &feature_indices); table->prune_features (lookups, &feature_indices); hb_map_t duplicate_feature_map; - table->find_duplicate_features (lookups, &feature_indices, &duplicate_feature_map); + _GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, &duplicate_feature_map); feature_indices.clear (); table->prune_langsys (&duplicate_feature_map, langsys_map, &feature_indices); @@ -197,14 +269,14 @@ _closure_glyphs_lookups_features (hb_face_t *face, #ifndef HB_NO_VAR static inline void - _collect_layout_variation_indices (hb_face_t *face, - const hb_set_t *glyphset, - const hb_map_t *gpos_lookups, - hb_set_t *layout_variation_indices, - hb_map_t *layout_variation_idx_map) +_collect_layout_variation_indices (hb_subset_plan_t* plan, + const hb_set_t *glyphset, + const hb_map_t *gpos_lookups, + hb_set_t *layout_variation_indices, + hb_map_t *layout_variation_idx_map) { - hb_blob_ptr_t<OT::GDEF> gdef = hb_sanitize_context_t ().reference_table<OT::GDEF> (face); - hb_blob_ptr_t<GPOS> gpos = hb_sanitize_context_t ().reference_table<GPOS> (face); + hb_blob_ptr_t<OT::GDEF> gdef = plan->source_table<OT::GDEF> (); + hb_blob_ptr_t<GPOS> gpos = plan->source_table<GPOS> (); if (!gdef->has_data ()) { @@ -215,7 +287,7 @@ static inline void OT::hb_collect_variation_indices_context_t c (layout_variation_indices, glyphset, gpos_lookups); gdef->collect_variation_indices (&c); - if (hb_ot_layout_has_positioning (face)) + if (hb_ot_layout_has_positioning (plan->source)) gpos->collect_variation_indices (&c); gdef->remap_layout_variation_indices (layout_variation_indices, layout_variation_idx_map); @@ -242,22 +314,16 @@ static void _colr_closure (hb_face_t *face, OT::COLR::accelerator_t colr (face); if (!colr.is_valid ()) return; - unsigned iteration_count = 0; hb_set_t palette_indices, layer_indices; - unsigned glyphs_num; - { - glyphs_num = glyphs_colred->get_population (); - // Collect all glyphs referenced by COLRv0 - hb_set_t glyphset_colrv0; - for (hb_codepoint_t gid : glyphs_colred->iter ()) - colr.closure_glyphs (gid, &glyphset_colrv0); + // Collect all glyphs referenced by COLRv0 + hb_set_t glyphset_colrv0; + for (hb_codepoint_t gid : *glyphs_colred) + colr.closure_glyphs (gid, &glyphset_colrv0); - glyphs_colred->union_ (glyphset_colrv0); + glyphs_colred->union_ (glyphset_colrv0); - //closure for COLRv1 - colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); - } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES && - glyphs_num != glyphs_colred->get_population ()); + //closure for COLRv1 + colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); _remap_indexes (&layer_indices, layers_map); @@ -265,10 +331,10 @@ static void _colr_closure (hb_face_t *face, } static inline void -_math_closure (hb_face_t *face, - hb_set_t *glyphset) +_math_closure (hb_subset_plan_t *plan, + hb_set_t *glyphset) { - hb_blob_ptr_t<OT::MATH> math = hb_sanitize_context_t ().reference_table<OT::MATH> (face); + hb_blob_ptr_t<OT::MATH> math = plan->source_table<OT::MATH> (); if (math->has_data ()) math->closure_glyphs (glyphset); math.destroy (); @@ -368,7 +434,7 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ()) operation_count = _glyf_add_gid_and_children (glyf, - item.glyphIndex, + item.get_gid (), gids_to_retain, operation_count, depth); @@ -395,18 +461,16 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, if (close_over_gsub) // closure all glyphs/lookups/features needed for GSUB substitutions. _closure_glyphs_lookups_features<GSUB> ( - plan->source, + plan, plan->_glyphset_gsub, - plan->layout_features, plan->gsub_lookups, plan->gsub_features, plan->gsub_langsys); if (close_over_gpos) _closure_glyphs_lookups_features<GPOS> ( - plan->source, + plan, plan->_glyphset_gsub, - plan->layout_features, plan->gpos_lookups, plan->gpos_features, plan->gpos_langsys); @@ -414,7 +478,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub); - _math_closure (plan->source, plan->_glyphset_mathed); + _math_closure (plan, plan->_glyphset_mathed); _remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ()); hb_set_t cur_glyphset = *plan->_glyphset_mathed; @@ -442,7 +506,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, #ifndef HB_NO_VAR if (close_over_gdef) - _collect_layout_variation_indices (plan->source, + _collect_layout_variation_indices (plan, plan->_glyphset_gsub, plan->gpos_lookups, plan->layout_variation_indices, @@ -506,16 +570,62 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, static void _nameid_closure (hb_face_t *face, - hb_set_t *nameids) + hb_set_t *nameids, + bool all_axes_pinned, + hb_hashmap_t<hb_tag_t, float> *user_axes_location) { #ifndef HB_NO_STYLE - face->table.STAT->collect_name_ids (nameids); + face->table.STAT->collect_name_ids (user_axes_location, nameids); #endif #ifndef HB_NO_VAR - face->table.fvar->collect_name_ids (nameids); + if (!all_axes_pinned) + face->table.fvar->collect_name_ids (user_axes_location, nameids); #endif } +#ifndef HB_NO_VAR +static void +_normalize_axes_location (hb_face_t *face, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location, + hb_hashmap_t<hb_tag_t, int> *normalized_axes_location, /* OUT */ + bool &all_axes_pinned) +{ + if (user_axes_location->is_empty ()) + return; + + hb_array_t<const OT::AxisRecord> axes = face->table.fvar->get_axes (); + + bool has_avar = face->table.avar->has_data (); + const OT::SegmentMaps *seg_maps = nullptr; + if (has_avar) + seg_maps = face->table.avar->get_segment_maps (); + + bool axis_not_pinned = false; + unsigned axis_count = 0; + for (const auto& axis : axes) + { + hb_tag_t axis_tag = axis.get_axis_tag (); + if (!user_axes_location->has (axis_tag)) + { + axis_not_pinned = true; + } + else + { + int normalized_v = axis.normalize_axis_value (user_axes_location->get (axis_tag)); + if (has_avar && axis_count < face->table.avar->get_axis_count ()) + { + normalized_v = seg_maps->map (normalized_v); + } + normalized_axes_location->set (axis_tag, normalized_v); + } + if (has_avar) + seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps); + + axis_count++; + } + all_axes_pinned = !axis_not_pinned; +} +#endif /** * hb_subset_plan_create_or_fail: * @face: font face to create the plan for. @@ -546,9 +656,9 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->unicode_to_new_gid_list.init (); plan->name_ids = hb_set_copy (input->sets.name_ids); - _nameid_closure (face, plan->name_ids); plan->name_languages = hb_set_copy (input->sets.name_languages); plan->layout_features = hb_set_copy (input->sets.layout_features); + plan->layout_scripts = hb_set_copy (input->sets.layout_scripts); plan->glyphs_requested = hb_set_copy (input->sets.glyphs); plan->drop_tables = hb_set_copy (input->sets.drop_tables); plan->no_subset_tables = hb_set_copy (input->sets.no_subset_tables); @@ -566,10 +676,8 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->gsub_lookups = hb_map_create (); plan->gpos_lookups = hb_map_create (); - if (plan->check_success (plan->gsub_langsys = hb_object_create<script_langsys_map> ())) - plan->gsub_langsys->init_shallow (); - if (plan->check_success (plan->gpos_langsys = hb_object_create<script_langsys_map> ())) - plan->gpos_langsys->init_shallow (); + plan->check_success (plan->gsub_langsys = hb_hashmap_create<unsigned, hb::unique_ptr<hb_set_t>> ()); + plan->check_success (plan->gpos_langsys = hb_hashmap_create<unsigned, hb::unique_ptr<hb_set_t>> ()); plan->gsub_features = hb_map_create (); plan->gpos_features = hb_map_create (); @@ -578,6 +686,13 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->layout_variation_indices = hb_set_create (); plan->layout_variation_idx_map = hb_map_create (); + plan->check_success (plan->sanitized_table_cache = hb_hashmap_create<hb_tag_t, hb::unique_ptr<hb_blob_t>> ()); + plan->check_success (plan->axes_location = hb_hashmap_create<hb_tag_t, int> ()); + plan->check_success (plan->user_axes_location = hb_hashmap_create<hb_tag_t, float> ()); + if (plan->user_axes_location && input->axes_location) + *plan->user_axes_location = *input->axes_location; + plan->all_axes_pinned = false; + if (unlikely (plan->in_error ())) { hb_subset_plan_destroy (plan); return nullptr; @@ -610,6 +725,14 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->glyph_map->get(plan->unicode_to_new_gid_list.arrayZ[i].second); } +#ifndef HB_NO_VAR + _normalize_axes_location (face, + input->axes_location, + plan->axes_location, + plan->all_axes_pinned); +#endif + + _nameid_closure (face, plan->name_ids, plan->all_axes_pinned, plan->user_axes_location); if (unlikely (plan->in_error ())) { hb_subset_plan_destroy (plan); return nullptr; @@ -632,10 +755,10 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) if (!hb_object_destroy (plan)) return; hb_set_destroy (plan->unicodes); - plan->unicode_to_new_gid_list.fini (); hb_set_destroy (plan->name_ids); hb_set_destroy (plan->name_languages); hb_set_destroy (plan->layout_features); + hb_set_destroy (plan->layout_scripts); hb_set_destroy (plan->glyphs_requested); hb_set_destroy (plan->drop_tables); hb_set_destroy (plan->no_subset_tables); @@ -658,18 +781,15 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_set_destroy (plan->layout_variation_indices); hb_map_destroy (plan->layout_variation_idx_map); - if (plan->gsub_langsys) - { - hb_object_destroy (plan->gsub_langsys); - plan->gsub_langsys->fini_shallow (); - hb_free (plan->gsub_langsys); - } + hb_hashmap_destroy (plan->gsub_langsys); + hb_hashmap_destroy (plan->gpos_langsys); + hb_hashmap_destroy (plan->axes_location); + hb_hashmap_destroy (plan->sanitized_table_cache); - if (plan->gpos_langsys) + if (plan->user_axes_location) { - hb_object_destroy (plan->gpos_langsys); - plan->gpos_langsys->fini_shallow (); - hb_free (plan->gpos_langsys); + hb_object_destroy (plan->user_axes_location); + hb_free (plan->user_axes_location); } hb_free (plan); @@ -755,7 +875,7 @@ hb_subset_plan_reference (hb_subset_plan_t *plan) * * Attaches a user-data key/data pair to the given subset plan object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 4.0.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index 2aaf19c61d..8912ae70d5 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -55,6 +55,9 @@ struct hb_subset_plan_t //layout features which will be preserved hb_set_t *layout_features; + // layout scripts which will be preserved. + hb_set_t *layout_scripts; + //glyph ids requested to retain hb_set_t *glyphs_requested; @@ -103,8 +106,34 @@ struct hb_subset_plan_t //Old -> New layout item variation store delta set index mapping hb_map_t *layout_variation_idx_map; + hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>>* sanitized_table_cache; + //normalized axes location map + hb_hashmap_t<hb_tag_t, int> *axes_location; + //user specified axes location map + hb_hashmap_t<hb_tag_t, float> *user_axes_location; + bool all_axes_pinned; + public: + template<typename T> + hb_blob_ptr_t<T> source_table() + { + if (sanitized_table_cache + && !sanitized_table_cache->in_error () + && sanitized_table_cache->has (T::tableTag)) { + return hb_blob_reference (sanitized_table_cache->get (T::tableTag).get ()); + } + + hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (source)}; + hb_blob_t* ret = hb_blob_reference (table_blob.get ()); + + if (likely (sanitized_table_cache)) + sanitized_table_cache->set (T::tableTag, + std::move (table_blob)); + + return ret; + } + bool in_error () const { return !successful; } bool check_success(bool success) diff --git a/thirdparty/harfbuzz/src/hb-subset-repacker.cc b/thirdparty/harfbuzz/src/hb-subset-repacker.cc index 2447d296b8..03e3feb1f6 100644 --- a/thirdparty/harfbuzz/src/hb-subset-repacker.cc +++ b/thirdparty/harfbuzz/src/hb-subset-repacker.cc @@ -43,7 +43,7 @@ hb_blob_t* hb_subset_repack_or_fail (hb_object_t* hb_objects, unsigned num_hb_ob packed.push (nullptr); for (unsigned i = 0 ; i < num_hb_objs ; i++) packed.push (&(hb_objects[i])); + return hb_resolve_overflows (packed, HB_OT_TAG_GSUB); } #endif - diff --git a/thirdparty/harfbuzz/src/hb-subset-repacker.h b/thirdparty/harfbuzz/src/hb-subset-repacker.h index f9a2383698..e28f879362 100644 --- a/thirdparty/harfbuzz/src/hb-subset-repacker.h +++ b/thirdparty/harfbuzz/src/hb-subset-repacker.h @@ -31,13 +31,13 @@ HB_BEGIN_DECLS #ifdef HB_EXPERIMENTAL_API -/** +/* * struct hb_link_t * width: offsetSize in bytes * position: position of the offset field in bytes * from beginning of subtable * objidx: index of subtable - **/ + */ struct hb_link_t { unsigned width; @@ -47,7 +47,7 @@ struct hb_link_t typedef struct hb_link_t hb_link_t; -/** +/* * struct hb_object_t * head: start of object data * tail: end of object data @@ -56,7 +56,7 @@ typedef struct hb_link_t hb_link_t; * num_virtual_links: num of objects that must be packed * after current object in the final serialized order * virtual_links: array of virtual link info - **/ + */ struct hb_object_t { char *head; diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 10c572c2f7..f62e7e895b 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -53,9 +53,10 @@ #include "hb-ot-var-gvar-table.hh" #include "hb-ot-var-hvar-table.hh" #include "hb-ot-math-table.hh" +#include "hb-ot-stat-table.hh" #include "hb-repacker.hh" -using OT::Layout::GSUB::GSUB; +using OT::Layout::GSUB; using OT::Layout::GPOS; /** @@ -242,10 +243,15 @@ _try_subset (const TableType *table, unsigned buf_size = buf->allocated; buf_size = buf_size * 2 + 16; + + + + DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (c->table_tag), buf_size); - if (unlikely (!buf->alloc (buf_size))) + if (unlikely (buf_size > c->source_blob->length * 16 || + !buf->alloc (buf_size))) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (c->table_tag), buf_size); @@ -260,15 +266,15 @@ template<typename TableType> static bool _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf) { - hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source); - const TableType *table = source_blob->as<TableType> (); + hb_blob_ptr_t<TableType> source_blob = plan->source_table<TableType> (); + const TableType *table = source_blob.get (); hb_tag_t tag = TableType::tableTag; - if (!source_blob->data) + if (!source_blob.get_blob()->data) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - hb_blob_destroy (source_blob); + source_blob.destroy (); return false; } @@ -278,23 +284,23 @@ _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf) TableType::tableTag == HB_OT_TAG_GPOS || TableType::tableTag == HB_OT_TAG_name; - unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob->length, same_size_table); + unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob.get_length (), same_size_table); DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); if (unlikely (!buf.alloc (buf_size))) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); - hb_blob_destroy (source_blob); + source_blob.destroy (); return false; } bool needed = false; hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); { - hb_subset_context_t c (source_blob, plan, &serializer, tag); + hb_subset_context_t c (source_blob.get_blob (), plan, &serializer, tag); needed = _try_subset (table, &buf, &c); } - hb_blob_destroy (source_blob); + source_blob.destroy (); if (serializer.in_error () && !serializer.only_offset_overflow ()) { @@ -356,6 +362,8 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) switch (tag) { case HB_TAG ('c','v','a','r'): /* hint table, fallthrough */ + return plan->all_axes_pinned || (plan->flags & HB_SUBSET_FLAGS_NO_HINTING); + case HB_TAG ('c','v','t',' '): /* hint table, fallthrough */ case HB_TAG ('f','p','g','m'): /* hint table, fallthrough */ case HB_TAG ('p','r','e','p'): /* hint table, fallthrough */ @@ -375,6 +383,14 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) return true; #endif + case HB_TAG ('a','v','a','r'): + case HB_TAG ('f','v','a','r'): + case HB_TAG ('g','v','a','r'): + case HB_OT_TAG_HVAR: + case HB_OT_TAG_VVAR: + case HB_TAG ('M','V','A','R'): + return plan->all_axes_pinned; + default: return false; } @@ -438,6 +454,11 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf); case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf); #endif + case HB_OT_TAG_STAT: + /*TODO(qxliu): change the condition as we support more complex + * instancing operation*/ + if (plan->all_axes_pinned) return _subset<const OT::STAT> (plan, buf); + else return _passthrough (plan, tag); default: if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) diff --git a/thirdparty/harfbuzz/src/hb-subset.h b/thirdparty/harfbuzz/src/hb-subset.h index a2799d91e8..08e52dbd2d 100644 --- a/thirdparty/harfbuzz/src/hb-subset.h +++ b/thirdparty/harfbuzz/src/hb-subset.h @@ -100,6 +100,8 @@ typedef enum { /*< flags >*/ * @HB_SUBSET_SETS_NAME_LANG_ID: the set of name lang ids that will be retained. * @HB_SUBSET_SETS_LAYOUT_FEATURE_TAG: the set of layout feature tags that will be retained * in the subset. + * @HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG: the set of layout script tags that will be retained + * in the subset. Defaults to all tags. Since: 5.0.0 * * List of sets that can be configured on the subset input. * @@ -113,6 +115,7 @@ typedef enum { HB_SUBSET_SETS_NAME_ID, HB_SUBSET_SETS_NAME_LANG_ID, HB_SUBSET_SETS_LAYOUT_FEATURE_TAG, + HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG, } hb_subset_sets_t; HB_EXTERN hb_subset_input_t * @@ -151,6 +154,21 @@ HB_EXTERN void hb_subset_input_set_flags (hb_subset_input_t *input, unsigned value); +#ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_VAR +HB_EXTERN hb_bool_t +hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag); + +HB_EXTERN hb_bool_t +hb_subset_input_pin_axis_location (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag, + float axis_value); +#endif +#endif + HB_EXTERN hb_face_t * hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input); diff --git a/thirdparty/harfbuzz/src/hb-unicode.cc b/thirdparty/harfbuzz/src/hb-unicode.cc index 05f74b9237..9899e01a41 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.cc +++ b/thirdparty/harfbuzz/src/hb-unicode.cc @@ -281,7 +281,7 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) * * Attaches a user-data key/data pair to the specified Unicode-functions structure. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -340,7 +340,7 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) * Tests whether the specified Unicode-functions structure * is immutable. * - * Return value: %true if @ufuncs is immutable, %false otherwise + * Return value: `true` if @ufuncs is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -421,7 +421,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE * Calls the composition function of the specified * Unicode-functions structure @ufuncs. * - * Return value: %true if @a and @b composed, %false otherwise + * Return value: `true` if @a and @b composed, `false` otherwise * * Since: 0.9.2 **/ @@ -446,7 +446,7 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs, * Calls the decomposition function of the specified * Unicode-functions structure @ufuncs. * - * Return value: %true if @ab was decomposed, %false otherwise + * Return value: `true` if @ab was decomposed, `false` otherwise * * Since: 0.9.2 **/ diff --git a/thirdparty/harfbuzz/src/hb-unicode.h b/thirdparty/harfbuzz/src/hb-unicode.h index c04ee15a09..a500384575 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.h +++ b/thirdparty/harfbuzz/src/hb-unicode.h @@ -429,7 +429,7 @@ typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs, * The method must return an #hb_bool_t indicating the success * of the composition. * - * Return value: %true is @a,@b composed, %false otherwise + * Return value: `true` is @a,@b composed, `false` otherwise * **/ typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, @@ -453,7 +453,7 @@ typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, * output parameters (if successful). The method must return an * #hb_bool_t indicating the success of the composition. * - * Return value: %true if @ab decomposed, %false otherwise + * Return value: `true` if @ab decomposed, `false` otherwise * **/ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index 7b08e3b4d2..a6d9f6b3fb 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -43,7 +43,6 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty using c_array_t = typename std::conditional<sorted, hb_sorted_array_t<const Type>, hb_array_t<const Type>>::type; hb_vector_t () = default; - hb_vector_t (std::nullptr_t) : hb_vector_t () {} hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t () { alloc (lst.size ()); diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index f036a12226..40ea3eb017 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -41,13 +41,13 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 4 +#define HB_VERSION_MAJOR 5 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 4 +#define HB_VERSION_MINOR 0 /** * HB_VERSION_MICRO: * @@ -60,7 +60,7 @@ HB_BEGIN_DECLS * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "4.4.1" +#define HB_VERSION_STRING "5.0.1" /** * HB_VERSION_ATLEAST: |