viewport.cpp 177 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382
  1. /**************************************************************************/
  2. /* viewport.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #include "viewport.h"
  31. #include "core/config/project_settings.h"
  32. #include "core/debugger/engine_debugger.h"
  33. #include "core/templates/pair.h"
  34. #include "core/templates/sort_array.h"
  35. #include "scene/2d/audio_listener_2d.h"
  36. #include "scene/2d/camera_2d.h"
  37. #include "scene/2d/physics/collision_object_2d.h"
  38. #ifndef _3D_DISABLED
  39. #include "scene/3d/audio_listener_3d.h"
  40. #include "scene/3d/camera_3d.h"
  41. #include "scene/3d/physics/collision_object_3d.h"
  42. #include "scene/3d/world_environment.h"
  43. #endif // _3D_DISABLED
  44. #include "scene/gui/control.h"
  45. #include "scene/gui/label.h"
  46. #include "scene/gui/popup.h"
  47. #include "scene/gui/popup_menu.h"
  48. #include "scene/gui/subviewport_container.h"
  49. #include "scene/main/canvas_layer.h"
  50. #include "scene/main/window.h"
  51. #include "scene/resources/mesh.h"
  52. #include "scene/resources/text_line.h"
  53. #include "scene/resources/world_2d.h"
  54. #include "servers/audio_server.h"
  55. #include "servers/rendering/rendering_server_globals.h"
  56. void ViewportTexture::setup_local_to_scene() {
  57. // For the same target viewport, setup is only allowed once to prevent multiple free or multiple creations.
  58. if (!vp_changed) {
  59. return;
  60. }
  61. if (vp_pending) {
  62. return;
  63. }
  64. Node *loc_scene = get_local_scene();
  65. if (!loc_scene) {
  66. return;
  67. }
  68. if (vp) {
  69. vp->viewport_textures.erase(this);
  70. vp = nullptr;
  71. }
  72. if (loc_scene->is_ready()) {
  73. _setup_local_to_scene(loc_scene);
  74. } else {
  75. loc_scene->connect(SceneStringName(ready), callable_mp(this, &ViewportTexture::_setup_local_to_scene).bind(loc_scene), CONNECT_ONE_SHOT);
  76. vp_pending = true;
  77. }
  78. }
  79. void ViewportTexture::reset_local_to_scene() {
  80. vp_changed = true;
  81. if (vp) {
  82. vp->viewport_textures.erase(this);
  83. vp = nullptr;
  84. }
  85. if (proxy.is_valid() && proxy_ph.is_null()) {
  86. proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
  87. RS::get_singleton()->texture_proxy_update(proxy, proxy_ph);
  88. }
  89. }
  90. void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) {
  91. if (path == p_path) {
  92. return;
  93. }
  94. path = p_path;
  95. reset_local_to_scene();
  96. if (get_local_scene() && !path.is_empty()) {
  97. setup_local_to_scene();
  98. } else {
  99. if (path.is_empty()) {
  100. vp_changed = false;
  101. }
  102. emit_changed();
  103. }
  104. }
  105. NodePath ViewportTexture::get_viewport_path_in_scene() const {
  106. return path;
  107. }
  108. int ViewportTexture::get_width() const {
  109. if (!vp) {
  110. _err_print_viewport_not_set();
  111. return 0;
  112. }
  113. if (vp->is_sub_viewport()) {
  114. return vp->size.width;
  115. }
  116. return vp->size.width * vp->get_stretch_transform().get_scale().width;
  117. }
  118. int ViewportTexture::get_height() const {
  119. if (!vp) {
  120. _err_print_viewport_not_set();
  121. return 0;
  122. }
  123. if (vp->is_sub_viewport()) {
  124. return vp->size.height;
  125. }
  126. return vp->size.height * vp->get_stretch_transform().get_scale().height;
  127. }
  128. Size2 ViewportTexture::get_size() const {
  129. if (!vp) {
  130. _err_print_viewport_not_set();
  131. return Size2();
  132. }
  133. if (vp->is_sub_viewport()) {
  134. return vp->size;
  135. }
  136. Size2 scale = vp->get_stretch_transform().get_scale();
  137. return Size2(vp->size.width * scale.width, vp->size.height * scale.height).ceil();
  138. }
  139. RID ViewportTexture::get_rid() const {
  140. if (proxy.is_null()) {
  141. proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
  142. proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
  143. }
  144. return proxy;
  145. }
  146. bool ViewportTexture::has_alpha() const {
  147. return false;
  148. }
  149. Ref<Image> ViewportTexture::get_image() const {
  150. if (!vp) {
  151. _err_print_viewport_not_set();
  152. return Ref<Image>();
  153. }
  154. return RS::get_singleton()->texture_2d_get(vp->texture_rid);
  155. }
  156. void ViewportTexture::_err_print_viewport_not_set() const {
  157. if (!vp_pending && !vp_changed) {
  158. ERR_PRINT("Viewport Texture must be set to use it.");
  159. }
  160. }
  161. void ViewportTexture::_setup_local_to_scene(const Node *p_loc_scene) {
  162. // Always reset this, even if this call fails with an error.
  163. vp_pending = false;
  164. Node *vpn = p_loc_scene->get_node_or_null(path);
  165. ERR_FAIL_NULL_MSG(vpn, "Path to node is invalid: '" + path + "'.");
  166. vp = Object::cast_to<Viewport>(vpn);
  167. ERR_FAIL_NULL_MSG(vp, "Path to node does not point to a viewport: '" + path + "'.");
  168. vp->viewport_textures.insert(this);
  169. ERR_FAIL_NULL(RenderingServer::get_singleton());
  170. if (proxy_ph.is_valid()) {
  171. RS::get_singleton()->texture_proxy_update(proxy, vp->texture_rid);
  172. RS::get_singleton()->free(proxy_ph);
  173. proxy_ph = RID();
  174. } else {
  175. ERR_FAIL_COND(proxy.is_valid()); // Should be invalid.
  176. proxy = RS::get_singleton()->texture_proxy_create(vp->texture_rid);
  177. }
  178. vp_changed = false;
  179. emit_changed();
  180. }
  181. void ViewportTexture::_bind_methods() {
  182. ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene);
  183. ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene);
  184. ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Viewport", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT), "set_viewport_path_in_scene", "get_viewport_path_in_scene");
  185. }
  186. ViewportTexture::ViewportTexture() {
  187. set_local_to_scene(true);
  188. }
  189. ViewportTexture::~ViewportTexture() {
  190. if (vp) {
  191. vp->viewport_textures.erase(this);
  192. }
  193. ERR_FAIL_NULL(RenderingServer::get_singleton());
  194. if (proxy_ph.is_valid()) {
  195. RS::get_singleton()->free(proxy_ph);
  196. }
  197. if (proxy.is_valid()) {
  198. RS::get_singleton()->free(proxy);
  199. }
  200. }
  201. void Viewport::_process_dirty_canvas_parent_orders() {
  202. for (const ObjectID &id : gui.canvas_parents_with_dirty_order) {
  203. Object *obj = ObjectDB::get_instance(id);
  204. if (!obj) {
  205. continue; // May have been deleted.
  206. }
  207. Node *n = static_cast<Node *>(obj);
  208. for (int i = 0; i < n->get_child_count(); i++) {
  209. Node *c = n->get_child(i);
  210. CanvasItem *ci = Object::cast_to<CanvasItem>(c);
  211. if (ci) {
  212. ci->update_draw_order();
  213. continue;
  214. }
  215. CanvasLayer *cl = Object::cast_to<CanvasLayer>(c);
  216. if (cl) {
  217. cl->update_draw_order();
  218. }
  219. }
  220. }
  221. gui.canvas_parents_with_dirty_order.clear();
  222. }
  223. void Viewport::_sub_window_update_order() {
  224. if (gui.sub_windows.size() < 2) {
  225. return;
  226. }
  227. if (!gui.sub_windows[gui.sub_windows.size() - 1].window->get_flag(Window::FLAG_ALWAYS_ON_TOP)) {
  228. int index = gui.sub_windows.size() - 1;
  229. while (index > 0 && gui.sub_windows[index - 1].window->get_flag(Window::FLAG_ALWAYS_ON_TOP)) {
  230. --index;
  231. }
  232. if (index != (gui.sub_windows.size() - 1)) {
  233. SubWindow sw = gui.sub_windows[gui.sub_windows.size() - 1];
  234. gui.sub_windows.remove_at(gui.sub_windows.size() - 1);
  235. gui.sub_windows.insert(index, sw);
  236. }
  237. }
  238. for (int i = 0; i < gui.sub_windows.size(); i++) {
  239. RS::get_singleton()->canvas_item_set_draw_index(gui.sub_windows[i].canvas_item, i);
  240. }
  241. }
  242. void Viewport::_sub_window_register(Window *p_window) {
  243. ERR_FAIL_COND(!is_inside_tree());
  244. for (int i = 0; i < gui.sub_windows.size(); i++) {
  245. ERR_FAIL_COND(gui.sub_windows[i].window == p_window);
  246. }
  247. if (gui.sub_windows.size() == 0) {
  248. subwindow_canvas = RS::get_singleton()->canvas_create();
  249. RS::get_singleton()->viewport_attach_canvas(viewport, subwindow_canvas);
  250. RS::get_singleton()->viewport_set_canvas_stacking(viewport, subwindow_canvas, SUBWINDOW_CANVAS_LAYER, 0);
  251. }
  252. SubWindow sw;
  253. sw.canvas_item = RS::get_singleton()->canvas_item_create();
  254. RS::get_singleton()->canvas_item_set_parent(sw.canvas_item, subwindow_canvas);
  255. sw.window = p_window;
  256. gui.sub_windows.push_back(sw);
  257. if (gui.subwindow_drag == SUB_WINDOW_DRAG_DISABLED) {
  258. if (p_window->get_flag(Window::FLAG_NO_FOCUS)) {
  259. _sub_window_update_order();
  260. } else {
  261. _sub_window_grab_focus(p_window);
  262. }
  263. } else {
  264. int index = _sub_window_find(gui.currently_dragged_subwindow);
  265. sw = gui.sub_windows[index];
  266. gui.sub_windows.remove_at(index);
  267. gui.sub_windows.push_back(sw);
  268. _sub_window_update_order();
  269. }
  270. RenderingServer::get_singleton()->viewport_set_parent_viewport(p_window->viewport, viewport);
  271. }
  272. void Viewport::_sub_window_update(Window *p_window) {
  273. int index = _sub_window_find(p_window);
  274. ERR_FAIL_COND(index == -1);
  275. SubWindow &sw = gui.sub_windows.write[index];
  276. sw.pending_window_update = false;
  277. RS::get_singleton()->canvas_item_clear(sw.canvas_item);
  278. Rect2i r = Rect2i(p_window->get_position(), p_window->get_size());
  279. if (!p_window->get_flag(Window::FLAG_BORDERLESS)) {
  280. Ref<StyleBox> panel = gui.subwindow_focused == p_window ? p_window->theme_cache.embedded_border : p_window->theme_cache.embedded_unfocused_border;
  281. panel->draw(sw.canvas_item, r);
  282. // Draw the title bar text.
  283. Ref<Font> title_font = p_window->theme_cache.title_font;
  284. int font_size = p_window->theme_cache.title_font_size;
  285. Color title_color = p_window->theme_cache.title_color;
  286. int title_height = p_window->theme_cache.title_height;
  287. int close_h_ofs = p_window->theme_cache.close_h_offset;
  288. int close_v_ofs = p_window->theme_cache.close_v_offset;
  289. TextLine title_text = TextLine(p_window->get_translated_title(), title_font, font_size);
  290. title_text.set_width(r.size.width - panel->get_minimum_size().x - close_h_ofs);
  291. title_text.set_direction(p_window->is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
  292. int x = (r.size.width - title_text.get_size().x) / 2;
  293. int y = (-title_height - title_text.get_size().y) / 2;
  294. Color font_outline_color = p_window->theme_cache.title_outline_modulate;
  295. int outline_size = p_window->theme_cache.title_outline_size;
  296. if (outline_size > 0 && font_outline_color.a > 0) {
  297. title_text.draw_outline(sw.canvas_item, r.position + Point2(x, y), outline_size, font_outline_color);
  298. }
  299. title_text.draw(sw.canvas_item, r.position + Point2(x, y), title_color);
  300. bool pressed = gui.subwindow_focused == sw.window && gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE && gui.subwindow_drag_close_inside;
  301. Ref<Texture2D> close_icon = pressed ? p_window->theme_cache.close_pressed : p_window->theme_cache.close;
  302. close_icon->draw(sw.canvas_item, r.position + Vector2(r.size.width - close_h_ofs, -close_v_ofs));
  303. }
  304. const Transform2D xform = sw.window->window_transform * sw.window->stretch_transform;
  305. Rect2 vr = xform.xform(sw.window->get_visible_rect());
  306. vr.position += p_window->get_position();
  307. if (vr != r) {
  308. RS::get_singleton()->canvas_item_add_rect(sw.canvas_item, r, Color());
  309. }
  310. RS::get_singleton()->canvas_item_add_texture_rect(sw.canvas_item, vr, sw.window->get_texture()->get_rid());
  311. }
  312. void Viewport::_sub_window_grab_focus(Window *p_window) {
  313. if (p_window == nullptr) {
  314. // Release current focus.
  315. if (gui.subwindow_focused) {
  316. gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
  317. gui.subwindow_focused = nullptr;
  318. gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
  319. }
  320. Window *this_window = Object::cast_to<Window>(this);
  321. if (this_window) {
  322. this_window->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_IN);
  323. }
  324. return;
  325. }
  326. // The index needs to be update before every usage in case an event callback changed the window list.
  327. int index = _sub_window_find(p_window);
  328. ERR_FAIL_COND(index == -1);
  329. if (p_window->get_flag(Window::FLAG_NO_FOCUS)) {
  330. // Release current focus.
  331. if (gui.subwindow_focused) {
  332. gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
  333. gui.subwindow_focused = nullptr;
  334. gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
  335. }
  336. // Can only move to foreground, but no focus granted.
  337. index = _sub_window_find(p_window);
  338. ERR_FAIL_COND(index == -1);
  339. SubWindow sw = gui.sub_windows[index];
  340. gui.sub_windows.remove_at(index);
  341. gui.sub_windows.push_back(sw);
  342. _sub_window_update_order();
  343. return;
  344. }
  345. if (gui.subwindow_focused) {
  346. if (gui.subwindow_focused == p_window) {
  347. return; // Nothing to do.
  348. }
  349. gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
  350. gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
  351. } else {
  352. Window *this_window = Object::cast_to<Window>(this);
  353. if (this_window) {
  354. this_window->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
  355. }
  356. }
  357. Window *old_focus = gui.subwindow_focused;
  358. gui.subwindow_focused = p_window;
  359. gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_IN);
  360. { // Move to foreground.
  361. index = _sub_window_find(p_window);
  362. ERR_FAIL_COND(index == -1);
  363. SubWindow sw = gui.sub_windows[index];
  364. gui.sub_windows.remove_at(index);
  365. gui.sub_windows.push_back(sw);
  366. index = gui.sub_windows.size() - 1;
  367. _sub_window_update_order();
  368. }
  369. if (old_focus) {
  370. _sub_window_update(old_focus);
  371. }
  372. _sub_window_update(p_window);
  373. }
  374. void Viewport::_sub_window_remove(Window *p_window) {
  375. int index = _sub_window_find(p_window);
  376. ERR_FAIL_COND(index == -1);
  377. ERR_FAIL_NULL(RenderingServer::get_singleton());
  378. SubWindow sw = gui.sub_windows[index];
  379. if (gui.subwindow_over == sw.window) {
  380. sw.window->_mouse_leave_viewport();
  381. gui.subwindow_over = nullptr;
  382. }
  383. RS::get_singleton()->free(sw.canvas_item);
  384. gui.sub_windows.remove_at(index);
  385. if (gui.sub_windows.size() == 0) {
  386. RS::get_singleton()->free(subwindow_canvas);
  387. subwindow_canvas = RID();
  388. }
  389. if (gui.currently_dragged_subwindow == p_window) {
  390. gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
  391. gui.currently_dragged_subwindow = nullptr;
  392. }
  393. if (gui.subwindow_focused == p_window) {
  394. Window *new_focused_window;
  395. Window *parent_visible = p_window->get_parent_visible_window();
  396. gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
  397. if (parent_visible) {
  398. new_focused_window = parent_visible;
  399. } else {
  400. new_focused_window = Object::cast_to<Window>(this);
  401. }
  402. if (new_focused_window) {
  403. int new_focused_index = _sub_window_find(new_focused_window);
  404. if (new_focused_index != -1) {
  405. gui.subwindow_focused = new_focused_window;
  406. } else {
  407. gui.subwindow_focused = nullptr;
  408. }
  409. new_focused_window->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_IN);
  410. } else {
  411. gui.subwindow_focused = nullptr;
  412. }
  413. }
  414. RenderingServer::get_singleton()->viewport_set_parent_viewport(p_window->viewport, p_window->parent ? p_window->parent->viewport : RID());
  415. }
  416. int Viewport::_sub_window_find(Window *p_window) const {
  417. for (int i = 0; i < gui.sub_windows.size(); i++) {
  418. if (gui.sub_windows[i].window == p_window) {
  419. return i;
  420. }
  421. }
  422. return -1;
  423. }
  424. void Viewport::_update_viewport_path() {
  425. if (viewport_textures.is_empty()) {
  426. return;
  427. }
  428. Node *scene_root = get_scene_file_path().is_empty() ? get_owner() : this;
  429. if (!scene_root && is_inside_tree()) {
  430. scene_root = get_tree()->get_edited_scene_root();
  431. }
  432. if (scene_root && (scene_root == this || scene_root->is_ancestor_of(this))) {
  433. NodePath path_in_scene = scene_root->get_path_to(this);
  434. for (ViewportTexture *E : viewport_textures) {
  435. E->path = path_in_scene;
  436. }
  437. }
  438. }
  439. void Viewport::_notification(int p_what) {
  440. ERR_MAIN_THREAD_GUARD;
  441. switch (p_what) {
  442. case NOTIFICATION_ENTER_TREE: {
  443. _update_viewport_path();
  444. if (get_parent()) {
  445. parent = get_parent()->get_viewport();
  446. RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, parent->get_viewport_rid());
  447. } else {
  448. parent = nullptr;
  449. }
  450. current_canvas = find_world_2d()->get_canvas();
  451. RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas);
  452. RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, current_canvas, canvas_transform);
  453. RenderingServer::get_singleton()->viewport_set_canvas_cull_mask(viewport, canvas_cull_mask);
  454. _update_audio_listener_2d();
  455. #ifndef _3D_DISABLED
  456. RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
  457. _update_audio_listener_3d();
  458. #endif // _3D_DISABLED
  459. add_to_group("_viewports");
  460. if (get_tree()->is_debugging_collisions_hint()) {
  461. PhysicsServer2D::get_singleton()->space_set_debug_contacts(find_world_2d()->get_space(), get_tree()->get_collision_debug_contact_count());
  462. contact_2d_debug = RenderingServer::get_singleton()->canvas_item_create();
  463. RenderingServer::get_singleton()->canvas_item_set_parent(contact_2d_debug, current_canvas);
  464. #ifndef _3D_DISABLED
  465. PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count());
  466. contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create();
  467. RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, false);
  468. RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0);
  469. RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid());
  470. contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create();
  471. RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh);
  472. RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario());
  473. RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
  474. #endif // _3D_DISABLED
  475. set_physics_process_internal(true);
  476. }
  477. } break;
  478. case NOTIFICATION_READY: {
  479. #ifndef _3D_DISABLED
  480. if (audio_listener_3d_set.size() && !audio_listener_3d) {
  481. AudioListener3D *first = nullptr;
  482. for (AudioListener3D *E : audio_listener_3d_set) {
  483. if (first == nullptr || first->is_greater_than(E)) {
  484. first = E;
  485. }
  486. }
  487. if (first) {
  488. first->make_current();
  489. }
  490. }
  491. if (camera_3d_set.size() && !camera_3d) {
  492. // There are cameras but no current camera, pick first in tree and make it current.
  493. Camera3D *first = nullptr;
  494. for (Camera3D *E : camera_3d_set) {
  495. if (first == nullptr || first->is_greater_than(E)) {
  496. first = E;
  497. }
  498. }
  499. if (first) {
  500. first->make_current();
  501. }
  502. }
  503. #endif // _3D_DISABLED
  504. } break;
  505. case NOTIFICATION_EXIT_TREE: {
  506. _gui_cancel_tooltip();
  507. RenderingServer::get_singleton()->viewport_set_scenario(viewport, RID());
  508. RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
  509. if (contact_2d_debug.is_valid()) {
  510. RenderingServer::get_singleton()->free(contact_2d_debug);
  511. contact_2d_debug = RID();
  512. }
  513. if (contact_3d_debug_multimesh.is_valid()) {
  514. RenderingServer::get_singleton()->free(contact_3d_debug_multimesh);
  515. RenderingServer::get_singleton()->free(contact_3d_debug_instance);
  516. contact_3d_debug_instance = RID();
  517. contact_3d_debug_multimesh = RID();
  518. }
  519. remove_from_group("_viewports");
  520. set_physics_process_internal(false);
  521. RS::get_singleton()->viewport_set_active(viewport, false);
  522. RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID());
  523. } break;
  524. case NOTIFICATION_PATH_RENAMED: {
  525. _update_viewport_path();
  526. } break;
  527. case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
  528. if (!get_tree()) {
  529. return;
  530. }
  531. if (get_tree()->is_debugging_collisions_hint() && contact_2d_debug.is_valid()) {
  532. RenderingServer::get_singleton()->canvas_item_clear(contact_2d_debug);
  533. RenderingServer::get_singleton()->canvas_item_set_draw_index(contact_2d_debug, 0xFFFFF); //very high index
  534. Vector<Vector2> points = PhysicsServer2D::get_singleton()->space_get_contacts(find_world_2d()->get_space());
  535. int point_count = PhysicsServer2D::get_singleton()->space_get_contact_count(find_world_2d()->get_space());
  536. Color ccol = get_tree()->get_debug_collision_contact_color();
  537. for (int i = 0; i < point_count; i++) {
  538. RenderingServer::get_singleton()->canvas_item_add_rect(contact_2d_debug, Rect2(points[i] - Vector2(2, 2), Vector2(5, 5)), ccol);
  539. }
  540. }
  541. #ifndef _3D_DISABLED
  542. if (get_tree()->is_debugging_collisions_hint() && contact_3d_debug_multimesh.is_valid()) {
  543. Vector<Vector3> points = PhysicsServer3D::get_singleton()->space_get_contacts(find_world_3d()->get_space());
  544. int point_count = PhysicsServer3D::get_singleton()->space_get_contact_count(find_world_3d()->get_space());
  545. RS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count);
  546. for (int i = 0; i < point_count; i++) {
  547. Transform3D point_transform;
  548. point_transform.origin = points[i];
  549. RS::get_singleton()->multimesh_instance_set_transform(contact_3d_debug_multimesh, i, point_transform);
  550. }
  551. }
  552. #endif // _3D_DISABLED
  553. } break;
  554. case NOTIFICATION_VP_MOUSE_ENTER: {
  555. gui.mouse_in_viewport = true;
  556. } break;
  557. case NOTIFICATION_VP_MOUSE_EXIT: {
  558. gui.mouse_in_viewport = false;
  559. _drop_physics_mouseover();
  560. // When the mouse exits the viewport, we don't want to end
  561. // mouse_focus, because, for example, we want to continue
  562. // dragging a scrollbar even if the mouse has left the viewport.
  563. } break;
  564. case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
  565. _gui_cancel_tooltip();
  566. _drop_physics_mouseover();
  567. _drop_mouse_focus();
  568. // When the window focus changes, we want to end mouse_focus, but
  569. // not the mouse_over. Note: The OS will trigger a separate mouse
  570. // exit event if the change in focus results in the mouse exiting
  571. // the window.
  572. } break;
  573. case NOTIFICATION_PREDELETE: {
  574. if (gui_parent) {
  575. gui_parent->gui.tooltip_popup = nullptr;
  576. gui_parent->gui.tooltip_label = nullptr;
  577. }
  578. } break;
  579. }
  580. }
  581. void Viewport::_process_picking() {
  582. if (!is_inside_tree()) {
  583. return;
  584. }
  585. if (!physics_object_picking) {
  586. return;
  587. }
  588. if (Object::cast_to<Window>(this) && Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) {
  589. return;
  590. }
  591. if (!gui.mouse_in_viewport || gui.subwindow_over) {
  592. // Clear picking events if the mouse has left the viewport or is over an embedded window.
  593. // These are locations, that are expected to not trigger physics picking.
  594. physics_picking_events.clear();
  595. return;
  596. }
  597. #ifndef _3D_DISABLED
  598. if (use_xr) {
  599. if (XRServer::get_singleton() != nullptr) {
  600. Ref<XRInterface> xr_interface = XRServer::get_singleton()->get_primary_interface();
  601. if (xr_interface.is_valid() && xr_interface->is_initialized() && xr_interface->get_view_count() > 1) {
  602. WARN_PRINT_ONCE("Object picking can't be used when stereo rendering, this will be turned off!");
  603. physics_object_picking = false; // don't try again.
  604. return;
  605. }
  606. }
  607. }
  608. #endif
  609. _drop_physics_mouseover(true);
  610. #ifndef _3D_DISABLED
  611. Vector2 last_pos(1e20, 1e20);
  612. CollisionObject3D *last_object = nullptr;
  613. ObjectID last_id;
  614. PhysicsDirectSpaceState3D::RayResult result;
  615. #endif // _3D_DISABLED
  616. PhysicsDirectSpaceState2D *ss2d = PhysicsServer2D::get_singleton()->space_get_direct_state(find_world_2d()->get_space());
  617. SubViewportContainer *parent_svc = Object::cast_to<SubViewportContainer>(get_parent());
  618. bool parent_ignore_mouse = (parent_svc && parent_svc->get_mouse_filter() == Control::MOUSE_FILTER_IGNORE);
  619. bool create_passive_hover_event = true;
  620. if (gui.mouse_over || parent_ignore_mouse) {
  621. // When the mouse is over a Control node, passive hovering would cause input events for Colliders, that are behind Control nodes.
  622. // When parent SubViewportContainer ignores mouse, that setting should be respected.
  623. create_passive_hover_event = false;
  624. } else {
  625. for (const Ref<InputEvent> &e : physics_picking_events) {
  626. Ref<InputEventMouse> m = e;
  627. if (m.is_valid()) {
  628. // A mouse event exists, so passive hovering isn't necessary.
  629. create_passive_hover_event = false;
  630. break;
  631. }
  632. }
  633. }
  634. if (create_passive_hover_event) {
  635. // Create a mouse motion event. This is necessary because objects or camera may have moved.
  636. // While this extra event is sent, it is checked if both camera and last object and last ID did not move.
  637. // If nothing changed, the event is discarded to avoid flooding with unnecessary motion events every frame.
  638. Ref<InputEventMouseMotion> mm;
  639. mm.instantiate();
  640. mm->set_device(InputEvent::DEVICE_ID_INTERNAL);
  641. mm->set_position(get_mouse_position());
  642. mm->set_global_position(mm->get_position());
  643. mm->set_alt_pressed(Input::get_singleton()->is_key_pressed(Key::ALT));
  644. mm->set_shift_pressed(Input::get_singleton()->is_key_pressed(Key::SHIFT));
  645. mm->set_ctrl_pressed(Input::get_singleton()->is_key_pressed(Key::CTRL));
  646. mm->set_meta_pressed(Input::get_singleton()->is_key_pressed(Key::META));
  647. mm->set_button_mask(Input::get_singleton()->get_mouse_button_mask());
  648. physics_picking_events.push_back(mm);
  649. }
  650. while (physics_picking_events.size()) {
  651. local_input_handled = false;
  652. if (!handle_input_locally) {
  653. Viewport *vp = this;
  654. while (!Object::cast_to<Window>(vp) && vp->get_parent()) {
  655. vp = vp->get_parent()->get_viewport();
  656. }
  657. vp->local_input_handled = false;
  658. }
  659. Ref<InputEvent> ev = physics_picking_events.front()->get();
  660. physics_picking_events.pop_front();
  661. Vector2 pos;
  662. bool is_mouse = false;
  663. Ref<InputEventMouseMotion> mm = ev;
  664. if (mm.is_valid()) {
  665. pos = mm->get_position();
  666. is_mouse = true;
  667. }
  668. Ref<InputEventMouseButton> mb = ev;
  669. if (mb.is_valid()) {
  670. pos = mb->get_position();
  671. is_mouse = true;
  672. }
  673. Ref<InputEventScreenDrag> sd = ev;
  674. if (sd.is_valid()) {
  675. pos = sd->get_position();
  676. }
  677. Ref<InputEventScreenTouch> st = ev;
  678. if (st.is_valid()) {
  679. pos = st->get_position();
  680. }
  681. if (ss2d) {
  682. // Send to 2D.
  683. uint64_t frame = get_tree()->get_frame();
  684. PhysicsDirectSpaceState2D::ShapeResult res[64];
  685. for (const CanvasLayer *E : canvas_layers) {
  686. Transform2D canvas_layer_transform;
  687. ObjectID canvas_layer_id;
  688. if (E) {
  689. // A descendant CanvasLayer.
  690. canvas_layer_transform = E->get_final_transform();
  691. canvas_layer_id = E->get_instance_id();
  692. } else {
  693. // This Viewport's builtin canvas.
  694. canvas_layer_transform = get_canvas_transform();
  695. canvas_layer_id = ObjectID();
  696. }
  697. Vector2 point = canvas_layer_transform.affine_inverse().xform(pos);
  698. PhysicsDirectSpaceState2D::PointParameters point_params;
  699. point_params.position = point;
  700. point_params.canvas_instance_id = canvas_layer_id;
  701. point_params.collide_with_areas = true;
  702. point_params.pick_point = true;
  703. int rc = ss2d->intersect_point(point_params, res, 64);
  704. if (physics_object_picking_sort) {
  705. struct ComparatorCollisionObjects {
  706. bool operator()(const PhysicsDirectSpaceState2D::ShapeResult &p_a, const PhysicsDirectSpaceState2D::ShapeResult &p_b) const {
  707. CollisionObject2D *a = Object::cast_to<CollisionObject2D>(p_a.collider);
  708. CollisionObject2D *b = Object::cast_to<CollisionObject2D>(p_b.collider);
  709. if (!a || !b) {
  710. return false;
  711. }
  712. int za = a->get_effective_z_index();
  713. int zb = b->get_effective_z_index();
  714. if (za != zb) {
  715. return zb < za;
  716. }
  717. return a->is_greater_than(b);
  718. }
  719. };
  720. SortArray<PhysicsDirectSpaceState2D::ShapeResult, ComparatorCollisionObjects> sorter;
  721. sorter.sort(res, rc);
  722. }
  723. for (int i = 0; i < rc; i++) {
  724. if (is_input_handled()) {
  725. break;
  726. }
  727. if (res[i].collider_id.is_valid() && res[i].collider) {
  728. CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
  729. if (co && co->can_process()) {
  730. bool send_event = true;
  731. if (is_mouse) {
  732. HashMap<ObjectID, uint64_t>::Iterator F = physics_2d_mouseover.find(res[i].collider_id);
  733. if (!F) {
  734. physics_2d_mouseover.insert(res[i].collider_id, frame);
  735. co->_mouse_enter();
  736. } else {
  737. F->value = frame;
  738. // It was already hovered, so don't send the event if it's faked.
  739. if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) {
  740. send_event = false;
  741. }
  742. }
  743. HashMap<Pair<ObjectID, int>, uint64_t, PairHash<ObjectID, int>>::Iterator SF = physics_2d_shape_mouseover.find(Pair(res[i].collider_id, res[i].shape));
  744. if (!SF) {
  745. physics_2d_shape_mouseover.insert(Pair(res[i].collider_id, res[i].shape), frame);
  746. co->_mouse_shape_enter(res[i].shape);
  747. } else {
  748. SF->value = frame;
  749. }
  750. }
  751. if (send_event) {
  752. co->_input_event_call(this, ev, res[i].shape);
  753. }
  754. if (physics_object_picking_first_only) {
  755. break;
  756. }
  757. }
  758. }
  759. }
  760. }
  761. if (is_mouse) {
  762. _cleanup_mouseover_colliders(false, false, frame);
  763. }
  764. }
  765. #ifndef _3D_DISABLED
  766. if (physics_object_picking_first_only && is_input_handled()) {
  767. continue;
  768. }
  769. CollisionObject3D *capture_object = nullptr;
  770. if (physics_object_capture.is_valid()) {
  771. capture_object = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture));
  772. if (!capture_object || !camera_3d || (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed())) {
  773. physics_object_capture = ObjectID();
  774. } else {
  775. last_id = physics_object_capture;
  776. last_object = capture_object;
  777. }
  778. }
  779. if (pos == last_pos) {
  780. if (last_id.is_valid()) {
  781. if (ObjectDB::get_instance(last_id) && last_object) {
  782. // Good, exists.
  783. _collision_object_3d_input_event(last_object, camera_3d, ev, result.position, result.normal, result.shape);
  784. if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
  785. physics_object_capture = last_id;
  786. }
  787. }
  788. }
  789. } else {
  790. if (camera_3d) {
  791. Vector3 from = camera_3d->project_ray_origin(pos);
  792. Vector3 dir = camera_3d->project_ray_normal(pos);
  793. real_t depth_far = camera_3d->get_far();
  794. PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space());
  795. if (space) {
  796. PhysicsDirectSpaceState3D::RayParameters ray_params;
  797. ray_params.from = from;
  798. ray_params.to = from + dir * depth_far;
  799. ray_params.collide_with_areas = true;
  800. ray_params.pick_ray = true;
  801. bool col = space->intersect_ray(ray_params, result);
  802. ObjectID new_collider;
  803. CollisionObject3D *co = col ? Object::cast_to<CollisionObject3D>(result.collider) : nullptr;
  804. if (co && co->can_process()) {
  805. new_collider = result.collider_id;
  806. if (!capture_object) {
  807. last_object = co;
  808. last_id = result.collider_id;
  809. if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
  810. physics_object_capture = last_id;
  811. }
  812. }
  813. }
  814. if (is_mouse && new_collider != physics_object_over) {
  815. if (physics_object_over.is_valid()) {
  816. CollisionObject3D *previous_co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
  817. if (previous_co) {
  818. previous_co->_mouse_exit();
  819. }
  820. }
  821. if (new_collider.is_valid()) {
  822. DEV_ASSERT(co);
  823. co->_mouse_enter();
  824. }
  825. physics_object_over = new_collider;
  826. }
  827. if (capture_object) {
  828. _collision_object_3d_input_event(capture_object, camera_3d, ev, result.position, result.normal, result.shape);
  829. } else if (new_collider.is_valid()) {
  830. _collision_object_3d_input_event(co, camera_3d, ev, result.position, result.normal, result.shape);
  831. }
  832. }
  833. last_pos = pos;
  834. }
  835. }
  836. #endif // _3D_DISABLED
  837. }
  838. }
  839. RID Viewport::get_viewport_rid() const {
  840. ERR_READ_THREAD_GUARD_V(RID());
  841. return viewport;
  842. }
  843. void Viewport::update_canvas_items() {
  844. ERR_MAIN_THREAD_GUARD;
  845. if (!is_inside_tree()) {
  846. return;
  847. }
  848. if (is_embedding_subwindows()) {
  849. for (Viewport::SubWindow w : gui.sub_windows) {
  850. if (w.window && !w.pending_window_update) {
  851. w.pending_window_update = true;
  852. w.window->_update_viewport_size();
  853. callable_mp(this, &Viewport::_sub_window_update).call_deferred(w.window);
  854. }
  855. }
  856. }
  857. _update_canvas_items(this);
  858. }
  859. bool Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override, bool p_allocated) {
  860. Transform2D stretch_transform_new = Transform2D();
  861. if (is_size_2d_override_stretch_enabled() && p_size_2d_override.width > 0 && p_size_2d_override.height > 0) {
  862. Size2 scale = Size2(p_size) / Size2(p_size_2d_override);
  863. stretch_transform_new.scale(scale);
  864. }
  865. Size2i new_size = p_size.maxi(2);
  866. if (size == new_size && size_allocated == p_allocated && stretch_transform == stretch_transform_new && p_size_2d_override == size_2d_override) {
  867. return false;
  868. }
  869. size = new_size;
  870. size_allocated = p_allocated;
  871. size_2d_override = p_size_2d_override;
  872. stretch_transform = stretch_transform_new;
  873. #ifndef _3D_DISABLED
  874. if (!use_xr) {
  875. #endif
  876. if (p_allocated) {
  877. RS::get_singleton()->viewport_set_size(viewport, size.width, size.height);
  878. } else {
  879. RS::get_singleton()->viewport_set_size(viewport, 0, 0);
  880. }
  881. #ifndef _3D_DISABLED
  882. } // if (!use_xr)
  883. #endif
  884. _update_global_transform();
  885. update_configuration_warnings();
  886. update_canvas_items();
  887. for (ViewportTexture *E : viewport_textures) {
  888. E->emit_changed();
  889. }
  890. emit_signal(SNAME("size_changed"));
  891. Rect2i limit = get_visible_rect();
  892. for (int i = 0; i < gui.sub_windows.size(); ++i) {
  893. Window *sw = gui.sub_windows[i].window;
  894. Rect2i rect = Rect2i(sw->position, sw->size);
  895. Rect2i new_rect = sw->fit_rect_in_parent(rect, limit);
  896. if (new_rect != rect) {
  897. sw->set_position(new_rect.position);
  898. sw->set_size(new_rect.size);
  899. }
  900. }
  901. return true;
  902. }
  903. Size2i Viewport::_get_size() const {
  904. #ifndef _3D_DISABLED
  905. if (use_xr) {
  906. if (XRServer::get_singleton() != nullptr) {
  907. Ref<XRInterface> xr_interface = XRServer::get_singleton()->get_primary_interface();
  908. if (xr_interface.is_valid() && xr_interface->is_initialized()) {
  909. Size2 xr_size = xr_interface->get_render_target_size();
  910. return (Size2i)xr_size;
  911. }
  912. }
  913. return Size2i();
  914. }
  915. #endif // _3D_DISABLED
  916. return size;
  917. }
  918. Size2i Viewport::_get_size_2d_override() const {
  919. return size_2d_override;
  920. }
  921. bool Viewport::_is_size_allocated() const {
  922. return size_allocated;
  923. }
  924. Rect2 Viewport::get_visible_rect() const {
  925. ERR_READ_THREAD_GUARD_V(Rect2());
  926. Rect2 r;
  927. if (size == Size2()) {
  928. r = Rect2(Point2(), DisplayServer::get_singleton()->window_get_size());
  929. } else {
  930. r = Rect2(Point2(), size);
  931. }
  932. if (size_2d_override != Size2i()) {
  933. r.size = size_2d_override;
  934. }
  935. return r;
  936. }
  937. void Viewport::canvas_parent_mark_dirty(Node *p_node) {
  938. ERR_MAIN_THREAD_GUARD;
  939. bool request_update = gui.canvas_parents_with_dirty_order.is_empty();
  940. gui.canvas_parents_with_dirty_order.insert(p_node->get_instance_id());
  941. if (request_update) {
  942. callable_mp(this, &Viewport::_process_dirty_canvas_parent_orders).call_deferred();
  943. }
  944. }
  945. void Viewport::enable_canvas_transform_override(bool p_enable) {
  946. ERR_MAIN_THREAD_GUARD;
  947. if (override_canvas_transform == p_enable) {
  948. return;
  949. }
  950. override_canvas_transform = p_enable;
  951. if (p_enable) {
  952. RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform_override);
  953. } else {
  954. RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform);
  955. }
  956. }
  957. bool Viewport::is_canvas_transform_override_enabled() const {
  958. ERR_READ_THREAD_GUARD_V(false);
  959. return override_canvas_transform;
  960. }
  961. void Viewport::set_canvas_transform_override(const Transform2D &p_transform) {
  962. ERR_MAIN_THREAD_GUARD;
  963. if (canvas_transform_override == p_transform) {
  964. return;
  965. }
  966. canvas_transform_override = p_transform;
  967. if (override_canvas_transform) {
  968. RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform_override);
  969. }
  970. }
  971. Transform2D Viewport::get_canvas_transform_override() const {
  972. ERR_READ_THREAD_GUARD_V(Transform2D());
  973. return canvas_transform_override;
  974. }
  975. void Viewport::set_canvas_transform(const Transform2D &p_transform) {
  976. ERR_MAIN_THREAD_GUARD;
  977. canvas_transform = p_transform;
  978. if (!override_canvas_transform) {
  979. RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform);
  980. }
  981. }
  982. Transform2D Viewport::get_canvas_transform() const {
  983. ERR_READ_THREAD_GUARD_V(Transform2D());
  984. return canvas_transform;
  985. }
  986. void Viewport::_update_global_transform() {
  987. Transform2D sxform = stretch_transform * global_canvas_transform;
  988. RenderingServer::get_singleton()->viewport_set_global_canvas_transform(viewport, sxform);
  989. }
  990. void Viewport::set_global_canvas_transform(const Transform2D &p_transform) {
  991. ERR_MAIN_THREAD_GUARD;
  992. global_canvas_transform = p_transform;
  993. _update_global_transform();
  994. }
  995. Transform2D Viewport::get_global_canvas_transform() const {
  996. ERR_READ_THREAD_GUARD_V(Transform2D());
  997. return global_canvas_transform;
  998. }
  999. void Viewport::_canvas_layer_add(CanvasLayer *p_canvas_layer) {
  1000. canvas_layers.insert(p_canvas_layer);
  1001. }
  1002. void Viewport::_canvas_layer_remove(CanvasLayer *p_canvas_layer) {
  1003. canvas_layers.erase(p_canvas_layer);
  1004. }
  1005. void Viewport::set_transparent_background(bool p_enable) {
  1006. ERR_MAIN_THREAD_GUARD;
  1007. transparent_bg = p_enable;
  1008. RS::get_singleton()->viewport_set_transparent_background(viewport, p_enable);
  1009. }
  1010. bool Viewport::has_transparent_background() const {
  1011. ERR_READ_THREAD_GUARD_V(false);
  1012. return transparent_bg;
  1013. }
  1014. void Viewport::set_use_hdr_2d(bool p_enable) {
  1015. ERR_MAIN_THREAD_GUARD;
  1016. use_hdr_2d = p_enable;
  1017. RS::get_singleton()->viewport_set_use_hdr_2d(viewport, p_enable);
  1018. }
  1019. bool Viewport::is_using_hdr_2d() const {
  1020. ERR_READ_THREAD_GUARD_V(false);
  1021. return use_hdr_2d;
  1022. }
  1023. void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
  1024. ERR_MAIN_THREAD_GUARD;
  1025. if (world_2d == p_world_2d) {
  1026. return;
  1027. }
  1028. if (is_inside_tree()) {
  1029. RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
  1030. }
  1031. if (world_2d.is_valid()) {
  1032. world_2d->remove_viewport(this);
  1033. }
  1034. if (p_world_2d.is_valid()) {
  1035. bool do_propagate = world_2d.is_valid() && is_inside_tree();
  1036. world_2d = p_world_2d;
  1037. if (do_propagate) {
  1038. _propagate_world_2d_changed(this);
  1039. }
  1040. } else {
  1041. WARN_PRINT("Invalid world_2d");
  1042. world_2d.instantiate();
  1043. }
  1044. world_2d->register_viewport(this);
  1045. _update_audio_listener_2d();
  1046. if (is_inside_tree()) {
  1047. current_canvas = find_world_2d()->get_canvas();
  1048. RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas);
  1049. }
  1050. }
  1051. Ref<World2D> Viewport::find_world_2d() const {
  1052. ERR_READ_THREAD_GUARD_V(Ref<World2D>());
  1053. if (world_2d.is_valid()) {
  1054. return world_2d;
  1055. } else if (parent) {
  1056. return parent->find_world_2d();
  1057. } else {
  1058. return Ref<World2D>();
  1059. }
  1060. }
  1061. void Viewport::_propagate_drag_notification(Node *p_node, int p_what) {
  1062. // Send notification to p_node and all children and descendant nodes of p_node, except to SubViewports which are not children of a SubViewportContainer.
  1063. p_node->notification(p_what);
  1064. bool is_svc = Object::cast_to<SubViewportContainer>(p_node);
  1065. for (int i = 0; i < p_node->get_child_count(); i++) {
  1066. Node *c = p_node->get_child(i);
  1067. if (!is_svc && Object::cast_to<SubViewport>(c)) {
  1068. continue;
  1069. }
  1070. Viewport::_propagate_drag_notification(c, p_what);
  1071. }
  1072. }
  1073. Ref<World2D> Viewport::get_world_2d() const {
  1074. ERR_READ_THREAD_GUARD_V(Ref<World2D>());
  1075. return world_2d;
  1076. }
  1077. Transform2D Viewport::get_stretch_transform() const {
  1078. return stretch_transform;
  1079. }
  1080. Transform2D Viewport::get_final_transform() const {
  1081. ERR_READ_THREAD_GUARD_V(Transform2D());
  1082. return stretch_transform * global_canvas_transform;
  1083. }
  1084. void Viewport::_update_canvas_items(Node *p_node) {
  1085. if (p_node != this) {
  1086. Window *w = Object::cast_to<Window>(p_node);
  1087. if (w && (!w->is_inside_tree() || !w->is_embedded())) {
  1088. return;
  1089. }
  1090. CanvasItem *ci = Object::cast_to<CanvasItem>(p_node);
  1091. if (ci) {
  1092. ci->queue_redraw();
  1093. }
  1094. }
  1095. int cc = p_node->get_child_count();
  1096. for (int i = 0; i < cc; i++) {
  1097. _update_canvas_items(p_node->get_child(i));
  1098. }
  1099. }
  1100. Ref<ViewportTexture> Viewport::get_texture() const {
  1101. ERR_READ_THREAD_GUARD_V(Ref<ViewportTexture>());
  1102. return default_texture;
  1103. }
  1104. void Viewport::set_positional_shadow_atlas_size(int p_size) {
  1105. ERR_MAIN_THREAD_GUARD;
  1106. positional_shadow_atlas_size = p_size;
  1107. RS::get_singleton()->viewport_set_positional_shadow_atlas_size(viewport, p_size, positional_shadow_atlas_16_bits);
  1108. }
  1109. int Viewport::get_positional_shadow_atlas_size() const {
  1110. ERR_READ_THREAD_GUARD_V(0);
  1111. return positional_shadow_atlas_size;
  1112. }
  1113. void Viewport::set_positional_shadow_atlas_16_bits(bool p_16_bits) {
  1114. ERR_MAIN_THREAD_GUARD;
  1115. if (positional_shadow_atlas_16_bits == p_16_bits) {
  1116. return;
  1117. }
  1118. positional_shadow_atlas_16_bits = p_16_bits;
  1119. RS::get_singleton()->viewport_set_positional_shadow_atlas_size(viewport, positional_shadow_atlas_size, positional_shadow_atlas_16_bits);
  1120. }
  1121. bool Viewport::get_positional_shadow_atlas_16_bits() const {
  1122. ERR_READ_THREAD_GUARD_V(false);
  1123. return positional_shadow_atlas_16_bits;
  1124. }
  1125. void Viewport::set_positional_shadow_atlas_quadrant_subdiv(int p_quadrant, PositionalShadowAtlasQuadrantSubdiv p_subdiv) {
  1126. ERR_MAIN_THREAD_GUARD;
  1127. ERR_FAIL_INDEX(p_quadrant, 4);
  1128. ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
  1129. if (positional_shadow_atlas_quadrant_subdiv[p_quadrant] == p_subdiv) {
  1130. return;
  1131. }
  1132. positional_shadow_atlas_quadrant_subdiv[p_quadrant] = p_subdiv;
  1133. static const int subdiv[SHADOW_ATLAS_QUADRANT_SUBDIV_MAX] = { 0, 1, 4, 16, 64, 256, 1024 };
  1134. RS::get_singleton()->viewport_set_positional_shadow_atlas_quadrant_subdivision(viewport, p_quadrant, subdiv[p_subdiv]);
  1135. }
  1136. Viewport::PositionalShadowAtlasQuadrantSubdiv Viewport::get_positional_shadow_atlas_quadrant_subdiv(int p_quadrant) const {
  1137. ERR_READ_THREAD_GUARD_V(SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
  1138. ERR_FAIL_INDEX_V(p_quadrant, 4, SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
  1139. return positional_shadow_atlas_quadrant_subdiv[p_quadrant];
  1140. }
  1141. Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) {
  1142. if (ev.is_null()) {
  1143. return ev; // No transformation defined for null event
  1144. }
  1145. Transform2D ai = get_final_transform().affine_inverse();
  1146. Ref<InputEventMouse> me = ev;
  1147. if (me.is_valid()) {
  1148. me = me->xformed_by(ai);
  1149. // For InputEventMouse, the global position is not adjusted by ev->xformed_by() and needs to be set separately.
  1150. me->set_global_position(me->get_position());
  1151. return me;
  1152. }
  1153. return ev->xformed_by(ai);
  1154. }
  1155. Vector2 Viewport::get_mouse_position() const {
  1156. ERR_READ_THREAD_GUARD_V(Vector2());
  1157. if (get_section_root_viewport() != SceneTree::get_singleton()->get_root()) {
  1158. // Rely on the most recent mouse coordinate from an InputEventMouse in push_input.
  1159. // In this case get_screen_transform is not applicable, because it is ambiguous.
  1160. return gui.last_mouse_pos;
  1161. } else if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_MOUSE)) {
  1162. Transform2D xform = get_screen_transform_internal(true);
  1163. if (xform.determinant() == 0) {
  1164. // Screen transform can be non-invertible when the Window is minimized.
  1165. return Vector2();
  1166. }
  1167. return xform.affine_inverse().xform(DisplayServer::get_singleton()->mouse_get_position());
  1168. } else {
  1169. // Fallback to Input for getting mouse position in case of emulated mouse.
  1170. return get_screen_transform_internal().affine_inverse().xform(Input::get_singleton()->get_mouse_position());
  1171. }
  1172. }
  1173. void Viewport::warp_mouse(const Vector2 &p_position) {
  1174. ERR_MAIN_THREAD_GUARD;
  1175. Transform2D xform = get_screen_transform_internal();
  1176. Vector2 gpos = xform.xform(p_position);
  1177. Input::get_singleton()->warp_mouse(gpos);
  1178. }
  1179. Point2 Viewport::wrap_mouse_in_rect(const Vector2 &p_relative, const Rect2 &p_rect) {
  1180. // Move the mouse cursor from its current position to a location bounded by `p_rect`
  1181. // in accordance with a heuristic that takes the traveled distance `p_relative` of the mouse
  1182. // into account.
  1183. // All parameters are in viewport coordinates.
  1184. // p_relative denotes the distance to the previous mouse position.
  1185. // p_rect denotes the area, in which the mouse should be confined in.
  1186. // The relative distance reported for the next event after a warp is in the boundaries of the
  1187. // size of the rect on that axis, but it may be greater, in which case there's no problem as
  1188. // fmod() will warp it, but if the pointer has moved in the opposite direction between the
  1189. // pointer relocation and the subsequent event, the reported relative distance will be less
  1190. // than the size of the rect and thus fmod() will be disabled for handling the situation.
  1191. // And due to this mouse warping mechanism being stateless, we need to apply some heuristics
  1192. // to detect the warp: if the relative distance is greater than the half of the size of the
  1193. // relevant rect (checked per each axis), it will be considered as the consequence of a former
  1194. // pointer warp.
  1195. const Point2 rel_sign(p_relative.x >= 0.0f ? 1 : -1, p_relative.y >= 0.0 ? 1 : -1);
  1196. const Size2 warp_margin = p_rect.size * 0.5f;
  1197. const Point2 rel_warped(
  1198. Math::fmod(p_relative.x + rel_sign.x * warp_margin.x, p_rect.size.x) - rel_sign.x * warp_margin.x,
  1199. Math::fmod(p_relative.y + rel_sign.y * warp_margin.y, p_rect.size.y) - rel_sign.y * warp_margin.y);
  1200. const Point2 pos_local = get_mouse_position() - p_rect.position;
  1201. const Point2 pos_warped(Math::fposmod(pos_local.x, p_rect.size.x), Math::fposmod(pos_local.y, p_rect.size.y));
  1202. if (pos_warped != pos_local) {
  1203. warp_mouse(pos_warped + p_rect.position);
  1204. }
  1205. return rel_warped;
  1206. }
  1207. void Viewport::_gui_sort_roots() {
  1208. if (!gui.roots_order_dirty) {
  1209. return;
  1210. }
  1211. gui.roots.sort_custom<Control::CComparator>();
  1212. gui.roots_order_dirty = false;
  1213. }
  1214. void Viewport::_gui_cancel_tooltip() {
  1215. gui.tooltip_control = nullptr;
  1216. gui.tooltip_text = "";
  1217. if (gui.tooltip_timer.is_valid()) {
  1218. gui.tooltip_timer->release_connections();
  1219. gui.tooltip_timer = Ref<SceneTreeTimer>();
  1220. }
  1221. if (gui.tooltip_popup) {
  1222. gui.tooltip_popup->queue_free();
  1223. }
  1224. }
  1225. String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_tooltip_owner) {
  1226. Vector2 pos = p_pos;
  1227. String tooltip;
  1228. while (p_control) {
  1229. tooltip = p_control->get_tooltip(pos);
  1230. // Temporary solution for PopupMenus.
  1231. PopupMenu *menu = Object::cast_to<PopupMenu>(this);
  1232. if (menu) {
  1233. tooltip = menu->get_tooltip(pos);
  1234. }
  1235. if (r_tooltip_owner) {
  1236. *r_tooltip_owner = p_control;
  1237. }
  1238. // If we found a tooltip, we stop here.
  1239. if (!tooltip.is_empty()) {
  1240. break;
  1241. }
  1242. // Otherwise, we check parent controls unless some conditions prevent it.
  1243. if (p_control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
  1244. break;
  1245. }
  1246. if (p_control->is_set_as_top_level()) {
  1247. break;
  1248. }
  1249. // Transform cursor pos for parent control.
  1250. pos = p_control->get_transform().xform(pos);
  1251. p_control = p_control->get_parent_control();
  1252. }
  1253. return tooltip;
  1254. }
  1255. void Viewport::_gui_show_tooltip() {
  1256. if (!gui.tooltip_control) {
  1257. return;
  1258. }
  1259. // Get the Control under cursor and the relevant tooltip text, if any.
  1260. Control *tooltip_owner = nullptr;
  1261. gui.tooltip_text = _gui_get_tooltip(
  1262. gui.tooltip_control,
  1263. gui.tooltip_control->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos),
  1264. &tooltip_owner);
  1265. gui.tooltip_text = gui.tooltip_text.strip_edges();
  1266. // Controls can implement `make_custom_tooltip` to provide their own tooltip.
  1267. // This should be a Control node which will be added as child to a TooltipPanel.
  1268. Control *base_tooltip = tooltip_owner->make_custom_tooltip(gui.tooltip_text);
  1269. // When the custom control is not visible, don't show any tooltip.
  1270. // This way, the custom tooltip from `ConnectionsDockTree` can create
  1271. // its own tooltip without conflicting with the default one, even an empty tooltip.
  1272. if (base_tooltip && !base_tooltip->is_visible()) {
  1273. return;
  1274. }
  1275. if (gui.tooltip_text.is_empty() && !base_tooltip) {
  1276. return; // Nothing to show.
  1277. }
  1278. // Remove previous popup if we change something.
  1279. if (gui.tooltip_popup) {
  1280. memdelete(gui.tooltip_popup);
  1281. gui.tooltip_popup = nullptr;
  1282. }
  1283. if (!tooltip_owner) {
  1284. return;
  1285. }
  1286. // Popup window which houses the tooltip content.
  1287. PopupPanel *panel = memnew(PopupPanel);
  1288. panel->set_theme_type_variation(SNAME("TooltipPanel"));
  1289. // If no custom tooltip is given, use a default implementation.
  1290. if (!base_tooltip) {
  1291. gui.tooltip_label = memnew(Label);
  1292. gui.tooltip_label->set_theme_type_variation(SNAME("TooltipLabel"));
  1293. gui.tooltip_label->set_text(gui.tooltip_text);
  1294. gui.tooltip_label->set_auto_translate_mode(tooltip_owner->get_tooltip_auto_translate_mode());
  1295. base_tooltip = gui.tooltip_label;
  1296. panel->connect(SceneStringName(mouse_entered), callable_mp(this, &Viewport::_gui_cancel_tooltip));
  1297. }
  1298. base_tooltip->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
  1299. panel->set_flag(Window::FLAG_NO_FOCUS, true);
  1300. panel->set_flag(Window::FLAG_POPUP, false);
  1301. panel->set_flag(Window::FLAG_MOUSE_PASSTHROUGH, true);
  1302. panel->set_wrap_controls(true);
  1303. panel->add_child(base_tooltip);
  1304. panel->gui_parent = this;
  1305. gui.tooltip_popup = panel;
  1306. tooltip_owner->add_child(gui.tooltip_popup);
  1307. Window *window = Object::cast_to<Window>(gui.tooltip_popup->get_embedder());
  1308. if (!window) { // Not embedded.
  1309. window = gui.tooltip_popup->get_parent_visible_window();
  1310. }
  1311. float win_scale = window->content_scale_factor;
  1312. Point2 tooltip_offset = GLOBAL_GET("display/mouse_cursor/tooltip_position_offset");
  1313. if (!gui.tooltip_popup->is_embedded()) {
  1314. tooltip_offset *= win_scale;
  1315. }
  1316. Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size());
  1317. Rect2i vr;
  1318. if (gui.tooltip_popup->is_embedded()) {
  1319. vr = gui.tooltip_popup->get_embedder()->get_visible_rect();
  1320. } else {
  1321. panel->content_scale_factor = win_scale;
  1322. r.size *= win_scale;
  1323. vr = window->get_usable_parent_rect();
  1324. }
  1325. r.size = r.size.ceil();
  1326. r.size = r.size.min(panel->get_max_size());
  1327. if (r.size.x + r.position.x > vr.size.x + vr.position.x) {
  1328. // Place it in the opposite direction. If it fails, just hug the border.
  1329. r.position.x = gui.tooltip_pos.x - r.size.x - tooltip_offset.x;
  1330. if (r.position.x < vr.position.x) {
  1331. r.position.x = vr.position.x + vr.size.x - r.size.x;
  1332. }
  1333. } else if (r.position.x < vr.position.x) {
  1334. r.position.x = vr.position.x;
  1335. }
  1336. if (r.size.y + r.position.y > vr.size.y + vr.position.y) {
  1337. // Same as above.
  1338. r.position.y = gui.tooltip_pos.y - r.size.y - tooltip_offset.y;
  1339. if (r.position.y < vr.position.y) {
  1340. r.position.y = vr.position.y + vr.size.y - r.size.y;
  1341. }
  1342. } else if (r.position.y < vr.position.y) {
  1343. r.position.y = vr.position.y;
  1344. }
  1345. DisplayServer::WindowID active_popup = DisplayServer::get_singleton()->window_get_active_popup();
  1346. if (active_popup == DisplayServer::INVALID_WINDOW_ID || active_popup == window->get_window_id()) {
  1347. gui.tooltip_popup->popup(r);
  1348. }
  1349. gui.tooltip_popup->child_controls_changed();
  1350. }
  1351. void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_input) {
  1352. Ref<InputEvent> ev = p_input;
  1353. // Returns true if an event should be impacted by a control's mouse filter.
  1354. bool is_pointer_event = Ref<InputEventMouse>(p_input).is_valid() || Ref<InputEventScreenDrag>(p_input).is_valid() || Ref<InputEventScreenTouch>(p_input).is_valid();
  1355. Ref<InputEventMouseButton> mb = p_input;
  1356. bool is_scroll_event = mb.is_valid() &&
  1357. (mb->get_button_index() == MouseButton::WHEEL_DOWN ||
  1358. mb->get_button_index() == MouseButton::WHEEL_UP ||
  1359. mb->get_button_index() == MouseButton::WHEEL_LEFT ||
  1360. mb->get_button_index() == MouseButton::WHEEL_RIGHT);
  1361. CanvasItem *ci = p_control;
  1362. while (ci) {
  1363. Control *control = Object::cast_to<Control>(ci);
  1364. if (control) {
  1365. if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) {
  1366. control->_call_gui_input(ev);
  1367. }
  1368. if (!control->is_inside_tree() || control->is_set_as_top_level()) {
  1369. break;
  1370. }
  1371. if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP && is_pointer_event && !(is_scroll_event && control->data.force_pass_scroll_events)) {
  1372. // Mouse, ScreenDrag and ScreenTouch events are stopped by default with MOUSE_FILTER_STOP, unless we have a scroll event and force_pass_scroll_events set to true
  1373. set_input_as_handled();
  1374. break;
  1375. }
  1376. }
  1377. if (is_input_handled()) {
  1378. // Break when the event is set to handled in a child Control node or after physics picking in SubViewport.
  1379. break;
  1380. }
  1381. if (ci->is_set_as_top_level()) {
  1382. break;
  1383. }
  1384. ev = ev->xformed_by(ci->get_transform()); // Transform event upwards.
  1385. ci = ci->get_parent_item();
  1386. }
  1387. }
  1388. void Viewport::_gui_call_notification(Control *p_control, int p_what) {
  1389. CanvasItem *ci = p_control;
  1390. while (ci) {
  1391. Control *control = Object::cast_to<Control>(ci);
  1392. if (control) {
  1393. if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) {
  1394. control->notification(p_what);
  1395. }
  1396. if (!control->is_inside_tree()) {
  1397. break;
  1398. }
  1399. if (!control->is_inside_tree() || control->is_set_as_top_level()) {
  1400. break;
  1401. }
  1402. if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
  1403. break;
  1404. }
  1405. }
  1406. if (ci->is_set_as_top_level()) {
  1407. break;
  1408. }
  1409. ci = ci->get_parent_item();
  1410. }
  1411. }
  1412. // `gui_find_control` doesn't take embedded windows into account. So the caller of this function
  1413. // needs to make sure, that there is no embedded window at the specified position.
  1414. Control *Viewport::gui_find_control(const Point2 &p_global) {
  1415. ERR_MAIN_THREAD_GUARD_V(nullptr);
  1416. _gui_sort_roots();
  1417. for (List<Control *>::Element *E = gui.roots.back(); E; E = E->prev()) {
  1418. Control *sw = E->get();
  1419. if (!sw->is_visible_in_tree()) {
  1420. continue;
  1421. }
  1422. Transform2D xform;
  1423. CanvasItem *pci = sw->get_parent_item();
  1424. if (pci) {
  1425. xform = pci->get_global_transform_with_canvas();
  1426. } else {
  1427. xform = sw->get_canvas_transform();
  1428. }
  1429. Control *ret = _gui_find_control_at_pos(sw, p_global, xform);
  1430. if (ret) {
  1431. return ret;
  1432. }
  1433. }
  1434. return nullptr;
  1435. }
  1436. Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform) {
  1437. if (!p_node->is_visible()) {
  1438. return nullptr; // Canvas item hidden, discard.
  1439. }
  1440. Transform2D matrix = p_xform * p_node->get_transform();
  1441. // matrix.determinant() == 0.0f implies that node does not exist on scene
  1442. if (matrix.determinant() == 0.0f) {
  1443. return nullptr;
  1444. }
  1445. Control *c = Object::cast_to<Control>(p_node);
  1446. if (!c || !c->is_clipping_contents() || c->has_point(matrix.affine_inverse().xform(p_global))) {
  1447. for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
  1448. CanvasItem *ci = Object::cast_to<CanvasItem>(p_node->get_child(i));
  1449. if (!ci || ci->is_set_as_top_level()) {
  1450. continue;
  1451. }
  1452. Control *ret = _gui_find_control_at_pos(ci, p_global, matrix);
  1453. if (ret) {
  1454. return ret;
  1455. }
  1456. }
  1457. }
  1458. if (!c || c->data.mouse_filter == Control::MOUSE_FILTER_IGNORE) {
  1459. return nullptr;
  1460. }
  1461. matrix.affine_invert();
  1462. if (!c->has_point(matrix.xform(p_global))) {
  1463. return nullptr;
  1464. }
  1465. Control *drag_preview = _gui_get_drag_preview();
  1466. if (!drag_preview || (c != drag_preview && !drag_preview->is_ancestor_of(c))) {
  1467. return c;
  1468. }
  1469. return nullptr;
  1470. }
  1471. bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check) {
  1472. // Attempt drop, try parent controls too.
  1473. CanvasItem *ci = p_at_control;
  1474. Viewport *section_root = get_section_root_viewport();
  1475. while (ci) {
  1476. Control *control = Object::cast_to<Control>(ci);
  1477. if (control) {
  1478. if (control->can_drop_data(p_at_pos, section_root->gui.drag_data)) {
  1479. if (!p_just_check) {
  1480. control->drop_data(p_at_pos, section_root->gui.drag_data);
  1481. }
  1482. return true;
  1483. }
  1484. if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
  1485. break;
  1486. }
  1487. }
  1488. p_at_pos = ci->get_transform().xform(p_at_pos);
  1489. if (ci->is_set_as_top_level()) {
  1490. break;
  1491. }
  1492. ci = ci->get_parent_item();
  1493. }
  1494. return false;
  1495. }
  1496. void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
  1497. ERR_FAIL_COND(p_event.is_null());
  1498. Ref<InputEventMouseButton> mb = p_event;
  1499. if (mb.is_valid()) {
  1500. Point2 mpos = mb->get_position();
  1501. if (mb->is_pressed()) {
  1502. if (gui.dragging && mb->get_button_index() == MouseButton::RIGHT) {
  1503. _perform_drop();
  1504. set_input_as_handled();
  1505. return;
  1506. }
  1507. MouseButtonMask button_mask = mouse_button_to_mask(mb->get_button_index());
  1508. if (!gui.mouse_focus_mask.is_empty() && !gui.mouse_focus_mask.has_flag(button_mask)) {
  1509. // Do not steal mouse focus and stuff while a focus mask without the current mouse button exists.
  1510. gui.mouse_focus_mask.set_flag(button_mask);
  1511. } else {
  1512. gui.mouse_focus = gui_find_control(mpos);
  1513. if (!gui.mouse_focus) {
  1514. return;
  1515. }
  1516. gui.mouse_focus_mask.set_flag(mouse_button_to_mask(mb->get_button_index()));
  1517. if (mb->get_button_index() == MouseButton::LEFT) {
  1518. gui.drag_accum = Vector2();
  1519. gui.drag_attempted = false;
  1520. }
  1521. }
  1522. DEV_ASSERT(gui.mouse_focus);
  1523. mb = mb->xformed_by(Transform2D()); // Make a copy of the event.
  1524. Point2 pos = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(mpos);
  1525. mb->set_position(pos);
  1526. #ifdef DEBUG_ENABLED
  1527. if (EngineDebugger::get_singleton()) {
  1528. Array arr;
  1529. arr.push_back(gui.mouse_focus->get_path());
  1530. arr.push_back(gui.mouse_focus->get_class());
  1531. EngineDebugger::get_singleton()->send_message("scene:click_ctrl", arr);
  1532. }
  1533. #endif
  1534. if (mb->get_button_index() == MouseButton::LEFT) { // Assign focus.
  1535. CanvasItem *ci = gui.mouse_focus;
  1536. while (ci) {
  1537. Control *control = Object::cast_to<Control>(ci);
  1538. if (control) {
  1539. if (control->get_focus_mode() != Control::FOCUS_NONE) {
  1540. // Grabbing unhovered focus can cause issues when mouse is dragged
  1541. // with another button held down.
  1542. if (control != gui.key_focus && gui.mouse_over_hierarchy.has(control)) {
  1543. control->grab_focus();
  1544. }
  1545. break;
  1546. }
  1547. if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
  1548. break;
  1549. }
  1550. }
  1551. if (ci->is_set_as_top_level()) {
  1552. break;
  1553. }
  1554. ci = ci->get_parent_item();
  1555. }
  1556. }
  1557. if (gui.mouse_focus && gui.mouse_focus->can_process()) {
  1558. _gui_call_input(gui.mouse_focus, mb);
  1559. }
  1560. if (gui.dragging && mb->get_button_index() == MouseButton::LEFT) {
  1561. // Alternate drop use (when using force_drag(), as proposed by #5342).
  1562. _perform_drop(gui.mouse_focus);
  1563. }
  1564. _gui_cancel_tooltip();
  1565. } else {
  1566. if (gui.dragging && mb->get_button_index() == MouseButton::LEFT) {
  1567. _perform_drop(gui.drag_mouse_over);
  1568. }
  1569. gui.mouse_focus_mask.clear_flag(mouse_button_to_mask(mb->get_button_index())); // Remove from mask.
  1570. if (!gui.mouse_focus) {
  1571. // Release event is only sent if a mouse focus (previously pressed button) exists.
  1572. return;
  1573. }
  1574. mb = mb->xformed_by(Transform2D()); // Make a copy.
  1575. Point2 pos = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(mpos);
  1576. mb->set_position(pos);
  1577. Control *mouse_focus = gui.mouse_focus;
  1578. // Disable mouse focus if needed before calling input,
  1579. // this makes popups on mouse press event work better,
  1580. // as the release will never be received otherwise.
  1581. if (gui.mouse_focus_mask.is_empty()) {
  1582. gui.mouse_focus = nullptr;
  1583. }
  1584. if (mouse_focus && mouse_focus->can_process()) {
  1585. _gui_call_input(mouse_focus, mb);
  1586. }
  1587. }
  1588. }
  1589. Ref<InputEventMouseMotion> mm = p_event;
  1590. if (mm.is_valid()) {
  1591. Point2 mpos = mm->get_position();
  1592. // Drag & drop.
  1593. Viewport *section_root = get_section_root_viewport();
  1594. if (!gui.drag_attempted && gui.mouse_focus && section_root && !section_root->gui.global_dragging && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
  1595. gui.drag_accum += mm->get_relative();
  1596. float len = gui.drag_accum.length();
  1597. if (len > 10) {
  1598. { // Attempt grab, try parent controls too.
  1599. CanvasItem *ci = gui.mouse_focus;
  1600. while (ci) {
  1601. Control *control = Object::cast_to<Control>(ci);
  1602. if (control) {
  1603. section_root->gui.global_dragging = true;
  1604. section_root->gui.drag_data = control->get_drag_data(control->get_global_transform_with_canvas().affine_inverse().xform(mpos - gui.drag_accum));
  1605. if (section_root->gui.drag_data.get_type() != Variant::NIL) {
  1606. gui.mouse_focus = nullptr;
  1607. gui.mouse_focus_mask.clear();
  1608. gui.dragging = true;
  1609. break;
  1610. } else {
  1611. Control *drag_preview = _gui_get_drag_preview();
  1612. if (drag_preview) {
  1613. ERR_PRINT("Don't set a drag preview and return null data. Preview was deleted and drag request ignored.");
  1614. memdelete(drag_preview);
  1615. gui.drag_preview_id = ObjectID();
  1616. }
  1617. section_root->gui.global_dragging = false;
  1618. }
  1619. if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
  1620. break;
  1621. }
  1622. }
  1623. if (ci->is_set_as_top_level()) {
  1624. break;
  1625. }
  1626. ci = ci->get_parent_item();
  1627. }
  1628. }
  1629. gui.drag_attempted = true;
  1630. if (gui.dragging) {
  1631. Viewport::_propagate_drag_notification(section_root, NOTIFICATION_DRAG_BEGIN);
  1632. }
  1633. }
  1634. }
  1635. Control *over = nullptr;
  1636. if (gui.mouse_focus) {
  1637. over = gui.mouse_focus;
  1638. } else if (gui.mouse_in_viewport) {
  1639. over = gui_find_control(mpos);
  1640. }
  1641. DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)Input::get_singleton()->get_default_cursor_shape();
  1642. if (over) {
  1643. Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse();
  1644. Size2 pos = localizer.xform(mpos);
  1645. Vector2 velocity = localizer.basis_xform(mm->get_velocity());
  1646. Vector2 rel = localizer.basis_xform(mm->get_relative());
  1647. mm = mm->xformed_by(Transform2D()); // Make a copy.
  1648. mm->set_global_position(mpos);
  1649. mm->set_velocity(velocity);
  1650. mm->set_relative(rel);
  1651. // Nothing pressed.
  1652. if (mm->get_button_mask().is_empty()) {
  1653. bool is_tooltip_shown = false;
  1654. if (gui.tooltip_popup) {
  1655. if (gui.tooltip_control) {
  1656. String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform_with_canvas().affine_inverse().xform(mpos));
  1657. tooltip = tooltip.strip_edges();
  1658. if (tooltip != gui.tooltip_text) {
  1659. _gui_cancel_tooltip();
  1660. } else {
  1661. is_tooltip_shown = true;
  1662. }
  1663. } else {
  1664. _gui_cancel_tooltip();
  1665. }
  1666. }
  1667. // Reset the timer if the mouse has moved more than 5 pixels or has entered a new control.
  1668. if (!is_tooltip_shown && over->can_process()) {
  1669. Vector2 new_tooltip_pos = over->get_screen_transform().xform(pos);
  1670. if (over != gui.tooltip_control || gui.tooltip_pos.distance_squared_to(new_tooltip_pos) > 25) {
  1671. if (gui.tooltip_timer.is_valid()) {
  1672. gui.tooltip_timer->release_connections();
  1673. }
  1674. gui.tooltip_control = over;
  1675. gui.tooltip_pos = new_tooltip_pos;
  1676. gui.tooltip_timer = get_tree()->create_timer(gui.tooltip_delay);
  1677. gui.tooltip_timer->set_ignore_time_scale(true);
  1678. gui.tooltip_timer->connect("timeout", callable_mp(this, &Viewport::_gui_show_tooltip));
  1679. }
  1680. }
  1681. }
  1682. mm->set_position(pos);
  1683. Control::CursorShape cursor_shape = Control::CURSOR_ARROW;
  1684. {
  1685. Control *c = over;
  1686. Vector2 cpos = pos;
  1687. while (c) {
  1688. if (!gui.mouse_focus_mask.is_empty() || c->has_point(cpos)) {
  1689. cursor_shape = c->get_cursor_shape(cpos);
  1690. } else {
  1691. cursor_shape = Control::CURSOR_ARROW;
  1692. }
  1693. cpos = c->get_transform().xform(cpos);
  1694. if (cursor_shape != Control::CURSOR_ARROW) {
  1695. break;
  1696. }
  1697. if (c->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
  1698. break;
  1699. }
  1700. if (c->is_set_as_top_level()) {
  1701. break;
  1702. }
  1703. c = c->get_parent_control();
  1704. }
  1705. }
  1706. ds_cursor_shape = (DisplayServer::CursorShape)cursor_shape;
  1707. if (over->can_process()) {
  1708. _gui_call_input(over, mm);
  1709. }
  1710. }
  1711. if (gui.dragging) {
  1712. // Handle drag & drop. This happens in the viewport where dragging started.
  1713. Control *drag_preview = _gui_get_drag_preview();
  1714. if (drag_preview) {
  1715. Vector2 pos = drag_preview->get_canvas_transform().affine_inverse().xform(mpos);
  1716. drag_preview->set_position(pos);
  1717. }
  1718. gui.drag_mouse_over = section_root->gui.target_control;
  1719. if (gui.drag_mouse_over) {
  1720. if (!_gui_drop(gui.drag_mouse_over, gui.drag_mouse_over->get_local_mouse_position(), true)) {
  1721. gui.drag_mouse_over = nullptr;
  1722. }
  1723. if (gui.drag_mouse_over) {
  1724. ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP;
  1725. } else {
  1726. ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN;
  1727. }
  1728. }
  1729. }
  1730. if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE) && (gui.dragging || (!section_root->gui.global_dragging && !Object::cast_to<SubViewportContainer>(over)))) {
  1731. // If dragging is active, then set the cursor shape only from the Viewport where dragging started.
  1732. // If dragging is inactive, then set the cursor shape only when not over a SubViewportContainer.
  1733. DisplayServer::get_singleton()->cursor_set_shape(ds_cursor_shape);
  1734. }
  1735. }
  1736. Ref<InputEventScreenTouch> touch_event = p_event;
  1737. if (touch_event.is_valid()) {
  1738. Size2 pos = touch_event->get_position();
  1739. const int touch_index = touch_event->get_index();
  1740. if (touch_event->is_pressed()) {
  1741. Control *over = gui_find_control(pos);
  1742. if (over) {
  1743. gui.touch_focus[touch_index] = over->get_instance_id();
  1744. if (over->can_process()) {
  1745. touch_event = touch_event->xformed_by(Transform2D()); // Make a copy.
  1746. pos = over->get_global_transform_with_canvas().affine_inverse().xform(pos);
  1747. touch_event->set_position(pos);
  1748. _gui_call_input(over, touch_event);
  1749. }
  1750. return;
  1751. }
  1752. } else {
  1753. ObjectID control_id = gui.touch_focus[touch_index];
  1754. Control *over = control_id.is_valid() ? Object::cast_to<Control>(ObjectDB::get_instance(control_id)) : nullptr;
  1755. if (over && over->can_process()) {
  1756. touch_event = touch_event->xformed_by(Transform2D()); // Make a copy.
  1757. pos = over->get_global_transform_with_canvas().affine_inverse().xform(pos);
  1758. touch_event->set_position(pos);
  1759. _gui_call_input(over, touch_event);
  1760. }
  1761. gui.touch_focus.erase(touch_index);
  1762. return;
  1763. }
  1764. }
  1765. Ref<InputEventGesture> gesture_event = p_event;
  1766. if (gesture_event.is_valid()) {
  1767. _gui_cancel_tooltip();
  1768. Size2 pos = gesture_event->get_position();
  1769. Control *over = gui_find_control(pos);
  1770. if (over) {
  1771. if (over->can_process()) {
  1772. gesture_event = gesture_event->xformed_by(Transform2D()); // Make a copy.
  1773. pos = over->get_global_transform_with_canvas().affine_inverse().xform(pos);
  1774. gesture_event->set_position(pos);
  1775. _gui_call_input(over, gesture_event);
  1776. }
  1777. return;
  1778. }
  1779. }
  1780. Ref<InputEventScreenDrag> drag_event = p_event;
  1781. if (drag_event.is_valid()) {
  1782. const int drag_event_index = drag_event->get_index();
  1783. ObjectID control_id = gui.touch_focus[drag_event_index];
  1784. Control *over = control_id.is_valid() ? Object::cast_to<Control>(ObjectDB::get_instance(control_id)) : nullptr;
  1785. if (!over) {
  1786. over = gui_find_control(drag_event->get_position());
  1787. }
  1788. if (over) {
  1789. if (over->can_process()) {
  1790. Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse();
  1791. Size2 pos = localizer.xform(drag_event->get_position());
  1792. Vector2 velocity = localizer.basis_xform(drag_event->get_velocity());
  1793. Vector2 rel = localizer.basis_xform(drag_event->get_relative());
  1794. drag_event = drag_event->xformed_by(Transform2D()); // Make a copy.
  1795. drag_event->set_velocity(velocity);
  1796. drag_event->set_relative(rel);
  1797. drag_event->set_position(pos);
  1798. _gui_call_input(over, drag_event);
  1799. }
  1800. return;
  1801. }
  1802. }
  1803. if (mm.is_null() && mb.is_null() && p_event->is_action_type()) {
  1804. if (gui.dragging && p_event->is_action_pressed(SNAME("ui_cancel")) && Input::get_singleton()->is_action_just_pressed(SNAME("ui_cancel"))) {
  1805. _perform_drop();
  1806. set_input_as_handled();
  1807. return;
  1808. }
  1809. if (p_event->is_action_pressed(SNAME("ui_cancel"))) {
  1810. // Cancel tooltip timer or hide tooltip when pressing Escape (this is standard behavior in most applications).
  1811. _gui_cancel_tooltip();
  1812. if (gui.tooltip_popup) {
  1813. // If a tooltip was hidden, prevent other actions associated with `ui_cancel` from occurring.
  1814. // For instance, this prevents the node from being deselected when pressing Escape
  1815. // to hide a documentation tooltip in the inspector.
  1816. set_input_as_handled();
  1817. return;
  1818. }
  1819. }
  1820. if (gui.key_focus && !gui.key_focus->is_visible_in_tree()) {
  1821. gui.key_focus->release_focus();
  1822. }
  1823. if (gui.key_focus) {
  1824. if (gui.key_focus->can_process()) {
  1825. gui.key_focus->_call_gui_input(p_event);
  1826. }
  1827. if (is_input_handled()) {
  1828. return;
  1829. }
  1830. }
  1831. Control *from = gui.key_focus ? gui.key_focus : nullptr;
  1832. if (from && p_event->is_pressed()) {
  1833. Control *next = nullptr;
  1834. Ref<InputEventJoypadMotion> joypadmotion_event = p_event;
  1835. if (joypadmotion_event.is_valid()) {
  1836. Input *input = Input::get_singleton();
  1837. if (p_event->is_action_pressed(SNAME("ui_focus_next")) && input->is_action_just_pressed(SNAME("ui_focus_next"))) {
  1838. next = from->find_next_valid_focus();
  1839. }
  1840. if (p_event->is_action_pressed(SNAME("ui_focus_prev")) && input->is_action_just_pressed(SNAME("ui_focus_prev"))) {
  1841. next = from->find_prev_valid_focus();
  1842. }
  1843. if (p_event->is_action_pressed(SNAME("ui_up")) && input->is_action_just_pressed(SNAME("ui_up"))) {
  1844. next = from->_get_focus_neighbor(SIDE_TOP);
  1845. }
  1846. if (p_event->is_action_pressed(SNAME("ui_left")) && input->is_action_just_pressed(SNAME("ui_left"))) {
  1847. next = from->_get_focus_neighbor(SIDE_LEFT);
  1848. }
  1849. if (p_event->is_action_pressed(SNAME("ui_right")) && input->is_action_just_pressed(SNAME("ui_right"))) {
  1850. next = from->_get_focus_neighbor(SIDE_RIGHT);
  1851. }
  1852. if (p_event->is_action_pressed(SNAME("ui_down")) && input->is_action_just_pressed(SNAME("ui_down"))) {
  1853. next = from->_get_focus_neighbor(SIDE_BOTTOM);
  1854. }
  1855. } else {
  1856. if (p_event->is_action_pressed(SNAME("ui_focus_next"), true, true)) {
  1857. next = from->find_next_valid_focus();
  1858. }
  1859. if (p_event->is_action_pressed(SNAME("ui_focus_prev"), true, true)) {
  1860. next = from->find_prev_valid_focus();
  1861. }
  1862. if (p_event->is_action_pressed(SNAME("ui_up"), true, true)) {
  1863. next = from->_get_focus_neighbor(SIDE_TOP);
  1864. }
  1865. if (p_event->is_action_pressed(SNAME("ui_left"), true, true)) {
  1866. next = from->_get_focus_neighbor(SIDE_LEFT);
  1867. }
  1868. if (p_event->is_action_pressed(SNAME("ui_right"), true, true)) {
  1869. next = from->_get_focus_neighbor(SIDE_RIGHT);
  1870. }
  1871. if (p_event->is_action_pressed(SNAME("ui_down"), true, true)) {
  1872. next = from->_get_focus_neighbor(SIDE_BOTTOM);
  1873. }
  1874. }
  1875. if (next) {
  1876. next->grab_focus();
  1877. set_input_as_handled();
  1878. }
  1879. }
  1880. }
  1881. }
  1882. void Viewport::_perform_drop(Control *p_control) {
  1883. // Without any arguments, simply cancel Drag and Drop.
  1884. if (p_control) {
  1885. gui.drag_successful = _gui_drop(p_control, p_control->get_local_mouse_position(), false);
  1886. } else {
  1887. gui.drag_successful = false;
  1888. }
  1889. Control *drag_preview = _gui_get_drag_preview();
  1890. if (drag_preview) {
  1891. memdelete(drag_preview);
  1892. gui.drag_preview_id = ObjectID();
  1893. }
  1894. Viewport *section_root = get_section_root_viewport();
  1895. section_root->gui.drag_data = Variant();
  1896. gui.dragging = false;
  1897. section_root->gui.global_dragging = false;
  1898. gui.drag_mouse_over = nullptr;
  1899. Viewport::_propagate_drag_notification(section_root, NOTIFICATION_DRAG_END);
  1900. // Display the new cursor shape instantly.
  1901. update_mouse_cursor_state();
  1902. }
  1903. void Viewport::_gui_cleanup_internal_state(Ref<InputEvent> p_event) {
  1904. ERR_FAIL_COND(p_event.is_null());
  1905. Ref<InputEventMouseButton> mb = p_event;
  1906. if (mb.is_valid()) {
  1907. if (!mb->is_pressed()) {
  1908. gui.mouse_focus_mask.clear_flag(mouse_button_to_mask(mb->get_button_index())); // Remove from mask.
  1909. }
  1910. }
  1911. }
  1912. List<Control *>::Element *Viewport::_gui_add_root_control(Control *p_control) {
  1913. gui.roots_order_dirty = true;
  1914. return gui.roots.push_back(p_control);
  1915. }
  1916. void Viewport::gui_set_root_order_dirty() {
  1917. ERR_MAIN_THREAD_GUARD;
  1918. gui.roots_order_dirty = true;
  1919. }
  1920. void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control *p_control) {
  1921. ERR_FAIL_COND_MSG(p_data.get_type() == Variant::NIL, "Drag data must be a value.");
  1922. gui.dragging = true;
  1923. Viewport *section_root = get_section_root_viewport();
  1924. section_root->gui.global_dragging = true;
  1925. section_root->gui.drag_data = p_data;
  1926. gui.mouse_focus = nullptr;
  1927. gui.mouse_focus_mask.clear();
  1928. if (p_control) {
  1929. _gui_set_drag_preview(p_base, p_control);
  1930. }
  1931. Viewport::_propagate_drag_notification(section_root, NOTIFICATION_DRAG_BEGIN);
  1932. }
  1933. void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
  1934. ERR_FAIL_NULL(p_control);
  1935. ERR_FAIL_COND(p_control->is_inside_tree());
  1936. ERR_FAIL_COND(p_control->get_parent() != nullptr);
  1937. Control *drag_preview = _gui_get_drag_preview();
  1938. if (drag_preview) {
  1939. memdelete(drag_preview);
  1940. }
  1941. p_control->set_as_top_level(true);
  1942. p_control->set_position(gui.last_mouse_pos);
  1943. p_base->get_root_parent_control()->add_child(p_control); // Add as child of viewport.
  1944. p_control->move_to_front();
  1945. gui.drag_preview_id = p_control->get_instance_id();
  1946. }
  1947. Control *Viewport::_gui_get_drag_preview() {
  1948. if (gui.drag_preview_id.is_null()) {
  1949. return nullptr;
  1950. } else {
  1951. Control *drag_preview = Object::cast_to<Control>(ObjectDB::get_instance(gui.drag_preview_id));
  1952. if (!drag_preview) {
  1953. ERR_PRINT("Don't free the control set as drag preview.");
  1954. gui.drag_preview_id = ObjectID();
  1955. }
  1956. return drag_preview;
  1957. }
  1958. }
  1959. void Viewport::_gui_remove_root_control(List<Control *>::Element *RI) {
  1960. gui.roots.erase(RI);
  1961. }
  1962. void Viewport::_gui_unfocus_control(Control *p_control) {
  1963. if (gui.key_focus == p_control) {
  1964. gui.key_focus->release_focus();
  1965. }
  1966. }
  1967. void Viewport::_gui_hide_control(Control *p_control) {
  1968. if (gui.mouse_focus == p_control) {
  1969. _drop_mouse_focus();
  1970. }
  1971. if (gui.key_focus == p_control) {
  1972. gui_release_focus();
  1973. }
  1974. if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.has(p_control)) {
  1975. _drop_mouse_over(p_control->get_parent_control());
  1976. }
  1977. if (gui.drag_mouse_over == p_control) {
  1978. gui.drag_mouse_over = nullptr;
  1979. }
  1980. if (gui.tooltip_control == p_control) {
  1981. _gui_cancel_tooltip();
  1982. }
  1983. }
  1984. void Viewport::_gui_remove_control(Control *p_control) {
  1985. if (gui.mouse_focus == p_control) {
  1986. gui.mouse_focus = nullptr;
  1987. gui.mouse_focus_mask.clear();
  1988. }
  1989. if (gui.key_focus == p_control) {
  1990. gui.key_focus = nullptr;
  1991. }
  1992. if (gui.mouse_over == p_control || gui.mouse_over_hierarchy.has(p_control)) {
  1993. _drop_mouse_over(p_control->get_parent_control());
  1994. }
  1995. if (gui.drag_mouse_over == p_control) {
  1996. gui.drag_mouse_over = nullptr;
  1997. }
  1998. if (gui.tooltip_control == p_control) {
  1999. gui.tooltip_control = nullptr;
  2000. }
  2001. }
  2002. void Viewport::canvas_item_top_level_changed() {
  2003. _gui_update_mouse_over();
  2004. }
  2005. void Viewport::_gui_update_mouse_over() {
  2006. if (gui.mouse_over == nullptr || gui.mouse_over_hierarchy.is_empty()) {
  2007. return;
  2008. }
  2009. if (gui.sending_mouse_enter_exit_notifications) {
  2010. // If notifications are already being sent, delay call to next frame.
  2011. if (get_tree() && !get_tree()->is_connected(SNAME("process_frame"), callable_mp(this, &Viewport::_gui_update_mouse_over))) {
  2012. get_tree()->connect(SNAME("process_frame"), callable_mp(this, &Viewport::_gui_update_mouse_over), CONNECT_ONE_SHOT);
  2013. }
  2014. return;
  2015. }
  2016. // Rebuild the mouse over hierarchy.
  2017. LocalVector<Control *> new_mouse_over_hierarchy;
  2018. LocalVector<Control *> needs_enter;
  2019. LocalVector<int> needs_exit;
  2020. CanvasItem *ancestor = gui.mouse_over;
  2021. bool removing = false;
  2022. bool reached_top = false;
  2023. while (ancestor) {
  2024. Control *ancestor_control = Object::cast_to<Control>(ancestor);
  2025. if (ancestor_control) {
  2026. int found = gui.mouse_over_hierarchy.find(ancestor_control);
  2027. if (found >= 0) {
  2028. // Remove the node if the propagation chain has been broken or it is now MOUSE_FILTER_IGNORE.
  2029. if (removing || ancestor_control->get_mouse_filter() == Control::MOUSE_FILTER_IGNORE) {
  2030. needs_exit.push_back(found);
  2031. }
  2032. }
  2033. if (found == 0) {
  2034. if (removing) {
  2035. // Stop if the chain has been broken and the top of the hierarchy has been reached.
  2036. break;
  2037. }
  2038. reached_top = true;
  2039. }
  2040. if (!removing && ancestor_control->get_mouse_filter() != Control::MOUSE_FILTER_IGNORE) {
  2041. new_mouse_over_hierarchy.push_back(ancestor_control);
  2042. // Add the node if it was not found and it is now not MOUSE_FILTER_IGNORE.
  2043. if (found < 0) {
  2044. needs_enter.push_back(ancestor_control);
  2045. }
  2046. }
  2047. if (ancestor_control->get_mouse_filter() == Control::MOUSE_FILTER_STOP) {
  2048. // MOUSE_FILTER_STOP breaks the propagation chain.
  2049. if (reached_top) {
  2050. break;
  2051. }
  2052. removing = true;
  2053. }
  2054. }
  2055. if (ancestor->is_set_as_top_level()) {
  2056. // Top level breaks the propagation chain.
  2057. if (reached_top) {
  2058. break;
  2059. } else {
  2060. removing = true;
  2061. ancestor = Object::cast_to<CanvasItem>(ancestor->get_parent());
  2062. continue;
  2063. }
  2064. }
  2065. ancestor = ancestor->get_parent_item();
  2066. }
  2067. if (needs_exit.is_empty() && needs_enter.is_empty()) {
  2068. return;
  2069. }
  2070. gui.sending_mouse_enter_exit_notifications = true;
  2071. // Send Mouse Exit Self notification.
  2072. if (gui.mouse_over && !needs_exit.is_empty() && needs_exit[0] == (int)gui.mouse_over_hierarchy.size() - 1) {
  2073. gui.mouse_over->notification(Control::NOTIFICATION_MOUSE_EXIT_SELF);
  2074. gui.mouse_over = nullptr;
  2075. }
  2076. // Send Mouse Exit notifications.
  2077. for (int exit_control_index : needs_exit) {
  2078. gui.mouse_over_hierarchy[exit_control_index]->notification(Control::NOTIFICATION_MOUSE_EXIT);
  2079. }
  2080. // Update the mouse over hierarchy.
  2081. gui.mouse_over_hierarchy.resize(new_mouse_over_hierarchy.size());
  2082. for (int i = 0; i < (int)new_mouse_over_hierarchy.size(); i++) {
  2083. gui.mouse_over_hierarchy[i] = new_mouse_over_hierarchy[new_mouse_over_hierarchy.size() - 1 - i];
  2084. }
  2085. // Send Mouse Enter notifications.
  2086. for (int i = needs_enter.size() - 1; i >= 0; i--) {
  2087. needs_enter[i]->notification(Control::NOTIFICATION_MOUSE_ENTER);
  2088. }
  2089. gui.sending_mouse_enter_exit_notifications = false;
  2090. }
  2091. Window *Viewport::get_base_window() {
  2092. ERR_READ_THREAD_GUARD_V(nullptr);
  2093. ERR_FAIL_COND_V(!is_inside_tree(), nullptr);
  2094. Viewport *v = this;
  2095. Window *w = Object::cast_to<Window>(v);
  2096. while (!w) {
  2097. v = v->get_parent_viewport();
  2098. w = Object::cast_to<Window>(v);
  2099. }
  2100. return w;
  2101. }
  2102. void Viewport::_gui_remove_focus_for_window(Node *p_window) {
  2103. if (get_base_window() == p_window) {
  2104. gui_release_focus();
  2105. }
  2106. }
  2107. bool Viewport::_gui_control_has_focus(const Control *p_control) {
  2108. return gui.key_focus == p_control;
  2109. }
  2110. void Viewport::_gui_control_grab_focus(Control *p_control) {
  2111. if (gui.key_focus && gui.key_focus == p_control) {
  2112. // No need for change.
  2113. return;
  2114. }
  2115. get_tree()->call_group("_viewports", "_gui_remove_focus_for_window", get_base_window());
  2116. if (p_control->is_inside_tree() && p_control->get_viewport() == this) {
  2117. gui.key_focus = p_control;
  2118. emit_signal(SNAME("gui_focus_changed"), p_control);
  2119. p_control->notification(Control::NOTIFICATION_FOCUS_ENTER);
  2120. p_control->queue_redraw();
  2121. }
  2122. }
  2123. void Viewport::_gui_accept_event() {
  2124. if (is_inside_tree()) {
  2125. set_input_as_handled();
  2126. }
  2127. }
  2128. void Viewport::_drop_mouse_focus() {
  2129. Control *c = gui.mouse_focus;
  2130. BitField<MouseButtonMask> mask = gui.mouse_focus_mask;
  2131. gui.mouse_focus = nullptr;
  2132. gui.mouse_focus_mask.clear();
  2133. if (!c) {
  2134. return;
  2135. }
  2136. for (int i = 0; i < 3; i++) {
  2137. if ((int)mask & (1 << i)) {
  2138. Ref<InputEventMouseButton> mb;
  2139. mb.instantiate();
  2140. mb->set_position(c->get_local_mouse_position());
  2141. mb->set_global_position(c->get_local_mouse_position());
  2142. mb->set_button_index(MouseButton(i + 1));
  2143. mb->set_pressed(false);
  2144. mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
  2145. c->_call_gui_input(mb);
  2146. }
  2147. }
  2148. }
  2149. void Viewport::_drop_physics_mouseover(bool p_paused_only) {
  2150. _cleanup_mouseover_colliders(true, p_paused_only);
  2151. #ifndef _3D_DISABLED
  2152. if (physics_object_over.is_valid()) {
  2153. CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
  2154. if (co) {
  2155. if (!co->is_inside_tree()) {
  2156. physics_object_over = ObjectID();
  2157. physics_object_capture = ObjectID();
  2158. } else if (!(p_paused_only && co->can_process())) {
  2159. co->_mouse_exit();
  2160. physics_object_over = ObjectID();
  2161. physics_object_capture = ObjectID();
  2162. }
  2163. }
  2164. }
  2165. #endif // _3D_DISABLED
  2166. }
  2167. void Viewport::_gui_grab_click_focus(Control *p_control) {
  2168. gui.mouse_click_grabber = p_control;
  2169. callable_mp(this, &Viewport::_post_gui_grab_click_focus).call_deferred();
  2170. }
  2171. void Viewport::_post_gui_grab_click_focus() {
  2172. Control *focus_grabber = gui.mouse_click_grabber;
  2173. if (!focus_grabber) {
  2174. // Redundant grab requests were made.
  2175. return;
  2176. }
  2177. gui.mouse_click_grabber = nullptr;
  2178. if (gui.mouse_focus) {
  2179. if (gui.mouse_focus == focus_grabber) {
  2180. return;
  2181. }
  2182. BitField<MouseButtonMask> mask = gui.mouse_focus_mask;
  2183. Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
  2184. for (int i = 0; i < 3; i++) {
  2185. if ((int)mask & (1 << i)) {
  2186. Ref<InputEventMouseButton> mb;
  2187. mb.instantiate();
  2188. // Send unclick.
  2189. mb->set_position(click);
  2190. mb->set_button_index(MouseButton(i + 1));
  2191. mb->set_pressed(false);
  2192. mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
  2193. gui.mouse_focus->_call_gui_input(mb);
  2194. }
  2195. }
  2196. gui.mouse_focus = focus_grabber;
  2197. click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
  2198. for (int i = 0; i < 3; i++) {
  2199. if ((int)mask & (1 << i)) {
  2200. Ref<InputEventMouseButton> mb;
  2201. mb.instantiate();
  2202. // Send click.
  2203. mb->set_position(click);
  2204. mb->set_button_index(MouseButton(i + 1));
  2205. mb->set_pressed(true);
  2206. mb->set_device(InputEvent::DEVICE_ID_INTERNAL);
  2207. callable_mp(gui.mouse_focus, &Control::_call_gui_input).call_deferred(mb);
  2208. }
  2209. }
  2210. }
  2211. }
  2212. ///////////////////////////////
  2213. void Viewport::push_text_input(const String &p_text) {
  2214. ERR_MAIN_THREAD_GUARD;
  2215. if (gui.subwindow_focused) {
  2216. gui.subwindow_focused->push_text_input(p_text);
  2217. return;
  2218. }
  2219. if (gui.key_focus) {
  2220. gui.key_focus->call("set_text", p_text);
  2221. }
  2222. }
  2223. Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point) {
  2224. if (p_subwindow->get_flag(Window::FLAG_BORDERLESS) || p_subwindow->get_flag(Window::FLAG_RESIZE_DISABLED)) {
  2225. return SUB_WINDOW_RESIZE_DISABLED;
  2226. }
  2227. Rect2i r = Rect2i(p_subwindow->get_position(), p_subwindow->get_size());
  2228. int title_height = p_subwindow->theme_cache.title_height;
  2229. r.position.y -= title_height;
  2230. r.size.y += title_height;
  2231. if (r.has_point(p_point)) {
  2232. return SUB_WINDOW_RESIZE_DISABLED; // It's inside, so no resize.
  2233. }
  2234. int dist_x = p_point.x < r.position.x ? (p_point.x - r.position.x) : (p_point.x > (r.position.x + r.size.x) ? (p_point.x - (r.position.x + r.size.x)) : 0);
  2235. int dist_y = p_point.y < r.position.y ? (p_point.y - r.position.y) : (p_point.y > (r.position.y + r.size.y) ? (p_point.y - (r.position.y + r.size.y)) : 0);
  2236. int limit = p_subwindow->theme_cache.resize_margin;
  2237. if (ABS(dist_x) > limit) {
  2238. return SUB_WINDOW_RESIZE_DISABLED;
  2239. }
  2240. if (ABS(dist_y) > limit) {
  2241. return SUB_WINDOW_RESIZE_DISABLED;
  2242. }
  2243. if (dist_x < 0 && dist_y < 0) {
  2244. return SUB_WINDOW_RESIZE_TOP_LEFT;
  2245. }
  2246. if (dist_x == 0 && dist_y < 0) {
  2247. return SUB_WINDOW_RESIZE_TOP;
  2248. }
  2249. if (dist_x > 0 && dist_y < 0) {
  2250. return SUB_WINDOW_RESIZE_TOP_RIGHT;
  2251. }
  2252. if (dist_x < 0 && dist_y == 0) {
  2253. return SUB_WINDOW_RESIZE_LEFT;
  2254. }
  2255. if (dist_x > 0 && dist_y == 0) {
  2256. return SUB_WINDOW_RESIZE_RIGHT;
  2257. }
  2258. if (dist_x < 0 && dist_y > 0) {
  2259. return SUB_WINDOW_RESIZE_BOTTOM_LEFT;
  2260. }
  2261. if (dist_x == 0 && dist_y > 0) {
  2262. return SUB_WINDOW_RESIZE_BOTTOM;
  2263. }
  2264. if (dist_x > 0 && dist_y > 0) {
  2265. return SUB_WINDOW_RESIZE_BOTTOM_RIGHT;
  2266. }
  2267. return SUB_WINDOW_RESIZE_DISABLED;
  2268. }
  2269. bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
  2270. if (gui.subwindow_drag != SUB_WINDOW_DRAG_DISABLED) {
  2271. ERR_FAIL_NULL_V(gui.currently_dragged_subwindow, false);
  2272. Ref<InputEventMouseButton> mb = p_event;
  2273. if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
  2274. if (gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE) {
  2275. if (gui.subwindow_drag_close_rect.has_point(mb->get_position())) {
  2276. // Close window.
  2277. gui.currently_dragged_subwindow->_event_callback(DisplayServer::WINDOW_EVENT_CLOSE_REQUEST);
  2278. }
  2279. }
  2280. gui.subwindow_drag = SUB_WINDOW_DRAG_DISABLED;
  2281. if (gui.currently_dragged_subwindow != nullptr) { // May have been erased.
  2282. _sub_window_update(gui.currently_dragged_subwindow);
  2283. gui.currently_dragged_subwindow = nullptr;
  2284. }
  2285. }
  2286. Ref<InputEventMouseMotion> mm = p_event;
  2287. if (mm.is_valid()) {
  2288. if (gui.subwindow_drag == SUB_WINDOW_DRAG_MOVE) {
  2289. Vector2 diff = mm->get_position() - gui.subwindow_drag_from;
  2290. Rect2i new_rect(gui.subwindow_drag_pos + diff, gui.currently_dragged_subwindow->get_size());
  2291. if (gui.currently_dragged_subwindow->is_clamped_to_embedder()) {
  2292. new_rect = gui.currently_dragged_subwindow->fit_rect_in_parent(new_rect, get_visible_rect());
  2293. }
  2294. gui.currently_dragged_subwindow->_rect_changed_callback(new_rect);
  2295. if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE)) {
  2296. DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_MOVE);
  2297. }
  2298. }
  2299. if (gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE) {
  2300. gui.subwindow_drag_close_inside = gui.subwindow_drag_close_rect.has_point(mm->get_position());
  2301. }
  2302. if (gui.subwindow_drag == SUB_WINDOW_DRAG_RESIZE) {
  2303. Vector2i diff = mm->get_position() - gui.subwindow_drag_from;
  2304. Size2i min_size = gui.currently_dragged_subwindow->get_min_size();
  2305. Size2i min_size_clamped = gui.currently_dragged_subwindow->get_clamped_minimum_size();
  2306. min_size_clamped = min_size_clamped.maxi(1);
  2307. Rect2i r = gui.subwindow_resize_from_rect;
  2308. Size2i limit = r.size - min_size_clamped;
  2309. switch (gui.subwindow_resize_mode) {
  2310. case SUB_WINDOW_RESIZE_TOP_LEFT: {
  2311. diff.x = MIN(diff.x, limit.x);
  2312. diff.y = MIN(diff.y, limit.y);
  2313. r.position += diff;
  2314. r.size -= diff;
  2315. } break;
  2316. case SUB_WINDOW_RESIZE_TOP: {
  2317. diff.x = 0;
  2318. diff.y = MIN(diff.y, limit.y);
  2319. r.position += diff;
  2320. r.size -= diff;
  2321. } break;
  2322. case SUB_WINDOW_RESIZE_TOP_RIGHT: {
  2323. diff.x = MAX(diff.x, -limit.x);
  2324. diff.y = MIN(diff.y, limit.y);
  2325. r.position.y += diff.y;
  2326. r.size.y -= diff.y;
  2327. r.size.x += diff.x;
  2328. } break;
  2329. case SUB_WINDOW_RESIZE_LEFT: {
  2330. diff.x = MIN(diff.x, limit.x);
  2331. diff.y = 0;
  2332. r.position += diff;
  2333. r.size -= diff;
  2334. } break;
  2335. case SUB_WINDOW_RESIZE_RIGHT: {
  2336. diff.x = MAX(diff.x, -limit.x);
  2337. r.size.x += diff.x;
  2338. } break;
  2339. case SUB_WINDOW_RESIZE_BOTTOM_LEFT: {
  2340. diff.x = MIN(diff.x, limit.x);
  2341. diff.y = MAX(diff.y, -limit.y);
  2342. r.position.x += diff.x;
  2343. r.size.x -= diff.x;
  2344. r.size.y += diff.y;
  2345. } break;
  2346. case SUB_WINDOW_RESIZE_BOTTOM: {
  2347. diff.y = MAX(diff.y, -limit.y);
  2348. r.size.y += diff.y;
  2349. } break;
  2350. case SUB_WINDOW_RESIZE_BOTTOM_RIGHT: {
  2351. diff.x = MAX(diff.x, -limit.x);
  2352. diff.y = MAX(diff.y, -limit.y);
  2353. r.size += diff;
  2354. } break;
  2355. default: {
  2356. }
  2357. }
  2358. Size2i max_size = gui.currently_dragged_subwindow->get_max_size();
  2359. if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) {
  2360. max_size = max_size.maxi(1);
  2361. if (r.size.x > max_size.x) {
  2362. r.size.x = max_size.x;
  2363. }
  2364. if (r.size.y > max_size.y) {
  2365. r.size.y = max_size.y;
  2366. }
  2367. }
  2368. gui.currently_dragged_subwindow->_rect_changed_callback(r);
  2369. }
  2370. if (gui.currently_dragged_subwindow) { // May have been erased.
  2371. _sub_window_update(gui.currently_dragged_subwindow);
  2372. }
  2373. }
  2374. return true; // Handled.
  2375. }
  2376. Ref<InputEventMouseButton> mb = p_event;
  2377. // If the event is a mouse button, we need to check whether another window was clicked.
  2378. if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
  2379. Window *click_on_window = nullptr;
  2380. for (int i = gui.sub_windows.size() - 1; i >= 0; i--) {
  2381. SubWindow sw = gui.sub_windows.write[i];
  2382. // Clicked inside window?
  2383. Rect2i r = Rect2i(sw.window->get_position(), sw.window->get_size());
  2384. if (!sw.window->get_flag(Window::FLAG_BORDERLESS)) {
  2385. // Check top bar.
  2386. int title_height = sw.window->theme_cache.title_height;
  2387. Rect2i title_bar = r;
  2388. title_bar.position.y -= title_height;
  2389. title_bar.size.y = title_height;
  2390. if (title_bar.size.y > 0 && title_bar.has_point(mb->get_position())) {
  2391. click_on_window = sw.window;
  2392. int close_h_ofs = sw.window->theme_cache.close_h_offset;
  2393. int close_v_ofs = sw.window->theme_cache.close_v_offset;
  2394. Ref<Texture2D> close_icon = sw.window->theme_cache.close;
  2395. Rect2 close_rect;
  2396. close_rect.position = Vector2(r.position.x + r.size.x - close_h_ofs, r.position.y - close_v_ofs);
  2397. close_rect.size = close_icon->get_size();
  2398. if (gui.subwindow_focused != sw.window) {
  2399. // Refocus.
  2400. _sub_window_grab_focus(sw.window);
  2401. }
  2402. if (close_rect.has_point(mb->get_position())) {
  2403. gui.subwindow_drag = SUB_WINDOW_DRAG_CLOSE;
  2404. gui.subwindow_drag_close_inside = true; // Starts inside.
  2405. gui.subwindow_drag_close_rect = close_rect;
  2406. } else {
  2407. gui.subwindow_drag = SUB_WINDOW_DRAG_MOVE;
  2408. }
  2409. gui.subwindow_drag_from = mb->get_position();
  2410. gui.subwindow_drag_pos = sw.window->get_position();
  2411. _sub_window_update(sw.window);
  2412. } else {
  2413. gui.subwindow_resize_mode = _sub_window_get_resize_margin(sw.window, mb->get_position());
  2414. if (gui.subwindow_resize_mode != SUB_WINDOW_RESIZE_DISABLED) {
  2415. if (gui.subwindow_focused != sw.window) {
  2416. // Refocus.
  2417. _sub_window_grab_focus(sw.window);
  2418. }
  2419. gui.subwindow_resize_from_rect = r;
  2420. gui.subwindow_drag_from = mb->get_position();
  2421. gui.subwindow_drag = SUB_WINDOW_DRAG_RESIZE;
  2422. click_on_window = sw.window;
  2423. }
  2424. }
  2425. }
  2426. if (!click_on_window && r.has_point(mb->get_position())) {
  2427. // Clicked, see if it needs to fetch focus.
  2428. if (gui.subwindow_focused != sw.window) {
  2429. // Refocus.
  2430. _sub_window_grab_focus(sw.window);
  2431. }
  2432. click_on_window = sw.window;
  2433. }
  2434. if (click_on_window) {
  2435. break;
  2436. }
  2437. }
  2438. gui.currently_dragged_subwindow = click_on_window;
  2439. if (!click_on_window && gui.subwindow_focused) {
  2440. // No window found and clicked, remove focus.
  2441. _sub_window_grab_focus(nullptr);
  2442. }
  2443. }
  2444. if (gui.subwindow_focused) {
  2445. Ref<InputEventMouseMotion> mm = p_event;
  2446. if (mm.is_valid()) {
  2447. SubWindowResize resize = _sub_window_get_resize_margin(gui.subwindow_focused, mm->get_position());
  2448. if (resize != SUB_WINDOW_RESIZE_DISABLED) {
  2449. DisplayServer::CursorShape shapes[SUB_WINDOW_RESIZE_MAX] = {
  2450. DisplayServer::CURSOR_ARROW,
  2451. DisplayServer::CURSOR_FDIAGSIZE,
  2452. DisplayServer::CURSOR_VSIZE,
  2453. DisplayServer::CURSOR_BDIAGSIZE,
  2454. DisplayServer::CURSOR_HSIZE,
  2455. DisplayServer::CURSOR_HSIZE,
  2456. DisplayServer::CURSOR_BDIAGSIZE,
  2457. DisplayServer::CURSOR_VSIZE,
  2458. DisplayServer::CURSOR_FDIAGSIZE
  2459. };
  2460. if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE)) {
  2461. DisplayServer::get_singleton()->cursor_set_shape(shapes[resize]);
  2462. }
  2463. return true; // Reserved for showing the resize cursor.
  2464. }
  2465. }
  2466. }
  2467. if (gui.subwindow_drag != SUB_WINDOW_DRAG_DISABLED) {
  2468. return true; // Dragging, don't pass the event.
  2469. }
  2470. if (!gui.subwindow_focused) {
  2471. return false;
  2472. }
  2473. Transform2D window_ofs;
  2474. window_ofs.set_origin(-gui.subwindow_focused->get_position());
  2475. Ref<InputEvent> ev = p_event->xformed_by(window_ofs);
  2476. gui.subwindow_focused->_window_input(ev);
  2477. return true;
  2478. }
  2479. void Viewport::_window_start_drag(Window *p_window) {
  2480. int index = _sub_window_find(p_window);
  2481. ERR_FAIL_COND(index == -1);
  2482. SubWindow sw = gui.sub_windows.write[index];
  2483. if (gui.subwindow_focused != sw.window) {
  2484. // Refocus.
  2485. _sub_window_grab_focus(sw.window);
  2486. }
  2487. gui.subwindow_drag = SUB_WINDOW_DRAG_MOVE;
  2488. gui.subwindow_drag_from = get_mouse_position();
  2489. gui.subwindow_drag_pos = sw.window->get_position();
  2490. gui.currently_dragged_subwindow = sw.window;
  2491. _sub_window_update(sw.window);
  2492. }
  2493. void Viewport::_window_start_resize(SubWindowResize p_edge, Window *p_window) {
  2494. int index = _sub_window_find(p_window);
  2495. ERR_FAIL_COND(index == -1);
  2496. SubWindow sw = gui.sub_windows.write[index];
  2497. Rect2i r = Rect2i(sw.window->get_position(), sw.window->get_size());
  2498. if (gui.subwindow_focused != sw.window) {
  2499. // Refocus.
  2500. _sub_window_grab_focus(sw.window);
  2501. }
  2502. gui.subwindow_drag = SUB_WINDOW_DRAG_RESIZE;
  2503. gui.subwindow_resize_mode = p_edge;
  2504. gui.subwindow_resize_from_rect = r;
  2505. gui.subwindow_drag_from = get_mouse_position();
  2506. gui.subwindow_drag_pos = sw.window->get_position();
  2507. gui.currently_dragged_subwindow = sw.window;
  2508. _sub_window_update(sw.window);
  2509. }
  2510. void Viewport::_update_mouse_over() {
  2511. // Update gui.mouse_over and gui.subwindow_over in all Viewports.
  2512. // Send necessary mouse_enter/mouse_exit signals and the MOUSE_ENTER/MOUSE_EXIT notifications for every Viewport in the SceneTree.
  2513. if (is_attached_in_viewport()) {
  2514. // Execute this function only, when it is processed by a native Window or a SubViewport, that has no SubViewportContainer as parent.
  2515. return;
  2516. }
  2517. if (get_tree()->get_root()->is_embedding_subwindows() || is_sub_viewport()) {
  2518. // Use embedder logic for calculating mouse position.
  2519. _update_mouse_over(gui.last_mouse_pos);
  2520. } else {
  2521. // Native Window: Use DisplayServer logic for calculating mouse position.
  2522. Window *receiving_window = get_tree()->get_root()->gui.windowmanager_window_over;
  2523. if (!receiving_window) {
  2524. return;
  2525. }
  2526. Vector2 pos = DisplayServer::get_singleton()->mouse_get_position() - receiving_window->get_position();
  2527. pos = receiving_window->get_final_transform().affine_inverse().xform(pos);
  2528. receiving_window->_update_mouse_over(pos);
  2529. }
  2530. }
  2531. void Viewport::_update_mouse_over(Vector2 p_pos) {
  2532. gui.last_mouse_pos = p_pos; // Necessary, because mouse cursor can be over Viewports that are not reached by the InputEvent.
  2533. // Look for embedded windows at mouse position.
  2534. if (is_embedding_subwindows()) {
  2535. for (int i = gui.sub_windows.size() - 1; i >= 0; i--) {
  2536. Window *sw = gui.sub_windows[i].window;
  2537. Rect2 swrect = Rect2(sw->get_position(), sw->get_size());
  2538. Rect2 swrect_border = swrect;
  2539. if (!sw->get_flag(Window::FLAG_BORDERLESS)) {
  2540. int title_height = sw->theme_cache.title_height;
  2541. int margin = sw->theme_cache.resize_margin;
  2542. swrect_border.position.y -= title_height + margin;
  2543. swrect_border.size.y += title_height + margin * 2;
  2544. swrect_border.position.x -= margin;
  2545. swrect_border.size.x += margin * 2;
  2546. }
  2547. if (swrect_border.has_point(p_pos)) {
  2548. if (gui.mouse_over) {
  2549. _drop_mouse_over();
  2550. } else if (!gui.subwindow_over) {
  2551. _drop_physics_mouseover();
  2552. }
  2553. if (swrect.has_point(p_pos)) {
  2554. if (sw != gui.subwindow_over) {
  2555. if (gui.subwindow_over) {
  2556. gui.subwindow_over->_mouse_leave_viewport();
  2557. }
  2558. gui.subwindow_over = sw;
  2559. }
  2560. if (!sw->is_input_disabled()) {
  2561. sw->_update_mouse_over(sw->get_final_transform().affine_inverse().xform(p_pos - sw->get_position()));
  2562. }
  2563. } else {
  2564. if (gui.subwindow_over) {
  2565. gui.subwindow_over->_mouse_leave_viewport();
  2566. gui.subwindow_over = nullptr;
  2567. }
  2568. }
  2569. return;
  2570. }
  2571. }
  2572. if (gui.subwindow_over) {
  2573. // Take care of moving mouse out of any embedded Window.
  2574. gui.subwindow_over->_mouse_leave_viewport();
  2575. gui.subwindow_over = nullptr;
  2576. }
  2577. }
  2578. // Look for Controls at mouse position.
  2579. Control *over = gui_find_control(p_pos);
  2580. get_section_root_viewport()->gui.target_control = over;
  2581. bool notify_embedded_viewports = false;
  2582. if (over != gui.mouse_over || (!over && !gui.mouse_over_hierarchy.is_empty())) {
  2583. // Find the common ancestor of `gui.mouse_over` and `over`.
  2584. Control *common_ancestor = nullptr;
  2585. LocalVector<Control *> over_ancestors;
  2586. if (over) {
  2587. // Get all ancestors that the mouse is currently over and need an enter signal.
  2588. CanvasItem *ancestor = over;
  2589. while (ancestor) {
  2590. Control *ancestor_control = Object::cast_to<Control>(ancestor);
  2591. if (ancestor_control) {
  2592. if (ancestor_control->get_mouse_filter() != Control::MOUSE_FILTER_IGNORE) {
  2593. int found = gui.mouse_over_hierarchy.find(ancestor_control);
  2594. if (found >= 0) {
  2595. common_ancestor = gui.mouse_over_hierarchy[found];
  2596. break;
  2597. }
  2598. over_ancestors.push_back(ancestor_control);
  2599. }
  2600. if (ancestor_control->get_mouse_filter() == Control::MOUSE_FILTER_STOP) {
  2601. // MOUSE_FILTER_STOP breaks the propagation chain.
  2602. break;
  2603. }
  2604. }
  2605. if (ancestor->is_set_as_top_level()) {
  2606. // Top level breaks the propagation chain.
  2607. break;
  2608. }
  2609. ancestor = ancestor->get_parent_item();
  2610. }
  2611. }
  2612. if (gui.mouse_over || !gui.mouse_over_hierarchy.is_empty()) {
  2613. // Send Mouse Exit Self and Mouse Exit notifications.
  2614. _drop_mouse_over(common_ancestor);
  2615. } else {
  2616. _drop_physics_mouseover();
  2617. }
  2618. if (over) {
  2619. gui.mouse_over = over;
  2620. gui.mouse_over_hierarchy.reserve(gui.mouse_over_hierarchy.size() + over_ancestors.size());
  2621. gui.sending_mouse_enter_exit_notifications = true;
  2622. // Send Mouse Enter notifications to parents first.
  2623. for (int i = over_ancestors.size() - 1; i >= 0; i--) {
  2624. gui.mouse_over_hierarchy.push_back(over_ancestors[i]);
  2625. over_ancestors[i]->notification(Control::NOTIFICATION_MOUSE_ENTER);
  2626. }
  2627. // Send Mouse Enter Self notification.
  2628. if (gui.mouse_over) {
  2629. gui.mouse_over->notification(Control::NOTIFICATION_MOUSE_ENTER_SELF);
  2630. }
  2631. gui.sending_mouse_enter_exit_notifications = false;
  2632. notify_embedded_viewports = true;
  2633. }
  2634. }
  2635. if (over) {
  2636. SubViewportContainer *c = Object::cast_to<SubViewportContainer>(over);
  2637. if (!c) {
  2638. return;
  2639. }
  2640. Vector2 pos = c->get_global_transform_with_canvas().affine_inverse().xform(p_pos);
  2641. if (c->is_stretch_enabled()) {
  2642. pos /= c->get_stretch_shrink();
  2643. }
  2644. for (int i = 0; i < c->get_child_count(); i++) {
  2645. SubViewport *v = Object::cast_to<SubViewport>(c->get_child(i));
  2646. if (!v || v->is_input_disabled()) {
  2647. continue;
  2648. }
  2649. if (notify_embedded_viewports) {
  2650. v->notification(NOTIFICATION_VP_MOUSE_ENTER);
  2651. }
  2652. v->_update_mouse_over(v->get_final_transform().affine_inverse().xform(pos));
  2653. }
  2654. Viewport *section_root = get_section_root_viewport();
  2655. if (section_root && c->is_mouse_target_enabled()) {
  2656. // Evaluating `mouse_target` and adjusting target_control needs to happen
  2657. // after `_update_mouse_over` in the SubViewports, because otherwise physics picking
  2658. // would not work inside SubViewports.
  2659. section_root->gui.target_control = over;
  2660. }
  2661. }
  2662. }
  2663. void Viewport::_mouse_leave_viewport() {
  2664. if (!is_inside_tree() || is_input_disabled()) {
  2665. return;
  2666. }
  2667. if (gui.subwindow_over) {
  2668. gui.subwindow_over->_mouse_leave_viewport();
  2669. gui.subwindow_over = nullptr;
  2670. } else if (gui.mouse_over) {
  2671. _drop_mouse_over();
  2672. }
  2673. notification(NOTIFICATION_VP_MOUSE_EXIT);
  2674. }
  2675. void Viewport::_drop_mouse_over(Control *p_until_control) {
  2676. if (gui.sending_mouse_enter_exit_notifications) {
  2677. // If notifications are already being sent, defer call.
  2678. callable_mp(this, &Viewport::_drop_mouse_over).call_deferred(p_until_control);
  2679. return;
  2680. }
  2681. _gui_cancel_tooltip();
  2682. SubViewportContainer *c = Object::cast_to<SubViewportContainer>(gui.mouse_over);
  2683. if (c) {
  2684. for (int i = 0; i < c->get_child_count(); i++) {
  2685. SubViewport *v = Object::cast_to<SubViewport>(c->get_child(i));
  2686. if (!v) {
  2687. continue;
  2688. }
  2689. v->_mouse_leave_viewport();
  2690. }
  2691. }
  2692. gui.sending_mouse_enter_exit_notifications = true;
  2693. if (gui.mouse_over && gui.mouse_over->is_inside_tree()) {
  2694. gui.mouse_over->notification(Control::NOTIFICATION_MOUSE_EXIT_SELF);
  2695. }
  2696. Viewport *section_root = get_section_root_viewport();
  2697. if (section_root && section_root->gui.target_control == gui.mouse_over) {
  2698. section_root->gui.target_control = nullptr;
  2699. }
  2700. gui.mouse_over = nullptr;
  2701. // Send Mouse Exit notifications to children first. Don't send to p_until_control or above.
  2702. int notification_until = p_until_control ? gui.mouse_over_hierarchy.find(p_until_control) + 1 : 0;
  2703. for (int i = gui.mouse_over_hierarchy.size() - 1; i >= notification_until; i--) {
  2704. if (gui.mouse_over_hierarchy[i]->is_inside_tree()) {
  2705. gui.mouse_over_hierarchy[i]->notification(Control::NOTIFICATION_MOUSE_EXIT);
  2706. }
  2707. }
  2708. gui.mouse_over_hierarchy.resize(notification_until);
  2709. gui.sending_mouse_enter_exit_notifications = false;
  2710. }
  2711. void Viewport::push_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
  2712. ERR_MAIN_THREAD_GUARD;
  2713. ERR_FAIL_COND(!is_inside_tree());
  2714. ERR_FAIL_COND(p_event.is_null());
  2715. if (disable_input || disable_input_override) {
  2716. return;
  2717. }
  2718. if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_ancestor_of(this)) {
  2719. return;
  2720. }
  2721. local_input_handled = false;
  2722. if (!handle_input_locally) {
  2723. Viewport *vp = this;
  2724. while (true) {
  2725. if (Object::cast_to<Window>(vp) || !vp->get_parent()) {
  2726. break;
  2727. }
  2728. vp = vp->get_parent()->get_viewport();
  2729. }
  2730. vp->local_input_handled = false;
  2731. }
  2732. Ref<InputEvent> ev;
  2733. if (!p_local_coords) {
  2734. ev = _make_input_local(p_event);
  2735. } else {
  2736. ev = p_event;
  2737. }
  2738. Ref<InputEventMouse> me = ev;
  2739. if (me.is_valid()) {
  2740. gui.last_mouse_pos = me->get_position();
  2741. _update_mouse_over();
  2742. }
  2743. if (is_embedding_subwindows() && _sub_windows_forward_input(ev)) {
  2744. set_input_as_handled();
  2745. return;
  2746. }
  2747. if (!_can_consume_input_events()) {
  2748. return;
  2749. }
  2750. if (!is_input_handled()) {
  2751. ERR_FAIL_COND(!is_inside_tree());
  2752. get_tree()->_call_input_pause(input_group, SceneTree::CALL_INPUT_TYPE_INPUT, ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
  2753. }
  2754. if (!is_input_handled()) {
  2755. ERR_FAIL_COND(!is_inside_tree());
  2756. _gui_input_event(ev);
  2757. } else {
  2758. // Cleanup internal GUI state after accepting event during _input().
  2759. _gui_cleanup_internal_state(ev);
  2760. }
  2761. if (!is_input_handled()) {
  2762. _push_unhandled_input_internal(ev);
  2763. }
  2764. event_count++;
  2765. }
  2766. #ifndef DISABLE_DEPRECATED
  2767. void Viewport::push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
  2768. ERR_MAIN_THREAD_GUARD;
  2769. WARN_DEPRECATED_MSG(R"*(The "push_unhandled_input()" method is deprecated, use "push_input()" instead.)*");
  2770. ERR_FAIL_COND(!is_inside_tree());
  2771. ERR_FAIL_COND(p_event.is_null());
  2772. local_input_handled = false;
  2773. if (disable_input || disable_input_override || !_can_consume_input_events()) {
  2774. return;
  2775. }
  2776. if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_ancestor_of(this)) {
  2777. return;
  2778. }
  2779. Ref<InputEvent> ev;
  2780. if (!p_local_coords) {
  2781. ev = _make_input_local(p_event);
  2782. } else {
  2783. ev = p_event;
  2784. }
  2785. _push_unhandled_input_internal(ev);
  2786. }
  2787. #endif // DISABLE_DEPRECATED
  2788. void Viewport::_push_unhandled_input_internal(const Ref<InputEvent> &p_event) {
  2789. // Shortcut Input.
  2790. if (Object::cast_to<InputEventKey>(*p_event) != nullptr || Object::cast_to<InputEventShortcut>(*p_event) != nullptr || Object::cast_to<InputEventJoypadButton>(*p_event) != nullptr) {
  2791. ERR_FAIL_COND(!is_inside_tree());
  2792. get_tree()->_call_input_pause(shortcut_input_group, SceneTree::CALL_INPUT_TYPE_SHORTCUT_INPUT, p_event, this);
  2793. }
  2794. // Unhandled key Input - Used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, and to handle Unicode input with Alt / Ctrl modifiers after handling shortcuts.
  2795. if (!is_input_handled() && (Object::cast_to<InputEventKey>(*p_event) != nullptr)) {
  2796. ERR_FAIL_COND(!is_inside_tree());
  2797. get_tree()->_call_input_pause(unhandled_key_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT, p_event, this);
  2798. }
  2799. // Unhandled Input.
  2800. if (!is_input_handled()) {
  2801. ERR_FAIL_COND(!is_inside_tree());
  2802. get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, p_event, this);
  2803. }
  2804. if (physics_object_picking && !is_input_handled()) {
  2805. if (Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED &&
  2806. (Object::cast_to<InputEventMouse>(*p_event) ||
  2807. Object::cast_to<InputEventScreenDrag>(*p_event) ||
  2808. Object::cast_to<InputEventScreenTouch>(*p_event)
  2809. )) {
  2810. physics_picking_events.push_back(p_event);
  2811. set_input_as_handled();
  2812. }
  2813. }
  2814. }
  2815. void Viewport::notify_mouse_entered() {
  2816. if (gui.mouse_in_viewport) {
  2817. WARN_PRINT_ED("The Viewport was previously notified that the mouse is in its area. There is no need to notify it at this time.");
  2818. return;
  2819. }
  2820. notification(NOTIFICATION_VP_MOUSE_ENTER);
  2821. }
  2822. void Viewport::notify_mouse_exited() {
  2823. if (!gui.mouse_in_viewport) {
  2824. WARN_PRINT_ED("The Viewport was previously notified that the mouse has left its area. There is no need to notify it at this time.");
  2825. return;
  2826. }
  2827. _mouse_leave_viewport();
  2828. }
  2829. void Viewport::set_physics_object_picking(bool p_enable) {
  2830. ERR_MAIN_THREAD_GUARD;
  2831. physics_object_picking = p_enable;
  2832. if (physics_object_picking) {
  2833. add_to_group("_picking_viewports");
  2834. } else {
  2835. physics_picking_events.clear();
  2836. if (is_in_group("_picking_viewports")) {
  2837. remove_from_group("_picking_viewports");
  2838. }
  2839. }
  2840. }
  2841. bool Viewport::get_physics_object_picking() {
  2842. ERR_READ_THREAD_GUARD_V(false);
  2843. return physics_object_picking;
  2844. }
  2845. void Viewport::set_physics_object_picking_sort(bool p_enable) {
  2846. ERR_MAIN_THREAD_GUARD;
  2847. physics_object_picking_sort = p_enable;
  2848. }
  2849. bool Viewport::get_physics_object_picking_sort() {
  2850. ERR_READ_THREAD_GUARD_V(false);
  2851. return physics_object_picking_sort;
  2852. }
  2853. void Viewport::set_physics_object_picking_first_only(bool p_enable) {
  2854. physics_object_picking_first_only = p_enable;
  2855. }
  2856. bool Viewport::get_physics_object_picking_first_only() {
  2857. return physics_object_picking_first_only;
  2858. }
  2859. Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const {
  2860. ERR_READ_THREAD_GUARD_V(Vector2());
  2861. Transform2D xf = stretch_transform * global_canvas_transform;
  2862. return xf.xform(p_viewport_coords);
  2863. }
  2864. Vector2 Viewport::get_camera_rect_size() const {
  2865. ERR_READ_THREAD_GUARD_V(Vector2());
  2866. return size;
  2867. }
  2868. void Viewport::set_disable_input(bool p_disable) {
  2869. ERR_MAIN_THREAD_GUARD;
  2870. if (p_disable == disable_input) {
  2871. return;
  2872. }
  2873. if (p_disable && !disable_input_override) {
  2874. _drop_mouse_focus();
  2875. _mouse_leave_viewport();
  2876. _gui_cancel_tooltip();
  2877. }
  2878. disable_input = p_disable;
  2879. }
  2880. bool Viewport::is_input_disabled() const {
  2881. ERR_READ_THREAD_GUARD_V(false);
  2882. return disable_input;
  2883. }
  2884. void Viewport::set_disable_input_override(bool p_disable) {
  2885. ERR_MAIN_THREAD_GUARD;
  2886. if (p_disable == disable_input_override) {
  2887. return;
  2888. }
  2889. if (p_disable && !disable_input) {
  2890. _drop_mouse_focus();
  2891. _mouse_leave_viewport();
  2892. _gui_cancel_tooltip();
  2893. }
  2894. disable_input_override = p_disable;
  2895. }
  2896. Variant Viewport::gui_get_drag_data() const {
  2897. ERR_READ_THREAD_GUARD_V(Variant());
  2898. return get_section_root_viewport()->gui.drag_data;
  2899. }
  2900. PackedStringArray Viewport::get_configuration_warnings() const {
  2901. ERR_MAIN_THREAD_GUARD_V(PackedStringArray());
  2902. PackedStringArray warnings = Node::get_configuration_warnings();
  2903. if (size.x <= 1 || size.y <= 1) {
  2904. warnings.push_back(RTR("The Viewport size must be greater than or equal to 2 pixels on both dimensions to render anything."));
  2905. }
  2906. return warnings;
  2907. }
  2908. void Viewport::gui_reset_canvas_sort_index() {
  2909. ERR_MAIN_THREAD_GUARD;
  2910. gui.canvas_sort_index = 0;
  2911. }
  2912. int Viewport::gui_get_canvas_sort_index() {
  2913. ERR_MAIN_THREAD_GUARD_V(0);
  2914. return gui.canvas_sort_index++;
  2915. }
  2916. void Viewport::gui_release_focus() {
  2917. ERR_MAIN_THREAD_GUARD;
  2918. if (gui.key_focus) {
  2919. Control *f = gui.key_focus;
  2920. gui.key_focus = nullptr;
  2921. f->notification(Control::NOTIFICATION_FOCUS_EXIT, true);
  2922. f->queue_redraw();
  2923. }
  2924. }
  2925. Control *Viewport::gui_get_focus_owner() const {
  2926. ERR_READ_THREAD_GUARD_V(nullptr);
  2927. return gui.key_focus;
  2928. }
  2929. Control *Viewport::gui_get_hovered_control() const {
  2930. ERR_READ_THREAD_GUARD_V(nullptr);
  2931. return gui.mouse_over;
  2932. }
  2933. void Viewport::set_msaa_2d(MSAA p_msaa) {
  2934. ERR_MAIN_THREAD_GUARD;
  2935. ERR_FAIL_INDEX(p_msaa, MSAA_MAX);
  2936. if (msaa_2d == p_msaa) {
  2937. return;
  2938. }
  2939. msaa_2d = p_msaa;
  2940. RS::get_singleton()->viewport_set_msaa_2d(viewport, RS::ViewportMSAA(p_msaa));
  2941. }
  2942. Viewport::MSAA Viewport::get_msaa_2d() const {
  2943. ERR_READ_THREAD_GUARD_V(MSAA_DISABLED);
  2944. return msaa_2d;
  2945. }
  2946. void Viewport::set_msaa_3d(MSAA p_msaa) {
  2947. ERR_MAIN_THREAD_GUARD;
  2948. ERR_FAIL_INDEX(p_msaa, MSAA_MAX);
  2949. if (msaa_3d == p_msaa) {
  2950. return;
  2951. }
  2952. msaa_3d = p_msaa;
  2953. RS::get_singleton()->viewport_set_msaa_3d(viewport, RS::ViewportMSAA(p_msaa));
  2954. }
  2955. Viewport::MSAA Viewport::get_msaa_3d() const {
  2956. ERR_READ_THREAD_GUARD_V(MSAA_DISABLED);
  2957. return msaa_3d;
  2958. }
  2959. void Viewport::set_screen_space_aa(ScreenSpaceAA p_screen_space_aa) {
  2960. ERR_MAIN_THREAD_GUARD;
  2961. ERR_FAIL_INDEX(p_screen_space_aa, SCREEN_SPACE_AA_MAX);
  2962. if (screen_space_aa == p_screen_space_aa) {
  2963. return;
  2964. }
  2965. screen_space_aa = p_screen_space_aa;
  2966. RS::get_singleton()->viewport_set_screen_space_aa(viewport, RS::ViewportScreenSpaceAA(p_screen_space_aa));
  2967. }
  2968. Viewport::ScreenSpaceAA Viewport::get_screen_space_aa() const {
  2969. ERR_READ_THREAD_GUARD_V(SCREEN_SPACE_AA_DISABLED);
  2970. return screen_space_aa;
  2971. }
  2972. void Viewport::set_use_taa(bool p_use_taa) {
  2973. ERR_MAIN_THREAD_GUARD;
  2974. if (use_taa == p_use_taa) {
  2975. return;
  2976. }
  2977. use_taa = p_use_taa;
  2978. RS::get_singleton()->viewport_set_use_taa(viewport, p_use_taa);
  2979. }
  2980. bool Viewport::is_using_taa() const {
  2981. ERR_READ_THREAD_GUARD_V(false);
  2982. return use_taa;
  2983. }
  2984. void Viewport::set_use_debanding(bool p_use_debanding) {
  2985. ERR_MAIN_THREAD_GUARD;
  2986. if (use_debanding == p_use_debanding) {
  2987. return;
  2988. }
  2989. use_debanding = p_use_debanding;
  2990. RS::get_singleton()->viewport_set_use_debanding(viewport, p_use_debanding);
  2991. }
  2992. bool Viewport::is_using_debanding() const {
  2993. ERR_READ_THREAD_GUARD_V(false);
  2994. return use_debanding;
  2995. }
  2996. void Viewport::set_mesh_lod_threshold(float p_pixels) {
  2997. ERR_MAIN_THREAD_GUARD;
  2998. mesh_lod_threshold = p_pixels;
  2999. RS::get_singleton()->viewport_set_mesh_lod_threshold(viewport, mesh_lod_threshold);
  3000. }
  3001. float Viewport::get_mesh_lod_threshold() const {
  3002. ERR_READ_THREAD_GUARD_V(0);
  3003. return mesh_lod_threshold;
  3004. }
  3005. void Viewport::set_use_occlusion_culling(bool p_use_occlusion_culling) {
  3006. ERR_MAIN_THREAD_GUARD;
  3007. if (use_occlusion_culling == p_use_occlusion_culling) {
  3008. return;
  3009. }
  3010. use_occlusion_culling = p_use_occlusion_culling;
  3011. RS::get_singleton()->viewport_set_use_occlusion_culling(viewport, p_use_occlusion_culling);
  3012. notify_property_list_changed();
  3013. }
  3014. bool Viewport::is_using_occlusion_culling() const {
  3015. ERR_READ_THREAD_GUARD_V(false);
  3016. return use_occlusion_culling;
  3017. }
  3018. void Viewport::set_debug_draw(DebugDraw p_debug_draw) {
  3019. ERR_MAIN_THREAD_GUARD;
  3020. debug_draw = p_debug_draw;
  3021. RS::get_singleton()->viewport_set_debug_draw(viewport, RS::ViewportDebugDraw(p_debug_draw));
  3022. }
  3023. Viewport::DebugDraw Viewport::get_debug_draw() const {
  3024. ERR_READ_THREAD_GUARD_V(DEBUG_DRAW_DISABLED);
  3025. return debug_draw;
  3026. }
  3027. int Viewport::get_render_info(RenderInfoType p_type, RenderInfo p_info) {
  3028. ERR_READ_THREAD_GUARD_V(0);
  3029. return RS::get_singleton()->viewport_get_render_info(viewport, RS::ViewportRenderInfoType(p_type), RS::ViewportRenderInfo(p_info));
  3030. }
  3031. void Viewport::set_snap_controls_to_pixels(bool p_enable) {
  3032. ERR_MAIN_THREAD_GUARD;
  3033. snap_controls_to_pixels = p_enable;
  3034. }
  3035. bool Viewport::is_snap_controls_to_pixels_enabled() const {
  3036. ERR_READ_THREAD_GUARD_V(false);
  3037. return snap_controls_to_pixels;
  3038. }
  3039. void Viewport::set_snap_2d_transforms_to_pixel(bool p_enable) {
  3040. ERR_MAIN_THREAD_GUARD;
  3041. snap_2d_transforms_to_pixel = p_enable;
  3042. RS::get_singleton()->viewport_set_snap_2d_transforms_to_pixel(viewport, snap_2d_transforms_to_pixel);
  3043. }
  3044. bool Viewport::is_snap_2d_transforms_to_pixel_enabled() const {
  3045. ERR_READ_THREAD_GUARD_V(false);
  3046. return snap_2d_transforms_to_pixel;
  3047. }
  3048. void Viewport::set_snap_2d_vertices_to_pixel(bool p_enable) {
  3049. ERR_MAIN_THREAD_GUARD;
  3050. snap_2d_vertices_to_pixel = p_enable;
  3051. RS::get_singleton()->viewport_set_snap_2d_vertices_to_pixel(viewport, snap_2d_vertices_to_pixel);
  3052. }
  3053. bool Viewport::is_snap_2d_vertices_to_pixel_enabled() const {
  3054. ERR_READ_THREAD_GUARD_V(false);
  3055. return snap_2d_vertices_to_pixel;
  3056. }
  3057. bool Viewport::gui_is_dragging() const {
  3058. ERR_READ_THREAD_GUARD_V(false);
  3059. return get_section_root_viewport()->gui.global_dragging;
  3060. }
  3061. bool Viewport::gui_is_drag_successful() const {
  3062. ERR_READ_THREAD_GUARD_V(false);
  3063. return gui.drag_successful;
  3064. }
  3065. void Viewport::gui_cancel_drag() {
  3066. ERR_MAIN_THREAD_GUARD;
  3067. if (gui_is_dragging()) {
  3068. _perform_drop();
  3069. }
  3070. }
  3071. void Viewport::set_input_as_handled() {
  3072. ERR_MAIN_THREAD_GUARD;
  3073. if (!handle_input_locally) {
  3074. ERR_FAIL_COND(!is_inside_tree());
  3075. Viewport *vp = this;
  3076. while (true) {
  3077. if (Object::cast_to<Window>(vp)) {
  3078. break;
  3079. }
  3080. if (!vp->get_parent()) {
  3081. break;
  3082. }
  3083. vp = vp->get_parent()->get_viewport();
  3084. }
  3085. if (vp != this) {
  3086. vp->set_input_as_handled();
  3087. return;
  3088. }
  3089. }
  3090. local_input_handled = true;
  3091. }
  3092. bool Viewport::is_input_handled() const {
  3093. ERR_READ_THREAD_GUARD_V(false);
  3094. if (!handle_input_locally) {
  3095. ERR_FAIL_COND_V(!is_inside_tree(), false);
  3096. const Viewport *vp = this;
  3097. while (true) {
  3098. if (Object::cast_to<Window>(vp)) {
  3099. break;
  3100. }
  3101. if (!vp->get_parent()) {
  3102. break;
  3103. }
  3104. vp = vp->get_parent()->get_viewport();
  3105. }
  3106. if (vp != this) {
  3107. return vp->is_input_handled();
  3108. }
  3109. }
  3110. return local_input_handled;
  3111. }
  3112. void Viewport::set_handle_input_locally(bool p_enable) {
  3113. ERR_MAIN_THREAD_GUARD;
  3114. handle_input_locally = p_enable;
  3115. }
  3116. bool Viewport::is_handling_input_locally() const {
  3117. ERR_READ_THREAD_GUARD_V(false);
  3118. return handle_input_locally;
  3119. }
  3120. void Viewport::set_default_canvas_item_texture_filter(DefaultCanvasItemTextureFilter p_filter) {
  3121. ERR_MAIN_THREAD_GUARD;
  3122. ERR_FAIL_INDEX(p_filter, DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX);
  3123. if (default_canvas_item_texture_filter == p_filter) {
  3124. return;
  3125. }
  3126. default_canvas_item_texture_filter = p_filter;
  3127. switch (default_canvas_item_texture_filter) {
  3128. case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST:
  3129. RS::get_singleton()->viewport_set_default_canvas_item_texture_filter(viewport, RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
  3130. break;
  3131. case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR:
  3132. RS::get_singleton()->viewport_set_default_canvas_item_texture_filter(viewport, RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR);
  3133. break;
  3134. case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS:
  3135. RS::get_singleton()->viewport_set_default_canvas_item_texture_filter(viewport, RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
  3136. break;
  3137. case DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS:
  3138. RS::get_singleton()->viewport_set_default_canvas_item_texture_filter(viewport, RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
  3139. break;
  3140. default: {
  3141. }
  3142. }
  3143. }
  3144. Viewport::DefaultCanvasItemTextureFilter Viewport::get_default_canvas_item_texture_filter() const {
  3145. ERR_READ_THREAD_GUARD_V(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
  3146. return default_canvas_item_texture_filter;
  3147. }
  3148. void Viewport::set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRepeat p_repeat) {
  3149. ERR_MAIN_THREAD_GUARD;
  3150. ERR_FAIL_INDEX(p_repeat, DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX);
  3151. if (default_canvas_item_texture_repeat == p_repeat) {
  3152. return;
  3153. }
  3154. default_canvas_item_texture_repeat = p_repeat;
  3155. switch (default_canvas_item_texture_repeat) {
  3156. case DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED:
  3157. RS::get_singleton()->viewport_set_default_canvas_item_texture_repeat(viewport, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
  3158. break;
  3159. case DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED:
  3160. RS::get_singleton()->viewport_set_default_canvas_item_texture_repeat(viewport, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
  3161. break;
  3162. case DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR:
  3163. RS::get_singleton()->viewport_set_default_canvas_item_texture_repeat(viewport, RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
  3164. break;
  3165. default: {
  3166. }
  3167. }
  3168. }
  3169. Viewport::DefaultCanvasItemTextureRepeat Viewport::get_default_canvas_item_texture_repeat() const {
  3170. ERR_READ_THREAD_GUARD_V(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
  3171. return default_canvas_item_texture_repeat;
  3172. }
  3173. void Viewport::set_vrs_mode(Viewport::VRSMode p_vrs_mode) {
  3174. ERR_MAIN_THREAD_GUARD;
  3175. // Note, set this even if not supported on this hardware, it will only be used if it is but we want to save the value as set by the user.
  3176. vrs_mode = p_vrs_mode;
  3177. switch (p_vrs_mode) {
  3178. case VRS_TEXTURE: {
  3179. RS::get_singleton()->viewport_set_vrs_mode(viewport, RS::VIEWPORT_VRS_TEXTURE);
  3180. } break;
  3181. case VRS_XR: {
  3182. RS::get_singleton()->viewport_set_vrs_mode(viewport, RS::VIEWPORT_VRS_XR);
  3183. } break;
  3184. default: {
  3185. RS::get_singleton()->viewport_set_vrs_mode(viewport, RS::VIEWPORT_VRS_DISABLED);
  3186. } break;
  3187. }
  3188. notify_property_list_changed();
  3189. }
  3190. Viewport::VRSMode Viewport::get_vrs_mode() const {
  3191. ERR_READ_THREAD_GUARD_V(VRS_DISABLED);
  3192. return vrs_mode;
  3193. }
  3194. void Viewport::set_vrs_update_mode(VRSUpdateMode p_vrs_update_mode) {
  3195. ERR_MAIN_THREAD_GUARD;
  3196. vrs_update_mode = p_vrs_update_mode;
  3197. switch (p_vrs_update_mode) {
  3198. case VRS_UPDATE_ONCE: {
  3199. RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_ONCE);
  3200. } break;
  3201. case VRS_UPDATE_ALWAYS: {
  3202. RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_ALWAYS);
  3203. } break;
  3204. default: {
  3205. RS::get_singleton()->viewport_set_vrs_update_mode(viewport, RS::VIEWPORT_VRS_UPDATE_DISABLED);
  3206. } break;
  3207. }
  3208. }
  3209. Viewport::VRSUpdateMode Viewport::get_vrs_update_mode() const {
  3210. ERR_READ_THREAD_GUARD_V(VRS_UPDATE_DISABLED);
  3211. return vrs_update_mode;
  3212. }
  3213. void Viewport::set_vrs_texture(Ref<Texture2D> p_texture) {
  3214. ERR_MAIN_THREAD_GUARD;
  3215. vrs_texture = p_texture;
  3216. // TODO need to add something here in case the RID changes
  3217. RID tex = p_texture.is_valid() ? p_texture->get_rid() : RID();
  3218. RS::get_singleton()->viewport_set_vrs_texture(viewport, tex);
  3219. }
  3220. Ref<Texture2D> Viewport::get_vrs_texture() const {
  3221. ERR_READ_THREAD_GUARD_V(Ref<Texture2D>());
  3222. return vrs_texture;
  3223. }
  3224. DisplayServer::WindowID Viewport::get_window_id() const {
  3225. ERR_READ_THREAD_GUARD_V(DisplayServer::INVALID_WINDOW_ID);
  3226. return DisplayServer::MAIN_WINDOW_ID;
  3227. }
  3228. Viewport *Viewport::get_parent_viewport() const {
  3229. ERR_READ_THREAD_GUARD_V(nullptr);
  3230. ERR_FAIL_COND_V(!is_inside_tree(), nullptr);
  3231. if (!get_parent()) {
  3232. return nullptr; //root viewport
  3233. }
  3234. return get_parent()->get_viewport();
  3235. }
  3236. void Viewport::set_embedding_subwindows(bool p_embed) {
  3237. ERR_THREAD_GUARD;
  3238. if (gui.embed_subwindows_hint == p_embed) {
  3239. return;
  3240. }
  3241. bool allow_change = true;
  3242. if (!is_inside_tree()) {
  3243. // Change can happen since no child window is displayed.
  3244. } else if (gui.embed_subwindows_hint) {
  3245. if (!gui.sub_windows.is_empty()) {
  3246. // Prevent change when this viewport has embedded windows.
  3247. allow_change = false;
  3248. }
  3249. } else {
  3250. Viewport *vp = this;
  3251. while (true) {
  3252. if (!vp->get_parent()) {
  3253. // Root window reached.
  3254. break;
  3255. }
  3256. vp = vp->get_parent()->get_viewport();
  3257. if (vp->is_embedding_subwindows()) {
  3258. for (int i = 0; i < vp->gui.sub_windows.size(); i++) {
  3259. if (is_ancestor_of(vp->gui.sub_windows[i].window)) {
  3260. // Prevent change when this viewport has child windows that are displayed in an ancestor viewport.
  3261. allow_change = false;
  3262. break;
  3263. }
  3264. }
  3265. }
  3266. }
  3267. if (allow_change) {
  3268. Vector<DisplayServer::WindowID> wl = DisplayServer::get_singleton()->get_window_list();
  3269. for (const DisplayServer::WindowID &window_id : wl) {
  3270. const Window *w = Window::get_from_id(window_id);
  3271. if (w && is_ancestor_of(w)) {
  3272. // Prevent change when this viewport has child windows that are displayed as native windows.
  3273. allow_change = false;
  3274. break;
  3275. }
  3276. }
  3277. }
  3278. }
  3279. if (allow_change) {
  3280. gui.embed_subwindows_hint = p_embed;
  3281. } else {
  3282. WARN_PRINT("Can't change \"gui_embed_subwindows\" while a child window is displayed. Consider hiding all child windows before changing this value.");
  3283. }
  3284. }
  3285. bool Viewport::is_embedding_subwindows() const {
  3286. ERR_READ_THREAD_GUARD_V(false);
  3287. return gui.embed_subwindows_hint;
  3288. }
  3289. TypedArray<Window> Viewport::get_embedded_subwindows() const {
  3290. TypedArray<Window> windows;
  3291. for (int i = 0; i < gui.sub_windows.size(); i++) {
  3292. windows.append(gui.sub_windows[i].window);
  3293. }
  3294. return windows;
  3295. }
  3296. void Viewport::subwindow_set_popup_safe_rect(Window *p_window, const Rect2i &p_rect) {
  3297. int index = _sub_window_find(p_window);
  3298. ERR_FAIL_COND(index == -1);
  3299. gui.sub_windows.write[index].parent_safe_rect = p_rect;
  3300. }
  3301. Rect2i Viewport::subwindow_get_popup_safe_rect(Window *p_window) const {
  3302. int index = _sub_window_find(p_window);
  3303. // FIXME: Re-enable ERR_FAIL_COND after rewriting embedded window popup closing.
  3304. // Currently it is expected, that index == -1 can happen.
  3305. if (index == -1) {
  3306. return Rect2i();
  3307. }
  3308. // ERR_FAIL_COND_V(index == -1, Rect2i());
  3309. return gui.sub_windows[index].parent_safe_rect;
  3310. }
  3311. void Viewport::set_sdf_oversize(SDFOversize p_sdf_oversize) {
  3312. ERR_MAIN_THREAD_GUARD;
  3313. ERR_FAIL_INDEX(p_sdf_oversize, SDF_OVERSIZE_MAX);
  3314. sdf_oversize = p_sdf_oversize;
  3315. RS::get_singleton()->viewport_set_sdf_oversize_and_scale(viewport, RS::ViewportSDFOversize(sdf_oversize), RS::ViewportSDFScale(sdf_scale));
  3316. }
  3317. Viewport::SDFOversize Viewport::get_sdf_oversize() const {
  3318. ERR_READ_THREAD_GUARD_V(SDF_OVERSIZE_100_PERCENT);
  3319. return sdf_oversize;
  3320. }
  3321. void Viewport::set_sdf_scale(SDFScale p_sdf_scale) {
  3322. ERR_MAIN_THREAD_GUARD;
  3323. ERR_FAIL_INDEX(p_sdf_scale, SDF_SCALE_MAX);
  3324. sdf_scale = p_sdf_scale;
  3325. RS::get_singleton()->viewport_set_sdf_oversize_and_scale(viewport, RS::ViewportSDFOversize(sdf_oversize), RS::ViewportSDFScale(sdf_scale));
  3326. }
  3327. Viewport::SDFScale Viewport::get_sdf_scale() const {
  3328. ERR_READ_THREAD_GUARD_V(SDF_SCALE_100_PERCENT);
  3329. return sdf_scale;
  3330. }
  3331. Transform2D Viewport::get_screen_transform() const {
  3332. ERR_READ_THREAD_GUARD_V(Transform2D());
  3333. return get_screen_transform_internal();
  3334. }
  3335. Transform2D Viewport::get_screen_transform_internal(bool p_absolute_position) const {
  3336. ERR_READ_THREAD_GUARD_V(Transform2D());
  3337. return get_final_transform();
  3338. }
  3339. void Viewport::update_mouse_cursor_state() {
  3340. // Updates need to happen in Window, because SubViewportContainers might be hidden behind other Controls.
  3341. Window *base_window = get_base_window();
  3342. if (base_window) {
  3343. base_window->update_mouse_cursor_state();
  3344. }
  3345. }
  3346. void Viewport::set_canvas_cull_mask(uint32_t p_canvas_cull_mask) {
  3347. ERR_MAIN_THREAD_GUARD;
  3348. canvas_cull_mask = p_canvas_cull_mask;
  3349. RenderingServer::get_singleton()->viewport_set_canvas_cull_mask(viewport, canvas_cull_mask);
  3350. }
  3351. uint32_t Viewport::get_canvas_cull_mask() const {
  3352. ERR_READ_THREAD_GUARD_V(0);
  3353. return canvas_cull_mask;
  3354. }
  3355. void Viewport::set_canvas_cull_mask_bit(uint32_t p_layer, bool p_enable) {
  3356. ERR_MAIN_THREAD_GUARD;
  3357. ERR_FAIL_UNSIGNED_INDEX(p_layer, 32);
  3358. if (p_enable) {
  3359. set_canvas_cull_mask(canvas_cull_mask | (1 << p_layer));
  3360. } else {
  3361. set_canvas_cull_mask(canvas_cull_mask & (~(1 << p_layer)));
  3362. }
  3363. }
  3364. bool Viewport::get_canvas_cull_mask_bit(uint32_t p_layer) const {
  3365. ERR_READ_THREAD_GUARD_V(false);
  3366. ERR_FAIL_UNSIGNED_INDEX_V(p_layer, 32, false);
  3367. return (canvas_cull_mask & (1 << p_layer));
  3368. }
  3369. #ifdef TOOLS_ENABLED
  3370. bool Viewport::is_visible_subviewport() const {
  3371. if (!is_sub_viewport()) {
  3372. return true;
  3373. }
  3374. SubViewportContainer *container = Object::cast_to<SubViewportContainer>(get_parent());
  3375. return container && container->is_visible_in_tree();
  3376. }
  3377. #endif // TOOLS_ENABLED
  3378. void Viewport::_update_audio_listener_2d() {
  3379. if (AudioServer::get_singleton()) {
  3380. AudioServer::get_singleton()->notify_listener_changed();
  3381. }
  3382. }
  3383. void Viewport::_audio_listener_2d_set(AudioListener2D *p_audio_listener) {
  3384. if (audio_listener_2d == p_audio_listener) {
  3385. return;
  3386. } else if (audio_listener_2d) {
  3387. audio_listener_2d->clear_current();
  3388. }
  3389. audio_listener_2d = p_audio_listener;
  3390. }
  3391. void Viewport::_audio_listener_2d_remove(AudioListener2D *p_audio_listener) {
  3392. if (audio_listener_2d == p_audio_listener) {
  3393. audio_listener_2d = nullptr;
  3394. }
  3395. }
  3396. void Viewport::_camera_2d_set(Camera2D *p_camera_2d) {
  3397. camera_2d = p_camera_2d;
  3398. }
  3399. void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paused_only, uint64_t p_frame_reference) {
  3400. List<ObjectID> to_erase;
  3401. List<ObjectID> to_mouse_exit;
  3402. for (const KeyValue<ObjectID, uint64_t> &E : physics_2d_mouseover) {
  3403. if (!p_clean_all_frames && E.value == p_frame_reference) {
  3404. continue;
  3405. }
  3406. Object *o = ObjectDB::get_instance(E.key);
  3407. if (o) {
  3408. CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
  3409. if (co && co->is_inside_tree()) {
  3410. if (p_clean_all_frames && p_paused_only && co->can_process()) {
  3411. continue;
  3412. }
  3413. to_mouse_exit.push_back(E.key);
  3414. }
  3415. }
  3416. to_erase.push_back(E.key);
  3417. }
  3418. while (to_erase.size()) {
  3419. physics_2d_mouseover.erase(to_erase.front()->get());
  3420. to_erase.pop_front();
  3421. }
  3422. // Per-shape.
  3423. List<Pair<ObjectID, int>> shapes_to_erase;
  3424. List<Pair<ObjectID, int>> shapes_to_mouse_exit;
  3425. for (KeyValue<Pair<ObjectID, int>, uint64_t> &E : physics_2d_shape_mouseover) {
  3426. if (!p_clean_all_frames && E.value == p_frame_reference) {
  3427. continue;
  3428. }
  3429. Object *o = ObjectDB::get_instance(E.key.first);
  3430. if (o) {
  3431. CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
  3432. if (co && co->is_inside_tree()) {
  3433. if (p_clean_all_frames && p_paused_only && co->can_process()) {
  3434. continue;
  3435. }
  3436. shapes_to_mouse_exit.push_back(E.key);
  3437. }
  3438. }
  3439. shapes_to_erase.push_back(E.key);
  3440. }
  3441. while (shapes_to_erase.size()) {
  3442. physics_2d_shape_mouseover.erase(shapes_to_erase.front()->get());
  3443. shapes_to_erase.pop_front();
  3444. }
  3445. while (to_mouse_exit.size()) {
  3446. Object *o = ObjectDB::get_instance(to_mouse_exit.front()->get());
  3447. CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
  3448. co->_mouse_exit();
  3449. to_mouse_exit.pop_front();
  3450. }
  3451. while (shapes_to_mouse_exit.size()) {
  3452. Pair<ObjectID, int> e = shapes_to_mouse_exit.front()->get();
  3453. Object *o = ObjectDB::get_instance(e.first);
  3454. CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
  3455. co->_mouse_shape_exit(e.second);
  3456. shapes_to_mouse_exit.pop_front();
  3457. }
  3458. }
  3459. AudioListener2D *Viewport::get_audio_listener_2d() const {
  3460. ERR_READ_THREAD_GUARD_V(nullptr);
  3461. return audio_listener_2d;
  3462. }
  3463. void Viewport::set_as_audio_listener_2d(bool p_enable) {
  3464. ERR_MAIN_THREAD_GUARD;
  3465. if (p_enable == is_audio_listener_2d_enabled) {
  3466. return;
  3467. }
  3468. is_audio_listener_2d_enabled = p_enable;
  3469. _update_audio_listener_2d();
  3470. }
  3471. bool Viewport::is_audio_listener_2d() const {
  3472. ERR_READ_THREAD_GUARD_V(false);
  3473. return is_audio_listener_2d_enabled;
  3474. }
  3475. Camera2D *Viewport::get_camera_2d() const {
  3476. ERR_READ_THREAD_GUARD_V(nullptr);
  3477. return camera_2d;
  3478. }
  3479. void Viewport::assign_next_enabled_camera_2d(const StringName &p_camera_group) {
  3480. ERR_MAIN_THREAD_GUARD;
  3481. List<Node *> camera_list;
  3482. get_tree()->get_nodes_in_group(p_camera_group, &camera_list);
  3483. Camera2D *new_camera = nullptr;
  3484. for (Node *E : camera_list) {
  3485. Camera2D *cam = Object::cast_to<Camera2D>(E);
  3486. if (!cam) {
  3487. continue; // Non-camera node (e.g. ParallaxBackground).
  3488. }
  3489. if (cam->is_enabled()) {
  3490. new_camera = cam;
  3491. break;
  3492. }
  3493. }
  3494. _camera_2d_set(new_camera);
  3495. if (!camera_2d) {
  3496. set_canvas_transform(Transform2D());
  3497. }
  3498. }
  3499. #ifndef _3D_DISABLED
  3500. AudioListener3D *Viewport::get_audio_listener_3d() const {
  3501. ERR_READ_THREAD_GUARD_V(nullptr);
  3502. return audio_listener_3d;
  3503. }
  3504. void Viewport::set_as_audio_listener_3d(bool p_enable) {
  3505. ERR_MAIN_THREAD_GUARD;
  3506. if (p_enable == is_audio_listener_3d_enabled) {
  3507. return;
  3508. }
  3509. is_audio_listener_3d_enabled = p_enable;
  3510. _update_audio_listener_3d();
  3511. }
  3512. bool Viewport::is_audio_listener_3d() const {
  3513. ERR_READ_THREAD_GUARD_V(false);
  3514. return is_audio_listener_3d_enabled;
  3515. }
  3516. void Viewport::_update_audio_listener_3d() {
  3517. if (AudioServer::get_singleton()) {
  3518. AudioServer::get_singleton()->notify_listener_changed();
  3519. }
  3520. }
  3521. void Viewport::_listener_transform_3d_changed_notify() {
  3522. }
  3523. void Viewport::_audio_listener_3d_set(AudioListener3D *p_listener) {
  3524. if (audio_listener_3d == p_listener) {
  3525. return;
  3526. }
  3527. audio_listener_3d = p_listener;
  3528. _update_audio_listener_3d();
  3529. _listener_transform_3d_changed_notify();
  3530. }
  3531. bool Viewport::_audio_listener_3d_add(AudioListener3D *p_listener) {
  3532. audio_listener_3d_set.insert(p_listener);
  3533. return audio_listener_3d_set.size() == 1;
  3534. }
  3535. void Viewport::_audio_listener_3d_remove(AudioListener3D *p_listener) {
  3536. audio_listener_3d_set.erase(p_listener);
  3537. if (audio_listener_3d == p_listener) {
  3538. audio_listener_3d = nullptr;
  3539. }
  3540. }
  3541. void Viewport::_audio_listener_3d_make_next_current(AudioListener3D *p_exclude) {
  3542. if (audio_listener_3d_set.size() > 0) {
  3543. for (AudioListener3D *E : audio_listener_3d_set) {
  3544. if (p_exclude == E) {
  3545. continue;
  3546. }
  3547. if (!E->is_inside_tree()) {
  3548. continue;
  3549. }
  3550. if (audio_listener_3d != nullptr) {
  3551. return;
  3552. }
  3553. E->make_current();
  3554. }
  3555. } else {
  3556. // Attempt to reset listener to the camera position.
  3557. if (camera_3d != nullptr) {
  3558. _update_audio_listener_3d();
  3559. _camera_3d_transform_changed_notify();
  3560. }
  3561. }
  3562. }
  3563. void Viewport::_collision_object_3d_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
  3564. Transform3D object_transform = p_object->get_global_transform();
  3565. Transform3D camera_transform = p_camera->get_global_transform();
  3566. ObjectID id = p_object->get_instance_id();
  3567. // Avoid sending the fake event unnecessarily if nothing really changed in the context.
  3568. if (object_transform == physics_last_object_transform && camera_transform == physics_last_camera_transform && physics_last_id == id) {
  3569. Ref<InputEventMouseMotion> mm = p_input_event;
  3570. if (mm.is_valid() && mm->get_device() == InputEvent::DEVICE_ID_INTERNAL) {
  3571. return; // Discarded.
  3572. }
  3573. }
  3574. p_object->_input_event_call(camera_3d, p_input_event, p_pos, p_normal, p_shape);
  3575. physics_last_object_transform = object_transform;
  3576. physics_last_camera_transform = camera_transform;
  3577. physics_last_id = id;
  3578. }
  3579. Camera3D *Viewport::get_camera_3d() const {
  3580. ERR_READ_THREAD_GUARD_V(nullptr);
  3581. return camera_3d;
  3582. }
  3583. void Viewport::_camera_3d_transform_changed_notify() {
  3584. }
  3585. void Viewport::_camera_3d_set(Camera3D *p_camera) {
  3586. if (camera_3d == p_camera) {
  3587. return;
  3588. }
  3589. if (camera_3d) {
  3590. camera_3d->notification(Camera3D::NOTIFICATION_LOST_CURRENT);
  3591. }
  3592. camera_3d = p_camera;
  3593. if (!camera_3d_override) {
  3594. if (camera_3d) {
  3595. RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d->get_camera());
  3596. } else {
  3597. RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID());
  3598. }
  3599. }
  3600. if (camera_3d) {
  3601. camera_3d->notification(Camera3D::NOTIFICATION_BECAME_CURRENT);
  3602. }
  3603. _update_audio_listener_3d();
  3604. _camera_3d_transform_changed_notify();
  3605. }
  3606. bool Viewport::_camera_3d_add(Camera3D *p_camera) {
  3607. camera_3d_set.insert(p_camera);
  3608. return camera_3d_set.size() == 1;
  3609. }
  3610. void Viewport::_camera_3d_remove(Camera3D *p_camera) {
  3611. camera_3d_set.erase(p_camera);
  3612. if (camera_3d == p_camera) {
  3613. _camera_3d_set(nullptr);
  3614. }
  3615. }
  3616. void Viewport::_camera_3d_make_next_current(Camera3D *p_exclude) {
  3617. for (Camera3D *E : camera_3d_set) {
  3618. if (p_exclude == E) {
  3619. continue;
  3620. }
  3621. if (!E->is_inside_tree()) {
  3622. continue;
  3623. }
  3624. if (camera_3d != nullptr) {
  3625. return;
  3626. }
  3627. E->make_current();
  3628. }
  3629. }
  3630. void Viewport::enable_camera_3d_override(bool p_enable) {
  3631. ERR_MAIN_THREAD_GUARD;
  3632. if (p_enable == camera_3d_override) {
  3633. return;
  3634. }
  3635. if (p_enable) {
  3636. camera_3d_override.rid = RenderingServer::get_singleton()->camera_create();
  3637. } else {
  3638. RenderingServer::get_singleton()->free(camera_3d_override.rid);
  3639. camera_3d_override.rid = RID();
  3640. }
  3641. if (p_enable) {
  3642. RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d_override.rid);
  3643. } else if (camera_3d) {
  3644. RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera_3d->get_camera());
  3645. } else {
  3646. RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID());
  3647. }
  3648. }
  3649. void Viewport::set_camera_3d_override_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far) {
  3650. ERR_MAIN_THREAD_GUARD;
  3651. if (camera_3d_override) {
  3652. if (camera_3d_override.fov == p_fovy_degrees && camera_3d_override.z_near == p_z_near &&
  3653. camera_3d_override.z_far == p_z_far && camera_3d_override.projection == Camera3DOverrideData::PROJECTION_PERSPECTIVE) {
  3654. return;
  3655. }
  3656. camera_3d_override.fov = p_fovy_degrees;
  3657. camera_3d_override.z_near = p_z_near;
  3658. camera_3d_override.z_far = p_z_far;
  3659. camera_3d_override.projection = Camera3DOverrideData::PROJECTION_PERSPECTIVE;
  3660. RenderingServer::get_singleton()->camera_set_perspective(camera_3d_override.rid, camera_3d_override.fov, camera_3d_override.z_near, camera_3d_override.z_far);
  3661. }
  3662. }
  3663. void Viewport::set_camera_3d_override_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far) {
  3664. ERR_MAIN_THREAD_GUARD;
  3665. if (camera_3d_override) {
  3666. if (camera_3d_override.size == p_size && camera_3d_override.z_near == p_z_near &&
  3667. camera_3d_override.z_far == p_z_far && camera_3d_override.projection == Camera3DOverrideData::PROJECTION_ORTHOGONAL) {
  3668. return;
  3669. }
  3670. camera_3d_override.size = p_size;
  3671. camera_3d_override.z_near = p_z_near;
  3672. camera_3d_override.z_far = p_z_far;
  3673. camera_3d_override.projection = Camera3DOverrideData::PROJECTION_ORTHOGONAL;
  3674. RenderingServer::get_singleton()->camera_set_orthogonal(camera_3d_override.rid, camera_3d_override.size, camera_3d_override.z_near, camera_3d_override.z_far);
  3675. }
  3676. }
  3677. HashMap<StringName, real_t> Viewport::get_camera_3d_override_properties() const {
  3678. HashMap<StringName, real_t> props;
  3679. props["size"] = 0;
  3680. props["fov"] = 0;
  3681. props["z_near"] = 0;
  3682. props["z_far"] = 0;
  3683. ERR_READ_THREAD_GUARD_V(props);
  3684. props["size"] = camera_3d_override.size;
  3685. props["fov"] = camera_3d_override.fov;
  3686. props["z_near"] = camera_3d_override.z_near;
  3687. props["z_far"] = camera_3d_override.z_far;
  3688. return props;
  3689. }
  3690. void Viewport::set_disable_3d(bool p_disable) {
  3691. ERR_MAIN_THREAD_GUARD;
  3692. disable_3d = p_disable;
  3693. RenderingServer::get_singleton()->viewport_set_disable_3d(viewport, disable_3d);
  3694. }
  3695. bool Viewport::is_3d_disabled() const {
  3696. ERR_READ_THREAD_GUARD_V(false);
  3697. return disable_3d;
  3698. }
  3699. bool Viewport::is_camera_3d_override_enabled() const {
  3700. ERR_READ_THREAD_GUARD_V(false);
  3701. return camera_3d_override;
  3702. }
  3703. void Viewport::set_camera_3d_override_transform(const Transform3D &p_transform) {
  3704. ERR_MAIN_THREAD_GUARD;
  3705. if (camera_3d_override) {
  3706. camera_3d_override.transform = p_transform;
  3707. RenderingServer::get_singleton()->camera_set_transform(camera_3d_override.rid, p_transform);
  3708. }
  3709. }
  3710. Transform3D Viewport::get_camera_3d_override_transform() const {
  3711. ERR_READ_THREAD_GUARD_V(Transform3D());
  3712. if (camera_3d_override) {
  3713. return camera_3d_override.transform;
  3714. }
  3715. return Transform3D();
  3716. }
  3717. Vector3 Viewport::camera_3d_override_project_ray_normal(const Point2 &p_pos) const {
  3718. ERR_READ_THREAD_GUARD_V(Vector3());
  3719. Vector3 ray = camera_3d_override_project_local_ray_normal(p_pos);
  3720. return camera_3d_override.transform.basis.xform(ray).normalized();
  3721. }
  3722. Vector3 Viewport::camera_3d_override_project_local_ray_normal(const Point2 &p_pos) const {
  3723. ERR_READ_THREAD_GUARD_V(Vector3());
  3724. Size2 viewport_size = get_camera_rect_size();
  3725. Vector2 cpos = get_camera_coords(p_pos);
  3726. Vector3 ray;
  3727. if (camera_3d_override.projection == Camera3DOverrideData::PROJECTION_ORTHOGONAL) {
  3728. ray = Vector3(0, 0, -1);
  3729. } else {
  3730. Projection cm;
  3731. cm.set_perspective(camera_3d_override.fov, get_visible_rect().size.aspect(), camera_3d_override.z_near, camera_3d_override.z_far, false);
  3732. Vector2 screen_he = cm.get_viewport_half_extents();
  3733. 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, -camera_3d_override.z_near).normalized();
  3734. }
  3735. return ray;
  3736. }
  3737. Vector3 Viewport::camera_3d_override_project_ray_origin(const Point2 &p_pos) const {
  3738. ERR_READ_THREAD_GUARD_V(Vector3());
  3739. Size2 viewport_size = get_camera_rect_size();
  3740. Vector2 cpos = get_camera_coords(p_pos);
  3741. ERR_FAIL_COND_V(viewport_size.y == 0, Vector3());
  3742. if (camera_3d_override.projection == Camera3DOverrideData::PROJECTION_ORTHOGONAL) {
  3743. Vector2 pos = cpos / viewport_size;
  3744. real_t vsize, hsize;
  3745. hsize = camera_3d_override.size * viewport_size.aspect();
  3746. vsize = camera_3d_override.size;
  3747. Vector3 ray;
  3748. ray.x = pos.x * (hsize)-hsize / 2;
  3749. ray.y = (1.0 - pos.y) * (vsize)-vsize / 2;
  3750. ray.z = -camera_3d_override.z_near;
  3751. ray = camera_3d_override.transform.xform(ray);
  3752. return ray;
  3753. } else {
  3754. return camera_3d_override.transform.origin;
  3755. };
  3756. }
  3757. Ref<World3D> Viewport::get_world_3d() const {
  3758. ERR_READ_THREAD_GUARD_V(Ref<World3D>());
  3759. return world_3d;
  3760. }
  3761. Ref<World3D> Viewport::find_world_3d() const {
  3762. ERR_READ_THREAD_GUARD_V(Ref<World3D>());
  3763. if (own_world_3d.is_valid()) {
  3764. return own_world_3d;
  3765. } else if (world_3d.is_valid()) {
  3766. return world_3d;
  3767. } else if (parent) {
  3768. return parent->find_world_3d();
  3769. } else {
  3770. return Ref<World3D>();
  3771. }
  3772. }
  3773. void Viewport::set_world_3d(const Ref<World3D> &p_world_3d) {
  3774. ERR_MAIN_THREAD_GUARD;
  3775. if (world_3d == p_world_3d) {
  3776. return;
  3777. }
  3778. if (is_inside_tree()) {
  3779. _propagate_exit_world_3d(this);
  3780. }
  3781. if (own_world_3d.is_valid() && world_3d.is_valid()) {
  3782. world_3d->disconnect_changed(callable_mp(this, &Viewport::_own_world_3d_changed));
  3783. }
  3784. world_3d = p_world_3d;
  3785. if (own_world_3d.is_valid()) {
  3786. if (world_3d.is_valid()) {
  3787. own_world_3d = world_3d->duplicate();
  3788. world_3d->connect_changed(callable_mp(this, &Viewport::_own_world_3d_changed));
  3789. } else {
  3790. own_world_3d.instantiate();
  3791. }
  3792. }
  3793. if (is_inside_tree()) {
  3794. _propagate_enter_world_3d(this);
  3795. }
  3796. if (is_inside_tree()) {
  3797. RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
  3798. }
  3799. _update_audio_listener_3d();
  3800. }
  3801. void Viewport::_own_world_3d_changed() {
  3802. ERR_FAIL_COND(world_3d.is_null());
  3803. ERR_FAIL_COND(own_world_3d.is_null());
  3804. if (is_inside_tree()) {
  3805. _propagate_exit_world_3d(this);
  3806. }
  3807. own_world_3d = world_3d->duplicate();
  3808. if (is_inside_tree()) {
  3809. _propagate_enter_world_3d(this);
  3810. }
  3811. if (is_inside_tree()) {
  3812. RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
  3813. }
  3814. _update_audio_listener_3d();
  3815. }
  3816. void Viewport::set_use_own_world_3d(bool p_use_own_world_3d) {
  3817. ERR_MAIN_THREAD_GUARD;
  3818. if (p_use_own_world_3d == own_world_3d.is_valid()) {
  3819. return;
  3820. }
  3821. if (is_inside_tree()) {
  3822. _propagate_exit_world_3d(this);
  3823. }
  3824. if (p_use_own_world_3d) {
  3825. if (world_3d.is_valid()) {
  3826. own_world_3d = world_3d->duplicate();
  3827. world_3d->connect_changed(callable_mp(this, &Viewport::_own_world_3d_changed));
  3828. } else {
  3829. own_world_3d.instantiate();
  3830. }
  3831. } else {
  3832. own_world_3d = Ref<World3D>();
  3833. if (world_3d.is_valid()) {
  3834. world_3d->disconnect_changed(callable_mp(this, &Viewport::_own_world_3d_changed));
  3835. }
  3836. }
  3837. if (is_inside_tree()) {
  3838. _propagate_enter_world_3d(this);
  3839. }
  3840. if (is_inside_tree()) {
  3841. RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
  3842. }
  3843. _update_audio_listener_3d();
  3844. }
  3845. bool Viewport::is_using_own_world_3d() const {
  3846. ERR_READ_THREAD_GUARD_V(false);
  3847. return own_world_3d.is_valid();
  3848. }
  3849. void Viewport::_propagate_enter_world_3d(Node *p_node) {
  3850. if (p_node != this) {
  3851. if (!p_node->is_inside_tree()) { //may not have entered scene yet
  3852. return;
  3853. }
  3854. if (Object::cast_to<Node3D>(p_node) || Object::cast_to<WorldEnvironment>(p_node)) {
  3855. p_node->notification(Node3D::NOTIFICATION_ENTER_WORLD);
  3856. } else {
  3857. Viewport *v = Object::cast_to<Viewport>(p_node);
  3858. if (v) {
  3859. if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) {
  3860. return;
  3861. }
  3862. }
  3863. }
  3864. }
  3865. for (int i = 0; i < p_node->get_child_count(); i++) {
  3866. _propagate_enter_world_3d(p_node->get_child(i));
  3867. }
  3868. }
  3869. void Viewport::_propagate_exit_world_3d(Node *p_node) {
  3870. if (p_node != this) {
  3871. if (!p_node->is_inside_tree()) { //may have exited scene already
  3872. return;
  3873. }
  3874. if (Object::cast_to<Node3D>(p_node) || Object::cast_to<WorldEnvironment>(p_node)) {
  3875. p_node->notification(Node3D::NOTIFICATION_EXIT_WORLD);
  3876. } else {
  3877. Viewport *v = Object::cast_to<Viewport>(p_node);
  3878. if (v) {
  3879. if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) {
  3880. return;
  3881. }
  3882. }
  3883. }
  3884. }
  3885. for (int i = 0; i < p_node->get_child_count(); i++) {
  3886. _propagate_exit_world_3d(p_node->get_child(i));
  3887. }
  3888. }
  3889. void Viewport::set_use_xr(bool p_use_xr) {
  3890. ERR_MAIN_THREAD_GUARD;
  3891. if (use_xr != p_use_xr) {
  3892. use_xr = p_use_xr;
  3893. RS::get_singleton()->viewport_set_use_xr(viewport, use_xr);
  3894. if (!use_xr) {
  3895. // Set viewport to previous size when exiting XR.
  3896. if (size_allocated) {
  3897. RS::get_singleton()->viewport_set_size(viewport, size.width, size.height);
  3898. } else {
  3899. RS::get_singleton()->viewport_set_size(viewport, 0, 0);
  3900. }
  3901. // Reset render target override textures.
  3902. RID rt = RS::get_singleton()->viewport_get_render_target(viewport);
  3903. RSG::texture_storage->render_target_set_override(rt, RID(), RID(), RID(), RID());
  3904. }
  3905. }
  3906. }
  3907. bool Viewport::is_using_xr() {
  3908. ERR_READ_THREAD_GUARD_V(false);
  3909. return use_xr;
  3910. }
  3911. void Viewport::set_scaling_3d_mode(Scaling3DMode p_scaling_3d_mode) {
  3912. ERR_MAIN_THREAD_GUARD;
  3913. if (scaling_3d_mode == p_scaling_3d_mode) {
  3914. return;
  3915. }
  3916. scaling_3d_mode = p_scaling_3d_mode;
  3917. RS::get_singleton()->viewport_set_scaling_3d_mode(viewport, (RS::ViewportScaling3DMode)(int)p_scaling_3d_mode);
  3918. }
  3919. Viewport::Scaling3DMode Viewport::get_scaling_3d_mode() const {
  3920. ERR_READ_THREAD_GUARD_V(SCALING_3D_MODE_BILINEAR);
  3921. return scaling_3d_mode;
  3922. }
  3923. void Viewport::set_scaling_3d_scale(float p_scaling_3d_scale) {
  3924. ERR_MAIN_THREAD_GUARD;
  3925. // Clamp to reasonable values that are actually useful.
  3926. // Values above 2.0 don't serve a practical purpose since the viewport
  3927. // isn't displayed with mipmaps.
  3928. scaling_3d_scale = CLAMP(p_scaling_3d_scale, 0.1, 2.0);
  3929. RS::get_singleton()->viewport_set_scaling_3d_scale(viewport, scaling_3d_scale);
  3930. }
  3931. float Viewport::get_scaling_3d_scale() const {
  3932. ERR_READ_THREAD_GUARD_V(0);
  3933. return scaling_3d_scale;
  3934. }
  3935. void Viewport::set_fsr_sharpness(float p_fsr_sharpness) {
  3936. ERR_MAIN_THREAD_GUARD;
  3937. if (fsr_sharpness == p_fsr_sharpness) {
  3938. return;
  3939. }
  3940. if (p_fsr_sharpness < 0.0f) {
  3941. p_fsr_sharpness = 0.0f;
  3942. }
  3943. fsr_sharpness = p_fsr_sharpness;
  3944. RS::get_singleton()->viewport_set_fsr_sharpness(viewport, p_fsr_sharpness);
  3945. }
  3946. float Viewport::get_fsr_sharpness() const {
  3947. ERR_READ_THREAD_GUARD_V(0);
  3948. return fsr_sharpness;
  3949. }
  3950. void Viewport::set_texture_mipmap_bias(float p_texture_mipmap_bias) {
  3951. ERR_MAIN_THREAD_GUARD;
  3952. if (texture_mipmap_bias == p_texture_mipmap_bias) {
  3953. return;
  3954. }
  3955. texture_mipmap_bias = p_texture_mipmap_bias;
  3956. RS::get_singleton()->viewport_set_texture_mipmap_bias(viewport, p_texture_mipmap_bias);
  3957. }
  3958. float Viewport::get_texture_mipmap_bias() const {
  3959. ERR_READ_THREAD_GUARD_V(0);
  3960. return texture_mipmap_bias;
  3961. }
  3962. void Viewport::set_anisotropic_filtering_level(AnisotropicFiltering p_anisotropic_filtering_level) {
  3963. ERR_MAIN_THREAD_GUARD;
  3964. if (anisotropic_filtering_level == p_anisotropic_filtering_level) {
  3965. return;
  3966. }
  3967. anisotropic_filtering_level = p_anisotropic_filtering_level;
  3968. RS::get_singleton()->viewport_set_anisotropic_filtering_level(viewport, (RS::ViewportAnisotropicFiltering)(int)p_anisotropic_filtering_level);
  3969. }
  3970. Viewport::AnisotropicFiltering Viewport::get_anisotropic_filtering_level() const {
  3971. ERR_READ_THREAD_GUARD_V(ANISOTROPY_DISABLED);
  3972. return anisotropic_filtering_level;
  3973. }
  3974. #endif // _3D_DISABLED
  3975. void Viewport::_propagate_world_2d_changed(Node *p_node) {
  3976. if (p_node != this) {
  3977. if (Object::cast_to<CanvasItem>(p_node)) {
  3978. p_node->notification(CanvasItem::NOTIFICATION_WORLD_2D_CHANGED);
  3979. } else {
  3980. Viewport *v = Object::cast_to<Viewport>(p_node);
  3981. if (v) {
  3982. if (v->world_2d.is_valid()) {
  3983. return;
  3984. }
  3985. }
  3986. }
  3987. }
  3988. for (int i = 0; i < p_node->get_child_count(); ++i) {
  3989. _propagate_world_2d_changed(p_node->get_child(i));
  3990. }
  3991. }
  3992. void Viewport::_bind_methods() {
  3993. ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d);
  3994. ClassDB::bind_method(D_METHOD("get_world_2d"), &Viewport::get_world_2d);
  3995. ClassDB::bind_method(D_METHOD("find_world_2d"), &Viewport::find_world_2d);
  3996. ClassDB::bind_method(D_METHOD("set_canvas_transform", "xform"), &Viewport::set_canvas_transform);
  3997. ClassDB::bind_method(D_METHOD("get_canvas_transform"), &Viewport::get_canvas_transform);
  3998. ClassDB::bind_method(D_METHOD("set_global_canvas_transform", "xform"), &Viewport::set_global_canvas_transform);
  3999. ClassDB::bind_method(D_METHOD("get_global_canvas_transform"), &Viewport::get_global_canvas_transform);
  4000. ClassDB::bind_method(D_METHOD("get_stretch_transform"), &Viewport::get_stretch_transform);
  4001. ClassDB::bind_method(D_METHOD("get_final_transform"), &Viewport::get_final_transform);
  4002. ClassDB::bind_method(D_METHOD("get_screen_transform"), &Viewport::get_screen_transform);
  4003. ClassDB::bind_method(D_METHOD("get_visible_rect"), &Viewport::get_visible_rect);
  4004. ClassDB::bind_method(D_METHOD("set_transparent_background", "enable"), &Viewport::set_transparent_background);
  4005. ClassDB::bind_method(D_METHOD("has_transparent_background"), &Viewport::has_transparent_background);
  4006. ClassDB::bind_method(D_METHOD("set_use_hdr_2d", "enable"), &Viewport::set_use_hdr_2d);
  4007. ClassDB::bind_method(D_METHOD("is_using_hdr_2d"), &Viewport::is_using_hdr_2d);
  4008. ClassDB::bind_method(D_METHOD("set_msaa_2d", "msaa"), &Viewport::set_msaa_2d);
  4009. ClassDB::bind_method(D_METHOD("get_msaa_2d"), &Viewport::get_msaa_2d);
  4010. ClassDB::bind_method(D_METHOD("set_msaa_3d", "msaa"), &Viewport::set_msaa_3d);
  4011. ClassDB::bind_method(D_METHOD("get_msaa_3d"), &Viewport::get_msaa_3d);
  4012. ClassDB::bind_method(D_METHOD("set_screen_space_aa", "screen_space_aa"), &Viewport::set_screen_space_aa);
  4013. ClassDB::bind_method(D_METHOD("get_screen_space_aa"), &Viewport::get_screen_space_aa);
  4014. ClassDB::bind_method(D_METHOD("set_use_taa", "enable"), &Viewport::set_use_taa);
  4015. ClassDB::bind_method(D_METHOD("is_using_taa"), &Viewport::is_using_taa);
  4016. ClassDB::bind_method(D_METHOD("set_use_debanding", "enable"), &Viewport::set_use_debanding);
  4017. ClassDB::bind_method(D_METHOD("is_using_debanding"), &Viewport::is_using_debanding);
  4018. ClassDB::bind_method(D_METHOD("set_use_occlusion_culling", "enable"), &Viewport::set_use_occlusion_culling);
  4019. ClassDB::bind_method(D_METHOD("is_using_occlusion_culling"), &Viewport::is_using_occlusion_culling);
  4020. ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw);
  4021. ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw);
  4022. ClassDB::bind_method(D_METHOD("get_render_info", "type", "info"), &Viewport::get_render_info);
  4023. ClassDB::bind_method(D_METHOD("get_texture"), &Viewport::get_texture);
  4024. ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking);
  4025. ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
  4026. ClassDB::bind_method(D_METHOD("set_physics_object_picking_sort", "enable"), &Viewport::set_physics_object_picking_sort);
  4027. ClassDB::bind_method(D_METHOD("get_physics_object_picking_sort"), &Viewport::get_physics_object_picking_sort);
  4028. ClassDB::bind_method(D_METHOD("set_physics_object_picking_first_only", "enable"), &Viewport::set_physics_object_picking_first_only);
  4029. ClassDB::bind_method(D_METHOD("get_physics_object_picking_first_only"), &Viewport::get_physics_object_picking_first_only);
  4030. ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid);
  4031. ClassDB::bind_method(D_METHOD("push_text_input", "text"), &Viewport::push_text_input);
  4032. ClassDB::bind_method(D_METHOD("push_input", "event", "in_local_coords"), &Viewport::push_input, DEFVAL(false));
  4033. #ifndef DISABLE_DEPRECATED
  4034. ClassDB::bind_method(D_METHOD("push_unhandled_input", "event", "in_local_coords"), &Viewport::push_unhandled_input, DEFVAL(false));
  4035. #endif // DISABLE_DEPRECATED
  4036. ClassDB::bind_method(D_METHOD("notify_mouse_entered"), &Viewport::notify_mouse_entered);
  4037. ClassDB::bind_method(D_METHOD("notify_mouse_exited"), &Viewport::notify_mouse_exited);
  4038. ClassDB::bind_method(D_METHOD("get_mouse_position"), &Viewport::get_mouse_position);
  4039. ClassDB::bind_method(D_METHOD("warp_mouse", "position"), &Viewport::warp_mouse);
  4040. ClassDB::bind_method(D_METHOD("update_mouse_cursor_state"), &Viewport::update_mouse_cursor_state);
  4041. ClassDB::bind_method(D_METHOD("gui_cancel_drag"), &Viewport::gui_cancel_drag);
  4042. ClassDB::bind_method(D_METHOD("gui_get_drag_data"), &Viewport::gui_get_drag_data);
  4043. ClassDB::bind_method(D_METHOD("gui_is_dragging"), &Viewport::gui_is_dragging);
  4044. ClassDB::bind_method(D_METHOD("gui_is_drag_successful"), &Viewport::gui_is_drag_successful);
  4045. ClassDB::bind_method(D_METHOD("gui_release_focus"), &Viewport::gui_release_focus);
  4046. ClassDB::bind_method(D_METHOD("gui_get_focus_owner"), &Viewport::gui_get_focus_owner);
  4047. ClassDB::bind_method(D_METHOD("gui_get_hovered_control"), &Viewport::gui_get_hovered_control);
  4048. ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input);
  4049. ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled);
  4050. ClassDB::bind_method(D_METHOD("_gui_remove_focus_for_window"), &Viewport::_gui_remove_focus_for_window);
  4051. ClassDB::bind_method(D_METHOD("set_positional_shadow_atlas_size", "size"), &Viewport::set_positional_shadow_atlas_size);
  4052. ClassDB::bind_method(D_METHOD("get_positional_shadow_atlas_size"), &Viewport::get_positional_shadow_atlas_size);
  4053. ClassDB::bind_method(D_METHOD("set_positional_shadow_atlas_16_bits", "enable"), &Viewport::set_positional_shadow_atlas_16_bits);
  4054. ClassDB::bind_method(D_METHOD("get_positional_shadow_atlas_16_bits"), &Viewport::get_positional_shadow_atlas_16_bits);
  4055. ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels);
  4056. ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled);
  4057. ClassDB::bind_method(D_METHOD("set_snap_2d_transforms_to_pixel", "enabled"), &Viewport::set_snap_2d_transforms_to_pixel);
  4058. ClassDB::bind_method(D_METHOD("is_snap_2d_transforms_to_pixel_enabled"), &Viewport::is_snap_2d_transforms_to_pixel_enabled);
  4059. ClassDB::bind_method(D_METHOD("set_snap_2d_vertices_to_pixel", "enabled"), &Viewport::set_snap_2d_vertices_to_pixel);
  4060. ClassDB::bind_method(D_METHOD("is_snap_2d_vertices_to_pixel_enabled"), &Viewport::is_snap_2d_vertices_to_pixel_enabled);
  4061. ClassDB::bind_method(D_METHOD("set_positional_shadow_atlas_quadrant_subdiv", "quadrant", "subdiv"), &Viewport::set_positional_shadow_atlas_quadrant_subdiv);
  4062. ClassDB::bind_method(D_METHOD("get_positional_shadow_atlas_quadrant_subdiv", "quadrant"), &Viewport::get_positional_shadow_atlas_quadrant_subdiv);
  4063. ClassDB::bind_method(D_METHOD("set_input_as_handled"), &Viewport::set_input_as_handled);
  4064. ClassDB::bind_method(D_METHOD("is_input_handled"), &Viewport::is_input_handled);
  4065. ClassDB::bind_method(D_METHOD("set_handle_input_locally", "enable"), &Viewport::set_handle_input_locally);
  4066. ClassDB::bind_method(D_METHOD("is_handling_input_locally"), &Viewport::is_handling_input_locally);
  4067. ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_filter", "mode"), &Viewport::set_default_canvas_item_texture_filter);
  4068. ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_filter"), &Viewport::get_default_canvas_item_texture_filter);
  4069. ClassDB::bind_method(D_METHOD("set_embedding_subwindows", "enable"), &Viewport::set_embedding_subwindows);
  4070. ClassDB::bind_method(D_METHOD("is_embedding_subwindows"), &Viewport::is_embedding_subwindows);
  4071. ClassDB::bind_method(D_METHOD("get_embedded_subwindows"), &Viewport::get_embedded_subwindows);
  4072. ClassDB::bind_method(D_METHOD("set_canvas_cull_mask", "mask"), &Viewport::set_canvas_cull_mask);
  4073. ClassDB::bind_method(D_METHOD("get_canvas_cull_mask"), &Viewport::get_canvas_cull_mask);
  4074. ClassDB::bind_method(D_METHOD("set_canvas_cull_mask_bit", "layer", "enable"), &Viewport::set_canvas_cull_mask_bit);
  4075. ClassDB::bind_method(D_METHOD("get_canvas_cull_mask_bit", "layer"), &Viewport::get_canvas_cull_mask_bit);
  4076. ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_repeat", "mode"), &Viewport::set_default_canvas_item_texture_repeat);
  4077. ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_repeat"), &Viewport::get_default_canvas_item_texture_repeat);
  4078. ClassDB::bind_method(D_METHOD("set_sdf_oversize", "oversize"), &Viewport::set_sdf_oversize);
  4079. ClassDB::bind_method(D_METHOD("get_sdf_oversize"), &Viewport::get_sdf_oversize);
  4080. ClassDB::bind_method(D_METHOD("set_sdf_scale", "scale"), &Viewport::set_sdf_scale);
  4081. ClassDB::bind_method(D_METHOD("get_sdf_scale"), &Viewport::get_sdf_scale);
  4082. ClassDB::bind_method(D_METHOD("set_mesh_lod_threshold", "pixels"), &Viewport::set_mesh_lod_threshold);
  4083. ClassDB::bind_method(D_METHOD("get_mesh_lod_threshold"), &Viewport::get_mesh_lod_threshold);
  4084. ClassDB::bind_method(D_METHOD("_process_picking"), &Viewport::_process_picking);
  4085. ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d);
  4086. ClassDB::bind_method(D_METHOD("is_audio_listener_2d"), &Viewport::is_audio_listener_2d);
  4087. ClassDB::bind_method(D_METHOD("get_audio_listener_2d"), &Viewport::get_audio_listener_2d);
  4088. ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d);
  4089. #ifndef _3D_DISABLED
  4090. ClassDB::bind_method(D_METHOD("set_world_3d", "world_3d"), &Viewport::set_world_3d);
  4091. ClassDB::bind_method(D_METHOD("get_world_3d"), &Viewport::get_world_3d);
  4092. ClassDB::bind_method(D_METHOD("find_world_3d"), &Viewport::find_world_3d);
  4093. ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d);
  4094. ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d);
  4095. ClassDB::bind_method(D_METHOD("get_audio_listener_3d"), &Viewport::get_audio_listener_3d);
  4096. ClassDB::bind_method(D_METHOD("get_camera_3d"), &Viewport::get_camera_3d);
  4097. ClassDB::bind_method(D_METHOD("set_as_audio_listener_3d", "enable"), &Viewport::set_as_audio_listener_3d);
  4098. ClassDB::bind_method(D_METHOD("is_audio_listener_3d"), &Viewport::is_audio_listener_3d);
  4099. ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d);
  4100. ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled);
  4101. ClassDB::bind_method(D_METHOD("set_use_xr", "use"), &Viewport::set_use_xr);
  4102. ClassDB::bind_method(D_METHOD("is_using_xr"), &Viewport::is_using_xr);
  4103. ClassDB::bind_method(D_METHOD("set_scaling_3d_mode", "scaling_3d_mode"), &Viewport::set_scaling_3d_mode);
  4104. ClassDB::bind_method(D_METHOD("get_scaling_3d_mode"), &Viewport::get_scaling_3d_mode);
  4105. ClassDB::bind_method(D_METHOD("set_scaling_3d_scale", "scale"), &Viewport::set_scaling_3d_scale);
  4106. ClassDB::bind_method(D_METHOD("get_scaling_3d_scale"), &Viewport::get_scaling_3d_scale);
  4107. ClassDB::bind_method(D_METHOD("set_fsr_sharpness", "fsr_sharpness"), &Viewport::set_fsr_sharpness);
  4108. ClassDB::bind_method(D_METHOD("get_fsr_sharpness"), &Viewport::get_fsr_sharpness);
  4109. ClassDB::bind_method(D_METHOD("set_texture_mipmap_bias", "texture_mipmap_bias"), &Viewport::set_texture_mipmap_bias);
  4110. ClassDB::bind_method(D_METHOD("get_texture_mipmap_bias"), &Viewport::get_texture_mipmap_bias);
  4111. ClassDB::bind_method(D_METHOD("set_anisotropic_filtering_level", "anisotropic_filtering_level"), &Viewport::set_anisotropic_filtering_level);
  4112. ClassDB::bind_method(D_METHOD("get_anisotropic_filtering_level"), &Viewport::get_anisotropic_filtering_level);
  4113. ClassDB::bind_method(D_METHOD("set_vrs_mode", "mode"), &Viewport::set_vrs_mode);
  4114. ClassDB::bind_method(D_METHOD("get_vrs_mode"), &Viewport::get_vrs_mode);
  4115. ClassDB::bind_method(D_METHOD("set_vrs_update_mode", "mode"), &Viewport::set_vrs_update_mode);
  4116. ClassDB::bind_method(D_METHOD("get_vrs_update_mode"), &Viewport::get_vrs_update_mode);
  4117. ClassDB::bind_method(D_METHOD("set_vrs_texture", "texture"), &Viewport::set_vrs_texture);
  4118. ClassDB::bind_method(D_METHOD("get_vrs_texture"), &Viewport::get_vrs_texture);
  4119. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
  4120. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr");
  4121. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
  4122. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d");
  4123. #endif // _3D_DISABLED
  4124. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", PROPERTY_USAGE_NONE), "set_world_2d", "get_world_2d");
  4125. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background");
  4126. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
  4127. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled");
  4128. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled");
  4129. ADD_GROUP("Rendering", "");
  4130. ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa_2d", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Average),4× (Slow),8× (Slowest)")), "set_msaa_2d", "get_msaa_2d");
  4131. ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa_3d", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Average),4× (Slow),8× (Slowest)")), "set_msaa_3d", "get_msaa_3d");
  4132. ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa");
  4133. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_taa"), "set_use_taa", "is_using_taa");
  4134. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding");
  4135. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_occlusion_culling"), "set_use_occlusion_culling", "is_using_occlusion_culling");
  4136. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mesh_lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_mesh_lod_threshold", "get_mesh_lod_threshold");
  4137. ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Lighting,Overdraw,Wireframe,Normal Buffer,VoxelGI Albedo,VoxelGI Lighting,VoxelGI Emission,Shadow Atlas,Directional Shadow Map,Scene Luminance,SSAO,SSIL,Directional Shadow Splits,Decal Atlas,SDFGI Cascades,SDFGI Probes,VoxelGI/SDFGI Buffer,Disable Mesh LOD,OmniLight3D Cluster,SpotLight3D Cluster,Decal Cluster,ReflectionProbe Cluster,Occlusion Culling Buffer,Motion Vectors,Internal Buffer"), "set_debug_draw", "get_debug_draw");
  4138. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr_2d"), "set_use_hdr_2d", "is_using_hdr_2d");
  4139. #ifndef _3D_DISABLED
  4140. ADD_GROUP("Scaling 3D", "");
  4141. ADD_PROPERTY(PropertyInfo(Variant::INT, "scaling_3d_mode", PROPERTY_HINT_ENUM, "Bilinear (Fastest),FSR 1.0 (Fast),FSR 2.2 (Slow),MetalFX (Spatial),MetalFX (Temporal)"), "set_scaling_3d_mode", "get_scaling_3d_mode");
  4142. 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");
  4143. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_mipmap_bias", PROPERTY_HINT_RANGE, "-2,2,0.001"), "set_texture_mipmap_bias", "get_texture_mipmap_bias");
  4144. ADD_PROPERTY(PropertyInfo(Variant::INT, "anisotropic_filtering_level", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Faster),4× (Fast),8× (Average),16x (Slow)")), "set_anisotropic_filtering_level", "get_anisotropic_filtering_level");
  4145. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fsr_sharpness", PROPERTY_HINT_RANGE, "0,2,0.1"), "set_fsr_sharpness", "get_fsr_sharpness");
  4146. ADD_GROUP("Variable Rate Shading", "vrs_");
  4147. ADD_PROPERTY(PropertyInfo(Variant::INT, "vrs_mode", PROPERTY_HINT_ENUM, "Disabled,Texture,Depth buffer,XR"), "set_vrs_mode", "get_vrs_mode");
  4148. ADD_PROPERTY(PropertyInfo(Variant::INT, "vrs_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,Always"), "set_vrs_update_mode", "get_vrs_update_mode");
  4149. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "vrs_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_vrs_texture", "get_vrs_texture");
  4150. #endif
  4151. ADD_GROUP("Canvas Items", "canvas_item_");
  4152. ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Linear Mipmap,Nearest Mipmap"), "set_default_canvas_item_texture_filter", "get_default_canvas_item_texture_filter");
  4153. ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_item_default_texture_repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirror"), "set_default_canvas_item_texture_repeat", "get_default_canvas_item_texture_repeat");
  4154. ADD_GROUP("Audio Listener", "audio_listener_");
  4155. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_2d"), "set_as_audio_listener_2d", "is_audio_listener_2d");
  4156. #ifndef _3D_DISABLED
  4157. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_3d"), "set_as_audio_listener_3d", "is_audio_listener_3d");
  4158. #endif // _3D_DISABLED
  4159. ADD_GROUP("Physics", "physics_");
  4160. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking");
  4161. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_sort"), "set_physics_object_picking_sort", "get_physics_object_picking_sort");
  4162. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_first_only"), "set_physics_object_picking_first_only", "get_physics_object_picking_first_only");
  4163. ADD_GROUP("GUI", "gui_");
  4164. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled");
  4165. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled");
  4166. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_embed_subwindows"), "set_embedding_subwindows", "is_embedding_subwindows");
  4167. ADD_GROUP("SDF", "sdf_");
  4168. ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%"), "set_sdf_oversize", "get_sdf_oversize");
  4169. ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale");
  4170. ADD_GROUP("Positional Shadow Atlas", "positional_shadow_atlas_");
  4171. ADD_PROPERTY(PropertyInfo(Variant::INT, "positional_shadow_atlas_size"), "set_positional_shadow_atlas_size", "get_positional_shadow_atlas_size");
  4172. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "positional_shadow_atlas_16_bits"), "set_positional_shadow_atlas_16_bits", "get_positional_shadow_atlas_16_bits");
  4173. ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 0);
  4174. ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 1);
  4175. ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 2);
  4176. ADD_PROPERTYI(PropertyInfo(Variant::INT, "positional_shadow_atlas_quad_3", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_positional_shadow_atlas_quadrant_subdiv", "get_positional_shadow_atlas_quadrant_subdiv", 3);
  4177. ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "canvas_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_canvas_transform", "get_canvas_transform");
  4178. ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "global_canvas_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_global_canvas_transform", "get_global_canvas_transform");
  4179. ADD_PROPERTY(PropertyInfo(Variant::INT, "canvas_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_canvas_cull_mask", "get_canvas_cull_mask");
  4180. ADD_SIGNAL(MethodInfo("size_changed"));
  4181. ADD_SIGNAL(MethodInfo("gui_focus_changed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
  4182. BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
  4183. BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1);
  4184. BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_4);
  4185. BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_16);
  4186. BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_64);
  4187. BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_256);
  4188. BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024);
  4189. BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
  4190. BIND_ENUM_CONSTANT(SCALING_3D_MODE_BILINEAR);
  4191. BIND_ENUM_CONSTANT(SCALING_3D_MODE_FSR);
  4192. BIND_ENUM_CONSTANT(SCALING_3D_MODE_FSR2);
  4193. BIND_ENUM_CONSTANT(SCALING_3D_MODE_METALFX_SPATIAL);
  4194. BIND_ENUM_CONSTANT(SCALING_3D_MODE_METALFX_TEMPORAL);
  4195. BIND_ENUM_CONSTANT(SCALING_3D_MODE_MAX);
  4196. BIND_ENUM_CONSTANT(MSAA_DISABLED);
  4197. BIND_ENUM_CONSTANT(MSAA_2X);
  4198. BIND_ENUM_CONSTANT(MSAA_4X);
  4199. BIND_ENUM_CONSTANT(MSAA_8X);
  4200. BIND_ENUM_CONSTANT(MSAA_MAX);
  4201. BIND_ENUM_CONSTANT(ANISOTROPY_DISABLED);
  4202. BIND_ENUM_CONSTANT(ANISOTROPY_2X);
  4203. BIND_ENUM_CONSTANT(ANISOTROPY_4X);
  4204. BIND_ENUM_CONSTANT(ANISOTROPY_8X);
  4205. BIND_ENUM_CONSTANT(ANISOTROPY_16X);
  4206. BIND_ENUM_CONSTANT(ANISOTROPY_MAX);
  4207. BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_DISABLED);
  4208. BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_FXAA);
  4209. BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_MAX);
  4210. BIND_ENUM_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME);
  4211. BIND_ENUM_CONSTANT(RENDER_INFO_PRIMITIVES_IN_FRAME);
  4212. BIND_ENUM_CONSTANT(RENDER_INFO_DRAW_CALLS_IN_FRAME);
  4213. BIND_ENUM_CONSTANT(RENDER_INFO_MAX);
  4214. BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_VISIBLE);
  4215. BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_SHADOW);
  4216. BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_CANVAS);
  4217. BIND_ENUM_CONSTANT(RENDER_INFO_TYPE_MAX);
  4218. BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED);
  4219. BIND_ENUM_CONSTANT(DEBUG_DRAW_UNSHADED);
  4220. BIND_ENUM_CONSTANT(DEBUG_DRAW_LIGHTING);
  4221. BIND_ENUM_CONSTANT(DEBUG_DRAW_OVERDRAW);
  4222. BIND_ENUM_CONSTANT(DEBUG_DRAW_WIREFRAME);
  4223. BIND_ENUM_CONSTANT(DEBUG_DRAW_NORMAL_BUFFER);
  4224. BIND_ENUM_CONSTANT(DEBUG_DRAW_VOXEL_GI_ALBEDO);
  4225. BIND_ENUM_CONSTANT(DEBUG_DRAW_VOXEL_GI_LIGHTING);
  4226. BIND_ENUM_CONSTANT(DEBUG_DRAW_VOXEL_GI_EMISSION);
  4227. BIND_ENUM_CONSTANT(DEBUG_DRAW_SHADOW_ATLAS);
  4228. BIND_ENUM_CONSTANT(DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS);
  4229. BIND_ENUM_CONSTANT(DEBUG_DRAW_SCENE_LUMINANCE);
  4230. BIND_ENUM_CONSTANT(DEBUG_DRAW_SSAO);
  4231. BIND_ENUM_CONSTANT(DEBUG_DRAW_SSIL);
  4232. BIND_ENUM_CONSTANT(DEBUG_DRAW_PSSM_SPLITS);
  4233. BIND_ENUM_CONSTANT(DEBUG_DRAW_DECAL_ATLAS);
  4234. BIND_ENUM_CONSTANT(DEBUG_DRAW_SDFGI);
  4235. BIND_ENUM_CONSTANT(DEBUG_DRAW_SDFGI_PROBES);
  4236. BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_BUFFER);
  4237. BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLE_LOD);
  4238. BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_OMNI_LIGHTS);
  4239. BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_SPOT_LIGHTS);
  4240. BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_DECALS);
  4241. BIND_ENUM_CONSTANT(DEBUG_DRAW_CLUSTER_REFLECTION_PROBES);
  4242. BIND_ENUM_CONSTANT(DEBUG_DRAW_OCCLUDERS)
  4243. BIND_ENUM_CONSTANT(DEBUG_DRAW_MOTION_VECTORS)
  4244. BIND_ENUM_CONSTANT(DEBUG_DRAW_INTERNAL_BUFFER);
  4245. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
  4246. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR);
  4247. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
  4248. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
  4249. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX);
  4250. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
  4251. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
  4252. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
  4253. BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX);
  4254. BIND_ENUM_CONSTANT(SDF_OVERSIZE_100_PERCENT);
  4255. BIND_ENUM_CONSTANT(SDF_OVERSIZE_120_PERCENT);
  4256. BIND_ENUM_CONSTANT(SDF_OVERSIZE_150_PERCENT);
  4257. BIND_ENUM_CONSTANT(SDF_OVERSIZE_200_PERCENT);
  4258. BIND_ENUM_CONSTANT(SDF_OVERSIZE_MAX);
  4259. BIND_ENUM_CONSTANT(SDF_SCALE_100_PERCENT);
  4260. BIND_ENUM_CONSTANT(SDF_SCALE_50_PERCENT);
  4261. BIND_ENUM_CONSTANT(SDF_SCALE_25_PERCENT);
  4262. BIND_ENUM_CONSTANT(SDF_SCALE_MAX);
  4263. BIND_ENUM_CONSTANT(VRS_DISABLED);
  4264. BIND_ENUM_CONSTANT(VRS_TEXTURE);
  4265. BIND_ENUM_CONSTANT(VRS_XR);
  4266. BIND_ENUM_CONSTANT(VRS_MAX);
  4267. BIND_ENUM_CONSTANT(VRS_UPDATE_DISABLED);
  4268. BIND_ENUM_CONSTANT(VRS_UPDATE_ONCE);
  4269. BIND_ENUM_CONSTANT(VRS_UPDATE_ALWAYS);
  4270. BIND_ENUM_CONSTANT(VRS_UPDATE_MAX);
  4271. }
  4272. void Viewport::_validate_property(PropertyInfo &p_property) const {
  4273. if (vrs_mode != VRS_TEXTURE && (p_property.name == "vrs_texture")) {
  4274. p_property.usage = PROPERTY_USAGE_NO_EDITOR;
  4275. }
  4276. if (vrs_mode == VRS_DISABLED && (p_property.name == "vrs_update_mode")) {
  4277. p_property.usage = PROPERTY_USAGE_NO_EDITOR;
  4278. }
  4279. }
  4280. Viewport::Viewport() {
  4281. world_2d.instantiate();
  4282. world_2d->register_viewport(this);
  4283. viewport = RenderingServer::get_singleton()->viewport_create();
  4284. texture_rid = RenderingServer::get_singleton()->viewport_get_texture(viewport);
  4285. default_texture.instantiate();
  4286. default_texture->vp = this;
  4287. viewport_textures.insert(default_texture.ptr());
  4288. default_texture->proxy = RS::get_singleton()->texture_proxy_create(texture_rid);
  4289. canvas_layers.insert(nullptr); // This eases picking code (interpreted as the canvas of the Viewport).
  4290. set_positional_shadow_atlas_size(positional_shadow_atlas_size);
  4291. for (int i = 0; i < 4; i++) {
  4292. positional_shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX;
  4293. }
  4294. set_positional_shadow_atlas_quadrant_subdiv(0, SHADOW_ATLAS_QUADRANT_SUBDIV_4);
  4295. set_positional_shadow_atlas_quadrant_subdiv(1, SHADOW_ATLAS_QUADRANT_SUBDIV_4);
  4296. set_positional_shadow_atlas_quadrant_subdiv(2, SHADOW_ATLAS_QUADRANT_SUBDIV_16);
  4297. set_positional_shadow_atlas_quadrant_subdiv(3, SHADOW_ATLAS_QUADRANT_SUBDIV_64);
  4298. set_mesh_lod_threshold(mesh_lod_threshold);
  4299. String id = itos(get_instance_id());
  4300. input_group = "_vp_input" + id;
  4301. unhandled_input_group = "_vp_unhandled_input" + id;
  4302. shortcut_input_group = "_vp_shortcut_input" + id;
  4303. unhandled_key_input_group = "_vp_unhandled_key_input" + id;
  4304. // Window tooltip.
  4305. gui.tooltip_delay = GLOBAL_GET("gui/timers/tooltip_delay_sec");
  4306. #ifndef _3D_DISABLED
  4307. set_scaling_3d_mode((Viewport::Scaling3DMode)(int)GLOBAL_GET("rendering/scaling_3d/mode"));
  4308. set_scaling_3d_scale(GLOBAL_GET("rendering/scaling_3d/scale"));
  4309. set_fsr_sharpness((float)GLOBAL_GET("rendering/scaling_3d/fsr_sharpness"));
  4310. set_texture_mipmap_bias((float)GLOBAL_GET("rendering/textures/default_filters/texture_mipmap_bias"));
  4311. set_anisotropic_filtering_level((Viewport::AnisotropicFiltering)(int)GLOBAL_GET("rendering/textures/default_filters/anisotropic_filtering_level"));
  4312. #endif // _3D_DISABLED
  4313. set_sdf_oversize(sdf_oversize); // Set to server.
  4314. // Physics interpolation mode for viewports is a special case.
  4315. // Typically viewports will be housed within Controls,
  4316. // and Controls default to PHYSICS_INTERPOLATION_MODE_OFF.
  4317. // Viewports can thus inherit physics interpolation OFF, which is unexpected.
  4318. // Setting to ON allows each viewport to have a fresh interpolation state.
  4319. set_physics_interpolation_mode(Node::PHYSICS_INTERPOLATION_MODE_ON);
  4320. }
  4321. Viewport::~Viewport() {
  4322. // Erase itself from viewport textures.
  4323. for (ViewportTexture *E : viewport_textures) {
  4324. E->vp = nullptr;
  4325. }
  4326. if (world_2d.is_valid()) {
  4327. world_2d->remove_viewport(this);
  4328. }
  4329. ERR_FAIL_NULL(RenderingServer::get_singleton());
  4330. RenderingServer::get_singleton()->free(viewport);
  4331. }
  4332. /////////////////////////////////
  4333. void SubViewport::set_size(const Size2i &p_size) {
  4334. ERR_MAIN_THREAD_GUARD;
  4335. _internal_set_size(p_size);
  4336. }
  4337. void SubViewport::set_size_force(const Size2i &p_size) {
  4338. ERR_MAIN_THREAD_GUARD;
  4339. // Use only for setting the size from the parent SubViewportContainer with enabled stretch mode.
  4340. // Don't expose function to scripting.
  4341. _internal_set_size(p_size, true);
  4342. }
  4343. void SubViewport::_internal_set_size(const Size2i &p_size, bool p_force) {
  4344. SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
  4345. if (!p_force && c && c->is_stretch_enabled()) {
  4346. #ifdef DEBUG_ENABLED
  4347. WARN_PRINT("Can't change the size of a `SubViewport` with a `SubViewportContainer` parent that has `stretch` enabled. Set `SubViewportContainer.stretch` to `false` to allow changing the size manually.");
  4348. #endif // DEBUG_ENABLED
  4349. return;
  4350. }
  4351. _set_size(p_size, _get_size_2d_override(), true);
  4352. if (c) {
  4353. c->update_minimum_size();
  4354. c->queue_redraw();
  4355. }
  4356. }
  4357. Size2i SubViewport::get_size() const {
  4358. ERR_READ_THREAD_GUARD_V(Size2());
  4359. return _get_size();
  4360. }
  4361. void SubViewport::set_size_2d_override(const Size2i &p_size) {
  4362. ERR_MAIN_THREAD_GUARD;
  4363. _set_size(_get_size(), p_size, true);
  4364. }
  4365. Size2i SubViewport::get_size_2d_override() const {
  4366. ERR_READ_THREAD_GUARD_V(Size2i());
  4367. return _get_size_2d_override();
  4368. }
  4369. void SubViewport::set_size_2d_override_stretch(bool p_enable) {
  4370. ERR_MAIN_THREAD_GUARD;
  4371. if (p_enable == size_2d_override_stretch) {
  4372. return;
  4373. }
  4374. size_2d_override_stretch = p_enable;
  4375. _set_size(_get_size(), _get_size_2d_override(), true);
  4376. }
  4377. bool SubViewport::is_size_2d_override_stretch_enabled() const {
  4378. ERR_READ_THREAD_GUARD_V(false);
  4379. return size_2d_override_stretch;
  4380. }
  4381. void SubViewport::set_update_mode(UpdateMode p_mode) {
  4382. ERR_MAIN_THREAD_GUARD;
  4383. update_mode = p_mode;
  4384. RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::ViewportUpdateMode(p_mode));
  4385. }
  4386. SubViewport::UpdateMode SubViewport::get_update_mode() const {
  4387. ERR_READ_THREAD_GUARD_V(UPDATE_DISABLED);
  4388. return update_mode;
  4389. }
  4390. void SubViewport::set_clear_mode(ClearMode p_mode) {
  4391. ERR_MAIN_THREAD_GUARD;
  4392. clear_mode = p_mode;
  4393. RS::get_singleton()->viewport_set_clear_mode(get_viewport_rid(), RS::ViewportClearMode(p_mode));
  4394. }
  4395. SubViewport::ClearMode SubViewport::get_clear_mode() const {
  4396. ERR_READ_THREAD_GUARD_V(CLEAR_MODE_ALWAYS);
  4397. return clear_mode;
  4398. }
  4399. DisplayServer::WindowID SubViewport::get_window_id() const {
  4400. ERR_READ_THREAD_GUARD_V(DisplayServer::INVALID_WINDOW_ID);
  4401. return DisplayServer::INVALID_WINDOW_ID;
  4402. }
  4403. Transform2D SubViewport::get_screen_transform_internal(bool p_absolute_position) const {
  4404. ERR_READ_THREAD_GUARD_V(Transform2D());
  4405. Transform2D container_transform;
  4406. SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
  4407. if (c) {
  4408. if (c->is_stretch_enabled()) {
  4409. container_transform.scale(Vector2(c->get_stretch_shrink(), c->get_stretch_shrink()));
  4410. }
  4411. container_transform = c->get_viewport()->get_screen_transform_internal(p_absolute_position) * c->get_global_transform_with_canvas() * container_transform;
  4412. } else {
  4413. WARN_PRINT_ONCE("SubViewport is not a child of a SubViewportContainer. get_screen_transform doesn't return the actual screen position.");
  4414. }
  4415. return container_transform * get_final_transform();
  4416. }
  4417. Transform2D SubViewport::get_popup_base_transform() const {
  4418. ERR_READ_THREAD_GUARD_V(Transform2D());
  4419. if (is_embedding_subwindows()) {
  4420. return Transform2D();
  4421. }
  4422. SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
  4423. if (!c) {
  4424. return get_final_transform();
  4425. }
  4426. Transform2D container_transform;
  4427. if (c->is_stretch_enabled()) {
  4428. container_transform.scale(Vector2(c->get_stretch_shrink(), c->get_stretch_shrink()));
  4429. }
  4430. return c->get_screen_transform() * container_transform * get_final_transform();
  4431. }
  4432. Viewport *SubViewport::get_section_root_viewport() const {
  4433. if (Object::cast_to<SubViewportContainer>(get_parent()) && get_parent()->get_viewport()) {
  4434. return get_parent()->get_viewport()->get_section_root_viewport();
  4435. }
  4436. SubViewport *vp = const_cast<SubViewport *>(this);
  4437. return vp;
  4438. }
  4439. bool SubViewport::is_attached_in_viewport() const {
  4440. return Object::cast_to<SubViewportContainer>(get_parent());
  4441. }
  4442. void SubViewport::_notification(int p_what) {
  4443. ERR_MAIN_THREAD_GUARD;
  4444. switch (p_what) {
  4445. case NOTIFICATION_ENTER_TREE: {
  4446. RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
  4447. SubViewportContainer *parent_svc = Object::cast_to<SubViewportContainer>(get_parent());
  4448. if (parent_svc) {
  4449. parent_svc->recalc_force_viewport_sizes();
  4450. }
  4451. } break;
  4452. case NOTIFICATION_EXIT_TREE: {
  4453. RS::get_singleton()->viewport_set_active(get_viewport_rid(), false);
  4454. } break;
  4455. }
  4456. }
  4457. void SubViewport::_bind_methods() {
  4458. ClassDB::bind_method(D_METHOD("set_size", "size"), &SubViewport::set_size);
  4459. ClassDB::bind_method(D_METHOD("get_size"), &SubViewport::get_size);
  4460. ClassDB::bind_method(D_METHOD("set_size_2d_override", "size"), &SubViewport::set_size_2d_override);
  4461. ClassDB::bind_method(D_METHOD("get_size_2d_override"), &SubViewport::get_size_2d_override);
  4462. ClassDB::bind_method(D_METHOD("set_size_2d_override_stretch", "enable"), &SubViewport::set_size_2d_override_stretch);
  4463. ClassDB::bind_method(D_METHOD("is_size_2d_override_stretch_enabled"), &SubViewport::is_size_2d_override_stretch_enabled);
  4464. ClassDB::bind_method(D_METHOD("set_update_mode", "mode"), &SubViewport::set_update_mode);
  4465. ClassDB::bind_method(D_METHOD("get_update_mode"), &SubViewport::get_update_mode);
  4466. ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &SubViewport::set_clear_mode);
  4467. ClassDB::bind_method(D_METHOD("get_clear_mode"), &SubViewport::get_clear_mode);
  4468. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size", PROPERTY_HINT_NONE, "suffix:px"), "set_size", "get_size");
  4469. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size_2d_override", PROPERTY_HINT_NONE, "suffix:px"), "set_size_2d_override", "get_size_2d_override");
  4470. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_2d_override_stretch"), "set_size_2d_override_stretch", "is_size_2d_override_stretch_enabled");
  4471. ADD_GROUP("Render Target", "render_target_");
  4472. ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode");
  4473. ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,When Parent Visible,Always"), "set_update_mode", "get_update_mode");
  4474. BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS);
  4475. BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER);
  4476. BIND_ENUM_CONSTANT(CLEAR_MODE_ONCE);
  4477. BIND_ENUM_CONSTANT(UPDATE_DISABLED);
  4478. BIND_ENUM_CONSTANT(UPDATE_ONCE);
  4479. BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE);
  4480. BIND_ENUM_CONSTANT(UPDATE_WHEN_PARENT_VISIBLE);
  4481. BIND_ENUM_CONSTANT(UPDATE_ALWAYS);
  4482. }
  4483. void SubViewport::_validate_property(PropertyInfo &p_property) const {
  4484. if (p_property.name == "size") {
  4485. SubViewportContainer *parent_svc = Object::cast_to<SubViewportContainer>(get_parent());
  4486. if (parent_svc && parent_svc->is_stretch_enabled()) {
  4487. p_property.usage = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY;
  4488. } else {
  4489. p_property.usage = PROPERTY_USAGE_DEFAULT;
  4490. }
  4491. }
  4492. }
  4493. SubViewport::SubViewport() {
  4494. RS::get_singleton()->viewport_set_size(get_viewport_rid(), get_size().width, get_size().height);
  4495. }
  4496. SubViewport::~SubViewport() {}