llviewerregion.cpp 102 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746
  1. /**
  2. * @file llviewerregion.cpp
  3. * @brief Implementation of the LLViewerRegion class.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewergpl$
  6. *
  7. * Copyright (c) 2000-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llviewerregion.h"
  34. #include "llapp.h"
  35. #include "llbbox.h"
  36. #include "llcorehttputil.h"
  37. #include "lldir.h"
  38. #include "llfasttimer.h"
  39. #include "llhost.h"
  40. #include "llhttpnode.h"
  41. #include "llregionhandle.h"
  42. #include "llsdserialize.h"
  43. #include "llsdutil.h"
  44. #include "llsurface.h"
  45. #include "lltrans.h"
  46. #include "llmessage.h"
  47. #include "llagent.h"
  48. #include "llappviewer.h" // For gFrameTimeSeconds
  49. #include "llavatartracker.h"
  50. #include "llcommandhandler.h"
  51. #include "llenvironment.h"
  52. #include "lleventpoll.h"
  53. #include "llfloatergodtools.h"
  54. #include "llfloaterregioninfo.h"
  55. #include "hbfloatersearch.h"
  56. #include "llgltfmateriallist.h"
  57. #include "llgridmanager.h" // For gIsInSecondLife
  58. #include "llselectmgr.h" // For dialog_refresh_all()
  59. #include "llspatialpartition.h"
  60. #include "llstartup.h"
  61. #include "llurldispatcher.h"
  62. #include "llviewercontrol.h"
  63. #include "llviewerdisplay.h" // For gTeleportDisplay
  64. #include "llviewermenu.h" // For update_upload_costs_in_menus()
  65. #include "llviewerobjectlist.h"
  66. #include "llvieweroctree.h"
  67. #include "llviewerparcelmgr.h"
  68. #include "llviewerparceloverlay.h"
  69. #include "llviewerwindow.h" // For getProgressView()
  70. #include "llvlcomposition.h"
  71. #include "llvlmanager.h"
  72. #include "llvoavatarself.h"
  73. #include "llworld.h"
  74. #include "llworldmap.h"
  75. // The server only keeps our pending agent info for 60 seconds. We want to
  76. // allow for seed cap retry, but its not useful after that 60 seconds. Even
  77. // when we gave up on login, keep trying for caps after we are logged in.
  78. constexpr U32 MAX_CAP_REQUEST_ATTEMPTS = 30;
  79. constexpr U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
  80. bool LLViewerRegion::sVOCacheCullingEnabled = false;
  81. S32 LLViewerRegion::sLastCameraUpdated = 0;
  82. S32 LLViewerRegion::sNewObjectCreationThrottle = -1;
  83. // NOTE: by using these instead of omitting the corresponding xxxAndSuspend()
  84. // parameters, we avoid seeing such classes constructed and destroyed each time
  85. LLCore::HttpHeaders::ptr_t LLViewerRegion::sHttpHeaders(new LLCore::HttpHeaders());
  86. LLCore::HttpOptions::ptr_t LLViewerRegion::sHttpOptions(new LLCore::HttpOptions());
  87. U64 LLRegionInfoModel::sRegionFlags = 0;
  88. U32 LLRegionInfoModel::sEstateID = 0;
  89. U32 LLRegionInfoModel::sParentEstateID = 0;
  90. S32 LLRegionInfoModel::sPricePerMeter = 0;
  91. S32 LLRegionInfoModel::sRedirectGridX = 0;
  92. S32 LLRegionInfoModel::sRedirectGridY = 0;
  93. F32 LLRegionInfoModel::sBillableFactor = 0.f;
  94. F32 LLRegionInfoModel::sObjectBonusFactor = 0.f;
  95. F32 LLRegionInfoModel::sWaterHeight = 0.f;
  96. F32 LLRegionInfoModel::sTerrainRaiseLimit = 0.f;
  97. F32 LLRegionInfoModel::sTerrainLowerLimit = 0.f;
  98. F32 LLRegionInfoModel::sSunHour = 0.f;
  99. S32 LLRegionInfoModel::sHardAgentLimit = 0;
  100. U8 LLRegionInfoModel::sSimAccess = 0;
  101. U8 LLRegionInfoModel::sAgentLimit = 0;
  102. bool LLRegionInfoModel::sUseEstateSun = false;
  103. std::string LLRegionInfoModel::sSimName;
  104. std::string LLRegionInfoModel::sSimType;
  105. // Support for secondlife:///app/region/{REGION} SLapps
  106. // N.B. this is defined to work exactly like the classic secondlife://{REGION}
  107. // However, the later syntax cannot support spaces in the region name because
  108. // spaces (and %20 chars) are illegal in the hostname of an http URL. Some
  109. // browsers let you get away with this, but some do not.
  110. // Hence we introduced the newer secondlife:///app/region alternative.
  111. class LLRegionHandler final : public LLCommandHandler
  112. {
  113. public:
  114. // requests will be throttled from a non-trusted browser
  115. LLRegionHandler()
  116. : LLCommandHandler("region", UNTRUSTED_THROTTLE)
  117. {
  118. }
  119. bool handle(const LLSD& params, const LLSD&, LLMediaCtrl* web) override
  120. {
  121. // Make sure that we at least have a region name
  122. S32 num_params = params.size();
  123. if (num_params < 1)
  124. {
  125. return false;
  126. }
  127. // Build a secondlife://{PLACE} SLurl from this SLapp
  128. std::string url = "secondlife://";
  129. for (S32 i = 0; i < num_params; ++i)
  130. {
  131. if (i > 0)
  132. {
  133. url += "/";
  134. }
  135. url += params[i].asString();
  136. }
  137. // Process the SLapp as if it was a secondlife://{PLACE} SLurl
  138. LLURLDispatcher::dispatch(url, "clicked", web, true);
  139. return true;
  140. }
  141. };
  142. LLRegionHandler gRegionHandler;
  143. LLViewerRegion::LLViewerRegion(const U64& handle, const LLHost& host,
  144. U32 grids_per_region_edge,
  145. U32 grids_per_patch_edge,
  146. F32 region_width_meters)
  147. : mHandle(handle),
  148. mHost(host),
  149. mTimeDilation(1.0f),
  150. mLastUpdate(0),
  151. mCreationTime(gFrameTimeSeconds),
  152. mIsEstateManager(false),
  153. mRegionFlags(REGION_FLAGS_DEFAULT),
  154. mRegionProtocols(0),
  155. mCentralBakeVersion(0),
  156. mSimAccess(SIM_ACCESS_MIN),
  157. mBillableFactor(1.0),
  158. mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
  159. mClassID(0),
  160. mCPURatio(0),
  161. mColoName("unknown"),
  162. mProductSKU("unknown"),
  163. mProductName("unknown"),
  164. mCacheLoading(false),
  165. mCacheLoaded(false),
  166. mCacheDirty(false),
  167. mPendingHandshakes(0),
  168. mLastCameraUpdate(0),
  169. mLastCameraOrigin(),
  170. mEventPoll(NULL),
  171. mSeedCapAttempts(0),
  172. mHttpResponderID(0),
  173. mCapabilitiesState(CAPABILITIES_STATE_INIT),
  174. mFeaturesReceived(false),
  175. mDead(false),
  176. mLastVisitedEntry(NULL),
  177. mInvisibilityCheckHistory(-1),
  178. mPaused(false),
  179. mMeshRezEnabled(false),
  180. mMeshUploadEnabled(false),
  181. mPhysicsShapeTypes(false),
  182. mDynamicPathfinding(false),
  183. mDynamicPathfindingEnabled(false),
  184. mBakesOnMeshEnabled(false),
  185. mOSExportPermSupported(false),
  186. mHoverHeigthFeature(false),
  187. mWhisperRange((U32)CHAT_WHISPER_RADIUS),
  188. mChatRange((U32)CHAT_NORMAL_RADIUS),
  189. mShoutRange((U32)CHAT_SHOUT_RADIUS),
  190. mMaxMaterialsPerTransaction(50), // Original hard coded default
  191. mRenderMaterialsCapability(1.f), // Original hard coded default
  192. mMaxTextureSize(1024),
  193. mHasPBRTerrain(false),
  194. mGLTFEnabled(false),
  195. mFirstWindLayerReceivedTime(0.f),
  196. mGotClouds(false),
  197. mWidth(region_width_meters) // Variable region size support
  198. {
  199. mOriginGlobal = from_region_handle(handle);
  200. updateRenderMatrix();
  201. mLandp = new LLSurface('l', NULL);
  202. // Create the composition layer for the surface
  203. mCompositionp = new LLVLComposition(mLandp, grids_per_region_edge,
  204. region_width_meters / grids_per_region_edge);
  205. mCompositionp->setSurface(mLandp);
  206. // Create the surfaces
  207. mLandp->setRegion(this);
  208. mLandp->create(grids_per_region_edge, grids_per_patch_edge, mOriginGlobal,
  209. mWidth);
  210. mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
  211. gViewerParcelMgr.setRegionWidth(region_width_meters);
  212. mWind.setRegionWidth(region_width_meters);
  213. mCloudLayer.create(this);
  214. mCloudLayer.setWindPointer(&mWind);
  215. setOriginGlobal(from_region_handle(handle));
  216. calculateCenterGlobal();
  217. // Create the object lists
  218. initStats();
  219. initPartitions();
  220. }
  221. void LLViewerRegion::initStats()
  222. {
  223. mLastNetUpdate.reset();
  224. mPacketsIn = 0;
  225. mBitsIn = 0;
  226. mLastBitsIn = 0;
  227. mLastPacketsIn = 0;
  228. mPacketsOut = 0;
  229. mLastPacketsOut = 0;
  230. mPacketsLost = 0;
  231. mLastPacketsLost = 0;
  232. mPingDelay = 0;
  233. mAlive = false; // can become false if circuit disconnects
  234. }
  235. // Creates object partitions. MUST MATCH declaration of eObjectPartitions
  236. void LLViewerRegion::initPartitions()
  237. {
  238. mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD
  239. mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN
  240. mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER
  241. mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER
  242. mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE
  243. mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE
  244. mObjectPartition.push_back(new LLCloudPartition(this)); //PARTITION_CLOUD
  245. mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS
  246. mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME
  247. mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE
  248. mObjectPartition.push_back(new LLAvatarPartition(this)); //PARTITION_AVATAR
  249. mObjectPartition.push_back(new LLPuppetPartition(this)); //PARTITION_PUPPET
  250. mObjectPartition.push_back(new LLHUDParticlePartition(this)); //PARTITION_HUD_PARTICLE
  251. mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE
  252. mObjectPartition.push_back(NULL); //PARTITION_NONE
  253. mVOCachePartition = getVOCachePartition();
  254. }
  255. void LLViewerRegion::deletePartitions()
  256. {
  257. std::for_each(mObjectPartition.begin(), mObjectPartition.end(),
  258. DeletePointer());
  259. mObjectPartition.clear();
  260. }
  261. LLViewerRegion::~LLViewerRegion()
  262. {
  263. mDead = true;
  264. mActiveSet.clear();
  265. mVisibleEntries.clear();
  266. mVisibleGroups.clear();
  267. mWaitingSet.clear();
  268. gVLManager.cleanupData(this);
  269. // Cannot do this on destruction, because the neighbor pointers might be
  270. // invalid. This should be reference counted...
  271. disconnectAllNeighbors();
  272. mCloudLayer.destroy();
  273. gViewerPartSim.cleanupRegion(this);
  274. gObjectList.killObjects(this);
  275. delete mCompositionp;
  276. delete mParcelOverlay;
  277. delete mLandp;
  278. delete mEventPoll;
  279. deletePartitions();
  280. saveObjectCache();
  281. }
  282. //static
  283. void LLViewerRegion::cacheLoadedCallback(U64 region_handle,
  284. LLVOCacheEntry::map_t* cachep,
  285. LLVOCacheEntry::emap_t* extrasp)
  286. {
  287. LLViewerRegion* self = gWorld.getRegionFromHandle(region_handle);
  288. if (self && !self->mDead && !LLApp::isExiting())
  289. {
  290. LL_DEBUGS("ObjectCache") << "Cache loaded callback for region: "
  291. << self->mName << " (handle " << region_handle
  292. << ")" << LL_ENDL;
  293. self->mCacheLoading = false;
  294. // Recover the cache data, if any.
  295. if (!cachep || cachep->empty())
  296. {
  297. self->mCacheDirty = true;
  298. }
  299. else
  300. {
  301. self->mCacheMap.swap(*cachep);
  302. }
  303. if (extrasp && !extrasp->empty())
  304. {
  305. self->mGLTFOverrides.swap(*extrasp);
  306. }
  307. // Reply to the pending handshake(s) now.
  308. while (self->mPendingHandshakes)
  309. {
  310. self->sendHandshakeReply();
  311. }
  312. }
  313. else if (!LLApp::isExiting())
  314. {
  315. llwarns << "Skipping for region handle " << region_handle
  316. << (self ? ": region not found." : " region is dead.")
  317. << llendl;
  318. }
  319. if (cachep)
  320. {
  321. delete cachep;
  322. }
  323. if (extrasp)
  324. {
  325. delete extrasp;
  326. }
  327. }
  328. void LLViewerRegion::loadObjectCache()
  329. {
  330. if (!mCacheLoaded)
  331. {
  332. // Pretend it is already loaded so that it does not get queued twice
  333. // or more (we do get several handshakes for the same region in SL). HB
  334. mCacheLoaded = true;
  335. if (LLVOCache::instanceExists())
  336. {
  337. llinfos << "Loading object cache for region: " << mName << llendl;
  338. mCacheLoading = true;
  339. LLVOCache::getInstance()->readFromCache(mHandle, mName, mCacheID);
  340. }
  341. }
  342. }
  343. void LLViewerRegion::saveObjectCache()
  344. {
  345. if (!mCacheLoaded)
  346. {
  347. LL_DEBUGS("ObjectCache") << "Cache map not loaded for region: "
  348. << mName << ". Skiping." << LL_ENDL;
  349. return;
  350. }
  351. if (mCacheMap.empty())
  352. {
  353. LL_DEBUGS("ObjectCache") << "Cache map empty for region: " << mName
  354. << ". Skiping." << LL_ENDL;
  355. return;
  356. }
  357. if (LLVOCache::instanceExists())
  358. {
  359. LL_DEBUGS("ObjectCache") << "Saving object cache for region: " << mName
  360. << LL_ENDL;
  361. constexpr F32 THRESHOLD = 600.f; // Seconds
  362. bool removal_enabled =
  363. sVOCacheCullingEnabled &&
  364. (LLApp::isExiting() ||
  365. mCreationTime - gFrameTimeSeconds > THRESHOLD);
  366. // Note: mCacheMap and/or mGLTFOverrides may be wiped out (for
  367. // speed, they are actually swapped with an empty map on successful
  368. // cache write) by this call. So they cannot be reused afterwards, but
  369. // this is OK, since we are going to destroy it: saveObjectCache() is
  370. // for now only called at the end of ~LLViewerRegion() (should this
  371. // change, the swap optimization would have to be removed and replaced
  372. // with a copy). HB
  373. LLVOCache::getInstance()->writeToCache(mHandle, mName, mCacheID,
  374. mCacheMap, mCacheDirty,
  375. mGLTFOverrides,
  376. removal_enabled);
  377. }
  378. mCacheDirty = false;
  379. }
  380. void LLViewerRegion::sendMessage()
  381. {
  382. gMessageSystemp->sendMessage(mHost);
  383. }
  384. void LLViewerRegion::sendReliableMessage()
  385. {
  386. gMessageSystemp->sendReliable(mHost);
  387. }
  388. void LLViewerRegion::sendEstateCovenantRequest()
  389. {
  390. LLMessageSystem* msg = gMessageSystemp;
  391. if (msg) // Paranoia
  392. {
  393. msg->newMessage(_PREHASH_EstateCovenantRequest);
  394. msg->nextBlockFast(_PREHASH_AgentData);
  395. msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
  396. msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
  397. msg->sendReliable(mHost);
  398. }
  399. }
  400. void LLViewerRegion::setWaterHeight(F32 water_level)
  401. {
  402. mLandp->setWaterHeight(water_level);
  403. }
  404. F32 LLViewerRegion::getWaterHeight() const
  405. {
  406. return mLandp->getWaterHeight();
  407. }
  408. void LLViewerRegion::setOriginGlobal(const LLVector3d& origin_global)
  409. {
  410. mOriginGlobal = origin_global;
  411. updateRenderMatrix();
  412. mLandp->setOriginGlobal(origin_global);
  413. mWind.setOriginGlobal(origin_global);
  414. mCloudLayer.setOriginGlobal(origin_global);
  415. calculateCenterGlobal();
  416. }
  417. void LLViewerRegion::updateRenderMatrix()
  418. {
  419. mRenderMatrix.setTranslation(getOriginAgent());
  420. }
  421. LLVector3 LLViewerRegion::getOriginAgent() const
  422. {
  423. return gAgent.getPosAgentFromGlobal(mOriginGlobal);
  424. }
  425. LLVector3 LLViewerRegion::getCenterAgent() const
  426. {
  427. return gAgent.getPosAgentFromGlobal(mCenterGlobal);
  428. }
  429. void LLViewerRegion::setRegionNameAndZone(const std::string& name_zone)
  430. {
  431. std::string::size_type pipe_pos = name_zone.find('|');
  432. if (pipe_pos != std::string::npos)
  433. {
  434. size_t length = name_zone.size();
  435. mName = name_zone.substr(0, pipe_pos);
  436. mZoning = name_zone.substr(pipe_pos + 1, length - pipe_pos - 1);
  437. }
  438. else
  439. {
  440. mName = name_zone;
  441. mZoning.clear();
  442. }
  443. LLStringUtil::stripNonprintable(mName);
  444. LLStringUtil::stripNonprintable(mZoning);
  445. if (mEventPoll)
  446. {
  447. mEventPoll->setRegionName(mName);
  448. }
  449. }
  450. bool LLViewerRegion::canManageEstate() const
  451. {
  452. return gAgent.isGodlike() || isEstateManager() || gAgentID == getOwner();
  453. }
  454. //static
  455. std::string LLViewerRegion::accessToString(U8 sim_access)
  456. {
  457. static std::string access_pg = LLTrans::getString("SIM_ACCESS_PG");
  458. static std::string access_mature = LLTrans::getString("SIM_ACCESS_MATURE");
  459. static std::string access_adult = LLTrans::getString("SIM_ACCESS_ADULT");
  460. static std::string access_down = LLTrans::getString("SIM_ACCESS_DOWN");
  461. static std::string access_min = LLTrans::getString("unknown");
  462. switch (sim_access)
  463. {
  464. case SIM_ACCESS_PG:
  465. return access_pg;
  466. case SIM_ACCESS_MATURE:
  467. return access_mature;
  468. case SIM_ACCESS_ADULT:
  469. return access_adult;
  470. case SIM_ACCESS_DOWN:
  471. return access_down;
  472. case SIM_ACCESS_MIN:
  473. default:
  474. return access_min;
  475. }
  476. }
  477. //static
  478. std::string LLViewerRegion::accessToShortString(U8 sim_access)
  479. {
  480. switch (sim_access)
  481. {
  482. case SIM_ACCESS_PG:
  483. return "PG";
  484. case SIM_ACCESS_MATURE:
  485. return "M";
  486. case SIM_ACCESS_ADULT:
  487. return "A";
  488. case SIM_ACCESS_MIN:
  489. default:
  490. return "U";
  491. }
  492. }
  493. //static
  494. const std::string& LLViewerRegion::getMaturityIconName(U8 sim_access)
  495. {
  496. static const std::string pg = "access_pg.tga";
  497. static const std::string mature = "access_mature.tga";
  498. static const std::string adult = "access_adult.tga";
  499. if (sim_access <= SIM_ACCESS_PG)
  500. {
  501. return pg;
  502. }
  503. if (sim_access <= SIM_ACCESS_MATURE)
  504. {
  505. return mature;
  506. }
  507. return adult;
  508. }
  509. //static
  510. void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)
  511. {
  512. if (!msg) return;
  513. std::string sim_name;
  514. msg->getString(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name);
  515. F32 water_height;
  516. msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
  517. if (msg->getSender() != gAgent.getRegionHost())
  518. {
  519. // Update is for a different region than the one we are in.
  520. // Just check for a waterheight change.
  521. gWorld.waterHeightRegionInfo(sim_name, water_height);
  522. return;
  523. }
  524. LLRegionInfoModel::sSimName = sim_name;
  525. LLRegionInfoModel::sWaterHeight = water_height;
  526. msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID,
  527. LLRegionInfoModel::sEstateID);
  528. msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID,
  529. LLRegionInfoModel::sParentEstateID);
  530. msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess,
  531. LLRegionInfoModel::sSimAccess);
  532. msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents,
  533. LLRegionInfoModel::sAgentLimit);
  534. LLRegionInfoModel::sHardAgentLimit = 0;
  535. msg->getS32(_PREHASH_RegionInfo2, _PREHASH_HardMaxAgents,
  536. LLRegionInfoModel::sHardAgentLimit);
  537. if (!LLRegionInfoModel::sHardAgentLimit)
  538. {
  539. LLRegionInfoModel::sHardAgentLimit = 100;
  540. }
  541. msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor,
  542. LLRegionInfoModel::sObjectBonusFactor);
  543. msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor,
  544. LLRegionInfoModel::sBillableFactor);
  545. msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit,
  546. LLRegionInfoModel::sTerrainRaiseLimit);
  547. msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit,
  548. LLRegionInfoModel::sTerrainLowerLimit);
  549. msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_PricePerMeter,
  550. LLRegionInfoModel::sPricePerMeter);
  551. msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_RedirectGridX,
  552. LLRegionInfoModel::sRedirectGridX);
  553. msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_RedirectGridY,
  554. LLRegionInfoModel::sRedirectGridY);
  555. msg->getBool(_PREHASH_RegionInfo, _PREHASH_UseEstateSun,
  556. LLRegionInfoModel::sUseEstateSun);
  557. // Actually the "last set" Sun hour, not the current Sun hour.
  558. msg->getF32(_PREHASH_RegionInfo, _PREHASH_SunHour,
  559. LLRegionInfoModel::sSunHour);
  560. // The only reasonable way to decide if we actually have any data is to
  561. // check to see if any of these fields have nonzero sizes
  562. std::string sim_type = LLTrans::getString("unknown");
  563. if (msg->getSize(_PREHASH_RegionInfo2, _PREHASH_ProductSKU) > 0 ||
  564. msg->getSize(_PREHASH_RegionInfo2, _PREHASH_ProductName) > 0)
  565. {
  566. msg->getString(_PREHASH_RegionInfo2, _PREHASH_ProductName,
  567. LLRegionInfoModel::sSimType);
  568. }
  569. else
  570. {
  571. LLRegionInfoModel::sSimType.clear();
  572. }
  573. if (msg->has(_PREHASH_RegionInfo3))
  574. {
  575. msg->getU64(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended,
  576. LLRegionInfoModel::sRegionFlags);
  577. }
  578. else
  579. {
  580. U32 flags = 0;
  581. msg->getU32(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
  582. LLRegionInfoModel::sRegionFlags = flags;
  583. }
  584. // Push values to the agent region
  585. LLViewerRegion* self = gAgent.getRegion();
  586. if (self)
  587. {
  588. self->setRegionNameAndZone(sim_name);
  589. self->setRegionFlags(LLRegionInfoModel::sRegionFlags);
  590. self->setSimAccess(LLRegionInfoModel::sSimAccess);
  591. self->setWaterHeight(LLRegionInfoModel::sWaterHeight);
  592. self->setBillableFactor(LLRegionInfoModel::sBillableFactor);
  593. }
  594. // Send the region info update notification to interested parties.
  595. LLFloaterRegionInfo::updateFromRegionInfo();
  596. LLFloaterGodTools::updateFromRegionInfo();
  597. // *TODO: this frequently results in one more request than we need. It is
  598. // not breaking, but should be nicer. We need to know new env version to
  599. // fix this, without it we can only do full re-request. They happens on
  600. // updates, on opening LLFloaterRegionInfo, on region crossing if info
  601. // floater is open.
  602. LLEnvironment::requestRegion();
  603. }
  604. void LLViewerRegion::renderPropertyLines() const
  605. {
  606. if (mParcelOverlay)
  607. {
  608. mParcelOverlay->renderPropertyLines();
  609. }
  610. }
  611. void LLViewerRegion::renderParcelBorders(F32 scale, const F32* color) const
  612. {
  613. if (mParcelOverlay)
  614. {
  615. mParcelOverlay->renderParcelBorders(scale, color);
  616. }
  617. }
  618. bool LLViewerRegion::renderBannedParcels(F32 scale, const F32* color) const
  619. {
  620. return mParcelOverlay && mParcelOverlay->renderBannedParcels(scale, color);
  621. }
  622. // This gets called when the height field changes.
  623. void LLViewerRegion::dirtyHeights()
  624. {
  625. // Property lines need to be reconstructed when the land changes.
  626. if (mParcelOverlay)
  627. {
  628. mParcelOverlay->setDirty();
  629. }
  630. }
  631. // Physically delete the cache entry
  632. void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entryp, bool for_rendering)
  633. {
  634. if (!entryp|| !entryp->isValid())
  635. {
  636. return;
  637. }
  638. if (for_rendering && !entryp->isState(LLVOCacheEntry::ACTIVE))
  639. {
  640. addNewObject(entryp); // Force to add to rendering pipeline
  641. }
  642. // Remove from active list and waiting list
  643. if (entryp->isState(LLVOCacheEntry::ACTIVE))
  644. {
  645. mActiveSet.erase(entryp);
  646. }
  647. else
  648. {
  649. if (entryp->isState(LLVOCacheEntry::WAITING))
  650. {
  651. mWaitingSet.erase(entryp);
  652. }
  653. // Remove from mVOCachePartition
  654. removeFromVOCacheTree(entryp);
  655. }
  656. // Remove from the forced visible list
  657. mVisibleEntries.erase(entryp);
  658. // Disconnect from parent if it is a child
  659. if (entryp->getParentID() > 0)
  660. {
  661. LLVOCacheEntry* parentp = getCacheEntry(entryp->getParentID());
  662. if (parentp)
  663. {
  664. parentp->removeChild(entryp);
  665. }
  666. }
  667. else if (entryp->getNumOfChildren() > 0)
  668. {
  669. LLVOCacheEntry* childp = entryp->getChild();
  670. while (childp)
  671. {
  672. killCacheEntry(childp, for_rendering);
  673. childp = entryp->getChild();
  674. }
  675. }
  676. #if 0 // Nope: do not do this ! The object may re-rez later in the same
  677. // session (e.g. for neighbour region objects, depending on draw
  678. // distance, while moving or caming around) and its override may
  679. // not be re-sent by the simulator, causing a loss in the override
  680. // data ! HB
  681. // Kill the associated GLTF override.
  682. mGLTFOverrides.erase(entryp->getLocalID());
  683. #endif
  684. // Will remove it from the object cache, real deletion
  685. entryp->setState(LLVOCacheEntry::INACTIVE);
  686. entryp->removeOctreeEntry();
  687. entryp->setValid(false);
  688. }
  689. // Physically delete the cache entry
  690. void LLViewerRegion::killCacheEntry(U32 local_id)
  691. {
  692. killCacheEntry(getCacheEntry(local_id));
  693. }
  694. void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry)
  695. {
  696. if (!entry || mDead ||
  697. // Ignore if already inserted
  698. entry->isState(LLVOCacheEntry::ACTIVE))
  699. {
  700. return;
  701. }
  702. if (entry->isState(LLVOCacheEntry::WAITING))
  703. {
  704. mWaitingSet.erase(entry);
  705. }
  706. entry->setState(LLVOCacheEntry::ACTIVE);
  707. entry->setVisible();
  708. llassert(entry->getEntry()->hasDrawable());
  709. mActiveSet.insert(entry);
  710. }
  711. void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry,
  712. LLDrawable* drawablep)
  713. {
  714. if (mDead || !entry || !entry->isValid() ||
  715. // Ignore if not an active entry
  716. !entry->isState(LLVOCacheEntry::ACTIVE))
  717. {
  718. return;
  719. }
  720. // Shift to the local regional space from agent space
  721. if (drawablep && drawablep->getVObj().notNull())
  722. {
  723. const LLVector3& pos = drawablep->getVObj()->getPositionRegion();
  724. LLVector4a shift;
  725. shift.load3(pos.mV);
  726. shift.sub(entry->getPositionGroup());
  727. entry->shift(shift);
  728. }
  729. if (entry->getParentID() > 0) // is a child
  730. {
  731. LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
  732. if (parent)
  733. {
  734. parent->addChild(entry);
  735. }
  736. else
  737. {
  738. // Parent not in cache (happens only when it is not cacheable)
  739. mOrphanMap[entry->getParentID()].push_back(entry->getLocalID());
  740. }
  741. }
  742. else
  743. {
  744. // Insert to vo cache tree.
  745. entry->updateParentBoundingInfo();
  746. entry->saveBoundingSphere();
  747. addToVOCacheTree(entry);
  748. }
  749. mVisibleEntries.erase(entry);
  750. mActiveSet.erase(entry);
  751. mWaitingSet.erase(entry);
  752. entry->setState(LLVOCacheEntry::INACTIVE);
  753. }
  754. bool LLViewerRegion::addVisibleGroup(LLViewerOctreeGroup* group)
  755. {
  756. if (mDead || group->isEmpty())
  757. {
  758. return false;
  759. }
  760. mVisibleGroups.push_back(group);
  761. return true;
  762. }
  763. void LLViewerRegion::updateReflectionProbes()
  764. {
  765. constexpr F32 HOVER_HEIGHT = 2.f;
  766. constexpr F32 PROBE_SPACING = 32.f;
  767. constexpr F32 HALF_PROBE_SPACING = PROBE_SPACING * 0.5f;
  768. constexpr F32 START = HALF_PROBE_SPACING;
  769. static const F32 PROBE_RADIUS = sqrtf(HALF_PROBE_SPACING *
  770. HALF_PROBE_SPACING * 3.f);
  771. // Using mWidth here instead of REGION_WIDTH_METERS for Variable region
  772. // size support. HB
  773. U32 grid_width = mWidth / PROBE_SPACING;
  774. mReflectionMaps.resize(grid_width * grid_width);
  775. F32 water_height = getWaterHeight();
  776. LLVector3 origin = getOriginAgent();
  777. for (U32 i = 0; i < grid_width; ++i)
  778. {
  779. F32 x = i * PROBE_SPACING + START;
  780. for (U32 j = 0; j < grid_width; ++j)
  781. {
  782. F32 y = j * PROBE_SPACING + START;
  783. U32 idx = i * grid_width + j;
  784. if (mReflectionMaps[idx].isNull())
  785. {
  786. mReflectionMaps[idx] =
  787. gPipeline.mReflectionMapManager.addProbe();
  788. }
  789. LLVector3 pos(x, y,
  790. HOVER_HEIGHT +
  791. llmax(water_height,
  792. mLandp->resolveHeightRegion(x, y)));
  793. pos += origin;
  794. mReflectionMaps[idx]->mOrigin.load3(pos.mV);
  795. mReflectionMaps[idx]->mRadius = PROBE_RADIUS;
  796. }
  797. }
  798. }
  799. void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
  800. {
  801. if (entry && sVOCacheCullingEnabled && !mDead &&
  802. entry->getEntry() && entry->isValid() &&
  803. entry->getParentID() == 0 && // Child in octree
  804. !entry->hasState(LLVOCacheEntry::IN_VO_TREE)) // Not in octree
  805. {
  806. llassert_always(!entry->getGroup()); // Not in octree.
  807. llassert(!entry->getEntry()->hasDrawable()); // No drawable
  808. if (mVOCachePartition->addEntry(entry->getEntry()))
  809. {
  810. entry->setState(LLVOCacheEntry::IN_VO_TREE);
  811. }
  812. }
  813. }
  814. void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry)
  815. {
  816. if (entry && !mDead && entry->getEntry() &&
  817. // Must be in tree
  818. entry->hasState(LLVOCacheEntry::IN_VO_TREE))
  819. {
  820. entry->clearState(LLVOCacheEntry::IN_VO_TREE);
  821. mVOCachePartition->removeEntry(entry->getEntry());
  822. }
  823. }
  824. // Add child objects as visible entries
  825. void LLViewerRegion::addVisibleChildCacheEntry(LLVOCacheEntry* parent,
  826. LLVOCacheEntry* child)
  827. {
  828. if (mDead)
  829. {
  830. return;
  831. }
  832. if (parent &&
  833. (!parent->isValid() || !parent->isState(LLVOCacheEntry::ACTIVE)))
  834. {
  835. // Parent must be valid and in rendering pipeline
  836. return;
  837. }
  838. if (child &&
  839. (!child->getEntry() || !child->isValid() ||
  840. !child->isState(LLVOCacheEntry::INACTIVE)))
  841. {
  842. // Child must be valid and not in the rendering pipeline
  843. return;
  844. }
  845. if (child)
  846. {
  847. child->setState(LLVOCacheEntry::IN_QUEUE);
  848. mVisibleEntries.insert(child);
  849. }
  850. else if (parent && parent->getNumOfChildren() > 0)
  851. {
  852. // Add all children
  853. while ((child = parent->getChild()))
  854. {
  855. addVisibleChildCacheEntry(NULL, child);
  856. }
  857. }
  858. }
  859. void LLViewerRegion::updateVisibleEntries()
  860. {
  861. if (mDead || !sNewObjectCreationThrottle ||
  862. (mVisibleGroups.empty() && mVisibleEntries.empty()))
  863. {
  864. return;
  865. }
  866. // A large number to force to load the object:
  867. constexpr F32 LARGE_SCENE_CONTRIBUTION = 1000.f;
  868. const LLVector3 camera_origin = gViewerCamera.getOrigin();
  869. const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame();
  870. bool needs_update = cur_frame - mLastCameraUpdate > 5 &&
  871. (camera_origin -
  872. mLastCameraOrigin).lengthSquared() > 10.f;
  873. U32 last_update = mLastCameraUpdate;
  874. LLVector4a local_origin;
  875. local_origin.load3((camera_origin - getOriginAgent()).mV);
  876. // Process visible entries
  877. for (LLVOCacheEntry::set_t::iterator iter = mVisibleEntries.begin(),
  878. end = mVisibleEntries.end();
  879. iter != end; )
  880. {
  881. LLVOCacheEntry::set_t::iterator curiter = iter++;
  882. LLVOCacheEntry* entryp = *curiter;
  883. if (entryp && entryp->isValid() &&
  884. entryp->getState() < LLVOCacheEntry::WAITING)
  885. {
  886. // Set a large number to force to load this object.
  887. entryp->setSceneContribution(LARGE_SCENE_CONTRIBUTION);
  888. mWaitingList.insert(entryp);
  889. }
  890. else
  891. {
  892. mVisibleEntries.erase(curiter);
  893. }
  894. }
  895. // Process visible groups
  896. if (!mVOCachePartition)
  897. {
  898. return;
  899. }
  900. // Object projected area threshold
  901. F32 projection_threshold =
  902. LLVOCacheEntry::getSquaredPixelThreshold(mVOCachePartition->isFrontCull());
  903. F32 dist_threshold =
  904. mVOCachePartition->isFrontCull() ? gAgent.mDrawDistance
  905. : LLVOCacheEntry::sRearFarRadius;
  906. for (U32 i = 0, count = mVisibleGroups.size(); i < count; ++i)
  907. {
  908. LLPointer<LLViewerOctreeGroup> group = mVisibleGroups[i];
  909. if (group.isNull() || group->getNumRefs() < 3 || // Group to be deleted
  910. !group->getOctreeNode() || group->isEmpty()) // Group empty
  911. {
  912. continue;
  913. }
  914. for (LLViewerOctreeGroup::element_iter it = group->getDataBegin(),
  915. end2 = group->getDataEnd();
  916. it != end2; ++it)
  917. {
  918. if (*it && (*it)->hasVOCacheEntry())
  919. {
  920. LLVOCacheEntry* entryp =
  921. (LLVOCacheEntry*)(*it)->getVOCacheEntry();
  922. if (entryp->getParentID() == 0 && entryp->isValid())
  923. {
  924. entryp->calcSceneContribution(local_origin, needs_update,
  925. last_update, dist_threshold);
  926. if (entryp->getSceneContribution() > projection_threshold)
  927. {
  928. mWaitingList.insert(entryp);
  929. }
  930. }
  931. }
  932. }
  933. }
  934. if (needs_update)
  935. {
  936. mLastCameraOrigin = camera_origin;
  937. mLastCameraUpdate = cur_frame;
  938. }
  939. }
  940. void LLViewerRegion::createVisibleObjects(F32 max_time)
  941. {
  942. if (mDead)
  943. {
  944. return;
  945. }
  946. if (mWaitingList.empty())
  947. {
  948. mVOCachePartition->setCullHistory(false);
  949. return;
  950. }
  951. S32 throttle = sNewObjectCreationThrottle;
  952. bool do_throttle = throttle > 0;
  953. bool has_new_obj = false;
  954. LLTimer update_timer;
  955. for (LLVOCacheEntry::prio_list_t::iterator iter = mWaitingList.begin(),
  956. end = mWaitingList.end();
  957. iter != end; ++iter)
  958. {
  959. LLVOCacheEntry* entryp = *iter;
  960. if (entryp->getState() < LLVOCacheEntry::WAITING)
  961. {
  962. addNewObject(entryp);
  963. has_new_obj = true;
  964. if ((do_throttle && --throttle <= 0) ||
  965. update_timer.getElapsedTimeF32() > max_time)
  966. {
  967. break;
  968. }
  969. }
  970. }
  971. mVOCachePartition->setCullHistory(has_new_obj);
  972. }
  973. void LLViewerRegion::clearCachedVisibleObjects()
  974. {
  975. mWaitingList.clear();
  976. mVisibleGroups.clear();
  977. // Reset all occluders
  978. mVOCachePartition->resetOccluders();
  979. mPaused = true;
  980. // Clean visible entries
  981. for (LLVOCacheEntry::set_t::iterator iter = mVisibleEntries.begin();
  982. iter != mVisibleEntries.end(); )
  983. {
  984. LLVOCacheEntry::set_t::iterator curiter = iter++;
  985. LLVOCacheEntry* entry = *curiter;
  986. LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
  987. // If no child or parent is cache-able
  988. if (!entry->getParentID() || parent)
  989. {
  990. if (parent) // Has a cache-able parent
  991. {
  992. parent->addChild(entry);
  993. }
  994. mVisibleEntries.erase(curiter);
  995. }
  996. }
  997. // Remove all visible entries.
  998. mLastVisitedEntry = NULL;
  999. std::vector<LLDrawable*> delete_list;
  1000. for (LLVOCacheEntry::set_t::iterator iter = mActiveSet.begin(),
  1001. end = mActiveSet.end();
  1002. iter != end; ++iter)
  1003. {
  1004. LLVOCacheEntry* entryp = *iter;
  1005. if (!entryp)
  1006. {
  1007. continue;
  1008. }
  1009. LLViewerOctreeEntry* octreep = entryp->getEntry();
  1010. if (!octreep)
  1011. {
  1012. continue;
  1013. }
  1014. LLDrawable* drawablep = (LLDrawable*)octreep->getDrawable();
  1015. if (drawablep && !drawablep->getParent())
  1016. {
  1017. delete_list.push_back(drawablep);
  1018. }
  1019. }
  1020. if (!delete_list.empty())
  1021. {
  1022. for (S32 i = 0, count = delete_list.size(); i < count; ++i)
  1023. {
  1024. gObjectList.killObject(delete_list[i]->getVObj());
  1025. }
  1026. delete_list.clear();
  1027. }
  1028. }
  1029. // Perform some necessary but very light updates to replace the function
  1030. // idleUpdate(...) in case there is not enough time.
  1031. void LLViewerRegion::lightIdleUpdate()
  1032. {
  1033. if (sVOCacheCullingEnabled && !mCacheMap.empty())
  1034. {
  1035. LL_FAST_TIMER(FTM_UPD_CACHEDOBJECTS);
  1036. // Reset all occluders
  1037. mVOCachePartition->resetOccluders();
  1038. }
  1039. }
  1040. void LLViewerRegion::idleUpdate(F32 max_update_time)
  1041. {
  1042. LLTimer update_timer;
  1043. mLastUpdate = LLViewerOctreeEntryData::getCurrentFrame();
  1044. {
  1045. LL_FAST_TIMER(FTM_UPD_LANDPATCHES);
  1046. mLandp->idleUpdate(max_update_time);
  1047. }
  1048. if (mParcelOverlay)
  1049. {
  1050. LL_FAST_TIMER(FTM_UPD_PARCELOVERLAY);
  1051. // Hopefully not a significant time sink...
  1052. mParcelOverlay->idleUpdate();
  1053. }
  1054. if (sVOCacheCullingEnabled && !mCacheMap.empty())
  1055. {
  1056. LL_FAST_TIMER(FTM_UPD_CACHEDOBJECTS);
  1057. mPaused = false; // Un-pause
  1058. S32 old_camera_id = LLViewerCamera::sCurCameraID;
  1059. LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
  1060. // Reset all occluders
  1061. mVOCachePartition->resetOccluders();
  1062. F32 max_time = max_update_time - update_timer.getElapsedTimeF32();
  1063. killInvisibleObjects(max_time * 0.4f);
  1064. updateVisibleEntries();
  1065. max_time = max_update_time - update_timer.getElapsedTimeF32();
  1066. createVisibleObjects(max_time);
  1067. mWaitingList.clear();
  1068. mVisibleGroups.clear();
  1069. LLViewerCamera::sCurCameraID = old_camera_id;
  1070. }
  1071. }
  1072. // Update the throttling number for new object creation
  1073. void LLViewerRegion::calcNewObjectCreationThrottle()
  1074. {
  1075. static LLCachedControl<S32> creation_throttle(gSavedSettings,
  1076. "NewObjectCreationThrottle");
  1077. static LLCachedControl<F32> throttle_delay(gSavedSettings,
  1078. "NewObjectCreationThrottleDelay");
  1079. static LLFrameTimer timer;
  1080. // sNewObjectCreationThrottle =
  1081. // -2 : throttle is disabled because either the screen is showing progress
  1082. // view, or immediate after the screen is not black
  1083. // -1 : throttle is disabled by the debug setting
  1084. // 0 : no new object creation is allowed
  1085. // > 0 : valid throttling number
  1086. if (throttle_delay > 0.f &&
  1087. (gTeleportDisplay ||
  1088. (gViewerWindowp && gViewerWindowp->getProgressView()->getVisible())))
  1089. {
  1090. sNewObjectCreationThrottle = -2; // cancel the throttling
  1091. timer.reset();
  1092. }
  1093. else if (sNewObjectCreationThrottle < -1)
  1094. {
  1095. // Just recovered from the login/teleport screen... Wait for
  1096. // throttle_delay to reset the throttle
  1097. if (timer.getElapsedTimeF32() > throttle_delay)
  1098. {
  1099. sNewObjectCreationThrottle = creation_throttle;
  1100. if (sNewObjectCreationThrottle < -1)
  1101. {
  1102. sNewObjectCreationThrottle = -1;
  1103. }
  1104. }
  1105. }
  1106. }
  1107. bool LLViewerRegion::isViewerCameraStatic()
  1108. {
  1109. return sLastCameraUpdated < LLViewerOctreeEntryData::getCurrentFrame();
  1110. }
  1111. void LLViewerRegion::killInvisibleObjects(F32 max_time)
  1112. {
  1113. if (!sVOCacheCullingEnabled || sNewObjectCreationThrottle < -1 ||
  1114. mActiveSet.empty())
  1115. {
  1116. return;
  1117. }
  1118. LLTimer update_timer;
  1119. LLVector4a camera_origin;
  1120. camera_origin.load3(gViewerCamera.getOrigin().mV);
  1121. LLVector4a local_origin;
  1122. local_origin.load3((gViewerCamera.getOrigin() - getOriginAgent()).mV);
  1123. F32 back_threshold = LLVOCacheEntry::sRearFarRadius;
  1124. size_t max_update = 64;
  1125. if (!mInvisibilityCheckHistory && isViewerCameraStatic())
  1126. {
  1127. // History is clean, reduce number of checking
  1128. max_update /= 2;
  1129. }
  1130. std::vector<LLDrawable*> delete_list;
  1131. S32 update_counter = llmin(max_update, mActiveSet.size());
  1132. LLVOCacheEntry::set_t::iterator iter;
  1133. for (iter = mActiveSet.upper_bound(mLastVisitedEntry);
  1134. update_counter > 0; --update_counter, ++iter)
  1135. {
  1136. if (iter == mActiveSet.end())
  1137. {
  1138. iter = mActiveSet.begin();
  1139. }
  1140. if ((*iter)->getParentID() > 0)
  1141. {
  1142. // Skip child objects: they are removed with their parent.
  1143. continue;
  1144. }
  1145. LLVOCacheEntry* entryp = *iter;
  1146. if (!entryp->isAnyVisible(camera_origin, local_origin,
  1147. back_threshold) &&
  1148. entryp->mLastCameraUpdated < sLastCameraUpdated)
  1149. {
  1150. killObject(entryp, delete_list);
  1151. }
  1152. if (max_time < update_timer.getElapsedTimeF32())
  1153. {
  1154. break; // We timed out
  1155. }
  1156. }
  1157. if (iter == mActiveSet.end())
  1158. {
  1159. mLastVisitedEntry = NULL;
  1160. }
  1161. else
  1162. {
  1163. mLastVisitedEntry = *iter;
  1164. }
  1165. mInvisibilityCheckHistory <<= 1;
  1166. if (!delete_list.empty())
  1167. {
  1168. mInvisibilityCheckHistory |= 1;
  1169. for (S32 i = 0, count = delete_list.size(); i < count; ++i)
  1170. {
  1171. gObjectList.killObject(delete_list[i]->getVObj());
  1172. }
  1173. delete_list.clear();
  1174. }
  1175. }
  1176. void LLViewerRegion::killObject(LLVOCacheEntry* entry,
  1177. std::vector<LLDrawable*>& delete_list)
  1178. {
  1179. // kill the object.
  1180. LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable();
  1181. llassert(drawablep && drawablep->getRegion() == this);
  1182. if (drawablep && !drawablep->getParent())
  1183. {
  1184. LLViewerObject* vobj = drawablep->getVObj();
  1185. if (vobj)
  1186. {
  1187. if (vobj->isSelected() ||
  1188. (vobj->flagAnimSource() && isAgentAvatarValid() &&
  1189. gAgentAvatarp->hasMotionFromSource(vobj->getID())))
  1190. {
  1191. // Do not remove objects user is interacting with
  1192. ((LLViewerOctreeEntryData*)drawablep)->setVisible();
  1193. return;
  1194. }
  1195. LLViewerObject::const_child_list_t& child_list = vobj->getChildren();
  1196. for (LLViewerObject::child_list_t::const_iterator
  1197. iter = child_list.begin(), end = child_list.end();
  1198. iter != end; ++iter)
  1199. {
  1200. LLViewerObject* child = *iter;
  1201. if (child && child->mDrawable)
  1202. {
  1203. if (!child->mDrawable->getEntry() ||
  1204. !child->mDrawable->getEntry()->hasVOCacheEntry() ||
  1205. child->isSelected() ||
  1206. (child->flagAnimSource() &&
  1207. isAgentAvatarValid() &&
  1208. gAgentAvatarp->hasMotionFromSource(child->getID())))
  1209. {
  1210. // Do not remove parent if any of its children is non-
  1211. // cacheable, animating or selected, especially for the
  1212. // case when an avatar sits on a cacheable object.
  1213. ((LLViewerOctreeEntryData*)drawablep)->setVisible();
  1214. return;
  1215. }
  1216. LLOcclusionCullingGroup* group =
  1217. (LLOcclusionCullingGroup*)child->mDrawable->getGroup();
  1218. if (group && group->isAnyRecentlyVisible())
  1219. {
  1220. // Set the parent visible if any of its children visible.
  1221. ((LLViewerOctreeEntryData*)drawablep)->setVisible();
  1222. return;
  1223. }
  1224. }
  1225. }
  1226. }
  1227. else
  1228. {
  1229. llwarns_once << "NULL viewer object for drawable: " << std::hex
  1230. << drawablep << std::dec << llendl;
  1231. llassert(false);
  1232. }
  1233. delete_list.push_back(drawablep);
  1234. }
  1235. }
  1236. LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
  1237. {
  1238. if (!entry || !entry->getEntry())
  1239. {
  1240. if (entry)
  1241. {
  1242. mVisibleEntries.erase(entry);
  1243. entry->setState(LLVOCacheEntry::INACTIVE);
  1244. }
  1245. return NULL;
  1246. }
  1247. LLViewerObject* objp = NULL;
  1248. if (!entry->getEntry()->hasDrawable())
  1249. {
  1250. // Not yet added to the rendering pipeline... Add the object now.
  1251. objp = gObjectList.processObjectUpdateFromCache(entry, this);
  1252. if (objp && !entry->isState(LLVOCacheEntry::ACTIVE))
  1253. {
  1254. mWaitingSet.insert(entry);
  1255. entry->setState(LLVOCacheEntry::WAITING);
  1256. }
  1257. }
  1258. else
  1259. {
  1260. LLViewerRegion* old_regionp =
  1261. ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion();
  1262. if (old_regionp != this)
  1263. {
  1264. // This object exists in two regions at the same time; this case
  1265. // can be safely ignored here because the server should soon send
  1266. // update message to remove one region for this object.
  1267. llwarns_once << "Entry: " << entry->getLocalID()
  1268. << " exists in two regions at the same time."
  1269. << llendl;
  1270. return NULL;
  1271. }
  1272. llwarns_once << "Entry: " << entry->getLocalID()
  1273. << " in rendering pipeline but not set to be active."
  1274. << llendl;
  1275. // Should not hit here any more, but does not hurt either, just put it
  1276. // back to active list
  1277. addActiveCacheEntry(entry);
  1278. }
  1279. if (objp)
  1280. {
  1281. loadCacheMiscExtras(objp);
  1282. }
  1283. return objp;
  1284. }
  1285. void LLViewerRegion::loadCacheMiscExtras(LLViewerObject* objp)
  1286. {
  1287. if (!objp)
  1288. {
  1289. return;
  1290. }
  1291. U32 local_id = objp->getLocalID();
  1292. LLVOCacheEntry::emap_t::iterator iter = mGLTFOverrides.find(local_id);
  1293. if (iter == mGLTFOverrides.end())
  1294. {
  1295. return;
  1296. }
  1297. LL_DEBUGS("ObjectCache") << "Applying cached data to object: "
  1298. << objp->getID() << LL_ENDL;
  1299. bool has_te[MAX_TES] = { false };
  1300. const LLGLTFOverrideCacheEntry& entry = iter->second;
  1301. for (auto it = entry.mGLTFMaterial.begin(),
  1302. end = entry.mGLTFMaterial.end();
  1303. it != end; ++it)
  1304. {
  1305. S32 te = it->first;
  1306. objp->setTEGLTFMaterialOverride(te, it->second);
  1307. if (objp->getTE(te) && objp->getTE(te)->isSelected())
  1308. {
  1309. LLGLTFMaterialList::doSelectionCallbacks(objp->getID(), te);
  1310. }
  1311. if (te < (S32)MAX_TES)
  1312. {
  1313. has_te[te] = true;
  1314. }
  1315. }
  1316. // Null out overrides on TEs that should not have them
  1317. for (U32 i = 0, count = llmin(objp->getNumTEs(), MAX_TES); i < count; ++i)
  1318. {
  1319. if (!has_te[i])
  1320. {
  1321. LLTextureEntry* tep = objp->getTE(i);
  1322. if (tep && tep->getGLTFMaterialOverride())
  1323. {
  1324. objp->setTEGLTFMaterialOverride(i, NULL);
  1325. LLGLTFMaterialList::doSelectionCallbacks(objp->getID(), i);
  1326. }
  1327. }
  1328. }
  1329. }
  1330. void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* objp)
  1331. {
  1332. if (!objp) return;
  1333. U32 local_id = objp->getLocalID();
  1334. LLVOCacheEntry::emap_t::iterator it = mGLTFOverrides.find(local_id);
  1335. if (it == mGLTFOverrides.end())
  1336. {
  1337. return;
  1338. }
  1339. for (auto& side : it->second.mGLTFMaterial)
  1340. {
  1341. objp->setTEGLTFMaterialOverride(side.first, side.second);
  1342. }
  1343. }
  1344. // Updates object cache if the object receives a full-update or a terse update
  1345. LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id,
  1346. LLViewerObject* objectp)
  1347. {
  1348. LLVOCacheEntry* entry = getCacheEntry(local_id);
  1349. if (!entry)
  1350. {
  1351. return objectp; // Not in the cache, do nothing.
  1352. }
  1353. if (!objectp) // Object not created
  1354. {
  1355. // Create a new object from cache.
  1356. objectp = addNewObject(entry);
  1357. }
  1358. // Remove from cache
  1359. killCacheEntry(entry, true);
  1360. return objectp;
  1361. }
  1362. void LLViewerRegion::forceUpdate()
  1363. {
  1364. mLandp->idleUpdate(0.f);
  1365. if (mParcelOverlay)
  1366. {
  1367. mParcelOverlay->idleUpdate(true);
  1368. }
  1369. }
  1370. bool LLViewerRegion::isEventPollInFlight() const
  1371. {
  1372. return mEventPoll && mEventPoll->isPollInFlight();
  1373. }
  1374. F32 LLViewerRegion::getEventPollRequestAge() const
  1375. {
  1376. return mEventPoll ? mEventPoll->getPollAge() : -1.f;
  1377. }
  1378. void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
  1379. {
  1380. mLandp->connectNeighbor(neighborp->mLandp, direction);
  1381. mCloudLayer.connectNeighbor(&(neighborp->mCloudLayer), direction);
  1382. }
  1383. void LLViewerRegion::disconnectAllNeighbors()
  1384. {
  1385. mLandp->disconnectAllNeighbors();
  1386. mCloudLayer.disconnectAllNeighbors();
  1387. }
  1388. F32 LLViewerRegion::getCompositionXY(S32 x, S32 y) const
  1389. {
  1390. if (x >= mWidth)
  1391. {
  1392. if (y >= mWidth)
  1393. {
  1394. LLVector3d center = getCenterGlobal() +
  1395. LLVector3d(mWidth, mWidth, 0.f);
  1396. LLViewerRegion* regionp = gWorld.getRegionFromPosGlobal(center);
  1397. if (regionp)
  1398. {
  1399. // OK, we need to do some hackery here - different simulators
  1400. // no longer use the same composition values, necessarily.
  1401. // If we're attempting to blend, then we want to make the
  1402. // fractional part of this region match the fractional of the
  1403. // adjacent. For now, just minimize the delta.
  1404. F32 our_comp = mCompositionp->getValueScaled(mWidth - 1.f,
  1405. mWidth - 1.f);
  1406. F32 adj_comp =
  1407. regionp->mCompositionp->getValueScaled(x - regionp->mWidth,
  1408. y - regionp->mWidth);
  1409. while (fabsf(our_comp - adj_comp) >= 1.f)
  1410. {
  1411. if (our_comp > adj_comp)
  1412. {
  1413. adj_comp += 1.f;
  1414. }
  1415. else
  1416. {
  1417. adj_comp -= 1.f;
  1418. }
  1419. }
  1420. return adj_comp;
  1421. }
  1422. }
  1423. else
  1424. {
  1425. LLVector3d center = getCenterGlobal() + LLVector3d(mWidth, 0, 0.f);
  1426. LLViewerRegion* regionp = gWorld.getRegionFromPosGlobal(center);
  1427. if (regionp)
  1428. {
  1429. // OK, we need to do some hackery here - different simulators
  1430. // no longer use the same composition values, necessarily.
  1431. // If we're attempting to blend, then we want to make the
  1432. // fractional part of this region match the fractional of the
  1433. // adjacent. For now, just minimize the delta.
  1434. F32 our_comp = mCompositionp->getValueScaled(mWidth - 1.f,
  1435. (F32)y);
  1436. F32 adj_comp =
  1437. regionp->mCompositionp->getValueScaled(x - regionp->mWidth,
  1438. (F32)y);
  1439. while (fabsf(our_comp - adj_comp) >= 1.f)
  1440. {
  1441. if (our_comp > adj_comp)
  1442. {
  1443. adj_comp += 1.f;
  1444. }
  1445. else
  1446. {
  1447. adj_comp -= 1.f;
  1448. }
  1449. }
  1450. return adj_comp;
  1451. }
  1452. }
  1453. }
  1454. else if (y >= mWidth)
  1455. {
  1456. LLVector3d center = getCenterGlobal() + LLVector3d(0.f, mWidth, 0.f);
  1457. LLViewerRegion* regionp = gWorld.getRegionFromPosGlobal(center);
  1458. if (regionp)
  1459. {
  1460. // OK, we need to do some hackery here - different simulators no
  1461. // longer use the same composition values, necessarily. If we're
  1462. // attempting to blend, then we want to make the fractional part of
  1463. // this region match the fractional of the adjacent. For now, just
  1464. // minimize the delta.
  1465. F32 our_comp = mCompositionp->getValueScaled((F32)x, mWidth - 1.f);
  1466. F32 adj_comp =
  1467. regionp->mCompositionp->getValueScaled((F32)x,
  1468. y - regionp->mWidth);
  1469. while (fabsf(our_comp - adj_comp) >= 1.f)
  1470. {
  1471. if (our_comp > adj_comp)
  1472. {
  1473. adj_comp += 1.f;
  1474. }
  1475. else
  1476. {
  1477. adj_comp -= 1.f;
  1478. }
  1479. }
  1480. return adj_comp;
  1481. }
  1482. }
  1483. return mCompositionp->getValueScaled((F32)x, (F32)y);
  1484. }
  1485. void LLViewerRegion::calculateCenterGlobal()
  1486. {
  1487. mCenterGlobal = mOriginGlobal;
  1488. mCenterGlobal.mdV[VX] += 0.5 * mWidth;
  1489. mCenterGlobal.mdV[VY] += 0.5 * mWidth;
  1490. mCenterGlobal.mdV[VZ] = 0.5 * mLandp->getMinZ() + mLandp->getMaxZ();
  1491. }
  1492. void LLViewerRegion::calculateCameraDistance()
  1493. {
  1494. mCameraDistanceSquared = (F32)(gAgent.getCameraPositionGlobal() -
  1495. getCenterGlobal()).lengthSquared();
  1496. }
  1497. std::ostream& operator<<(std::ostream& s, const LLViewerRegion& region)
  1498. {
  1499. s << "{ " << region.mHost
  1500. << " mOriginGlobal = " << region.getOriginGlobal() << "\n";
  1501. std::string name = region.getName();
  1502. if (!name.empty())
  1503. {
  1504. s << " mName = " << name << '\n';
  1505. }
  1506. name = region.getZoning();
  1507. if (!name.empty())
  1508. {
  1509. s << " mZoning = " << name << '\n';
  1510. }
  1511. s << "}";
  1512. return s;
  1513. }
  1514. void LLViewerRegion::updateNetStats()
  1515. {
  1516. F32 dt = mLastNetUpdate.getElapsedTimeAndResetF32();
  1517. LLCircuitData* cdp = gMessageSystemp->mCircuitInfo.findCircuit(mHost);
  1518. if (!cdp)
  1519. {
  1520. mAlive = false;
  1521. return;
  1522. }
  1523. mAlive = true;
  1524. mDeltaTime = dt;
  1525. mLastPacketsIn = mPacketsIn;
  1526. mLastBitsIn = mBitsIn;
  1527. mLastPacketsOut = mPacketsOut;
  1528. mLastPacketsLost = mPacketsLost;
  1529. mPacketsIn = cdp->getPacketsIn();
  1530. mBitsIn = 8 * cdp->getBytesIn();
  1531. mPacketsOut = cdp->getPacketsOut();
  1532. mPacketsLost = cdp->getPacketsLost();
  1533. mPingDelay = cdp->getPingDelay();
  1534. mBitStat.addValue(mBitsIn - mLastBitsIn);
  1535. mPacketsStat.addValue(mPacketsIn - mLastPacketsIn);
  1536. mPacketsLostStat.addValue(mPacketsLost);
  1537. }
  1538. U32 LLViewerRegion::getPacketsLost() const
  1539. {
  1540. LLCircuitData* cdp = gMessageSystemp->mCircuitInfo.findCircuit(mHost);
  1541. if (!cdp)
  1542. {
  1543. llinfos << "Could not find circuit for " << mHost << llendl;
  1544. return 0;
  1545. }
  1546. return cdp->getPacketsLost();
  1547. }
  1548. bool LLViewerRegion::pointInRegionGlobal(const LLVector3d& point_global) const
  1549. {
  1550. LLVector3 pos_region = getPosRegionFromGlobal(point_global);
  1551. return pos_region.mV[VX] >= 0 && pos_region.mV[VX] < mWidth &&
  1552. pos_region.mV[VY] >= 0 && pos_region.mV[VY] <mWidth;
  1553. }
  1554. LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3& pos_region) const
  1555. {
  1556. return gAgent.getPosAgentFromGlobal(getPosGlobalFromRegion(pos_region));
  1557. }
  1558. F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
  1559. {
  1560. return mLandp->resolveHeightRegion(region_pos);
  1561. }
  1562. bool LLViewerRegion::isOwnedSelf(const LLVector3& pos)
  1563. {
  1564. return mParcelOverlay && mParcelOverlay->isOwnedSelf(pos);
  1565. }
  1566. // Owned by a group you belong to? (officer or member)
  1567. bool LLViewerRegion::isOwnedGroup(const LLVector3& pos)
  1568. {
  1569. return mParcelOverlay && mParcelOverlay->isOwnedGroup(pos);
  1570. }
  1571. // Yhe new TCP coarse location handler node
  1572. class CoarseLocationUpdate final : public LLHTTPNode
  1573. {
  1574. public:
  1575. void post(ResponsePtr responder, const LLSD& context,
  1576. const LLSD& input) const override
  1577. {
  1578. LLHost host(input["sender"].asString());
  1579. LLViewerRegion* region = gWorld.getRegion(host);
  1580. if (!region)
  1581. {
  1582. return;
  1583. }
  1584. S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
  1585. S32 you_index = input["body"]["Index"][0]["You" ].asInteger();
  1586. std::vector<U32>* avatar_locs = &region->mMapAvatars;
  1587. uuid_vec_t* avatar_ids = &region->mMapAvatarIDs;
  1588. avatar_locs->clear();
  1589. avatar_ids->clear();
  1590. LLSD locs = input["body"]["Location"];
  1591. LLSD agents = input["body"]["AgentData"];
  1592. LLSD::array_iterator locs_it = locs.beginArray();
  1593. LLSD::array_iterator locs_end = locs.endArray();
  1594. LLSD::array_iterator agents_it = agents.beginArray();
  1595. bool has_agent_data = input["body"].has("AgentData");
  1596. // Variable region size support
  1597. F64 scale_factor = (F64)region->getWidth() / REGION_WIDTH_METERS;
  1598. for (S32 i = 0; locs_it != locs_end; ++i, ++locs_it)
  1599. {
  1600. U8 x = locs_it->get("X").asInteger();
  1601. U8 y = locs_it->get("Y").asInteger();
  1602. U8 z = locs_it->get("Z").asInteger();
  1603. // treat the target specially for the map, and don't add you or the
  1604. // target
  1605. if (i == target_index)
  1606. {
  1607. LLVector3d global_pos(region->getOriginGlobal());
  1608. global_pos.mdV[VX] += (F64)x * scale_factor;
  1609. global_pos.mdV[VY] += (F64)y * scale_factor;
  1610. global_pos.mdV[VZ] += (F64)z * 4.0;
  1611. gAvatarTracker.setTrackedCoarseLocation(global_pos);
  1612. }
  1613. else if (i != you_index)
  1614. {
  1615. U32 pos = 0x0;
  1616. pos |= x;
  1617. pos <<= 8;
  1618. pos |= y;
  1619. pos <<= 8;
  1620. pos |= z;
  1621. avatar_locs->push_back(pos);
  1622. if (has_agent_data)
  1623. {
  1624. // For backwards compatibility with old message format
  1625. avatar_ids->emplace_back(agents_it->get("AgentID").asUUID());
  1626. }
  1627. }
  1628. if (has_agent_data)
  1629. {
  1630. ++agents_it;
  1631. }
  1632. }
  1633. }
  1634. };
  1635. // build the coarse location HTTP node under the "/message" URL
  1636. LLHTTPRegistration<CoarseLocationUpdate>
  1637. gHTTPRegistrationCoarseLocationUpdate("/message/CoarseLocationUpdate");
  1638. // the deprecated coarse location handler
  1639. void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
  1640. {
  1641. mMapAvatars.clear();
  1642. mMapAvatarIDs.clear();
  1643. U8 x_pos = 0;
  1644. U8 y_pos = 0;
  1645. U8 z_pos = 0;
  1646. U32 pos = 0x0;
  1647. S16 agent_index;
  1648. S16 target_index;
  1649. msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
  1650. msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
  1651. // Variable region size support
  1652. F64 scale_factor = (F64)mWidth / REGION_WIDTH_METERS;
  1653. bool has_agent_data = msg->has(_PREHASH_AgentData);
  1654. S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
  1655. LLUUID agent_id;
  1656. for (S32 i = 0; i < count; ++i)
  1657. {
  1658. msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
  1659. msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
  1660. msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
  1661. agent_id.setNull();
  1662. if (has_agent_data)
  1663. {
  1664. msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID,
  1665. agent_id, i);
  1666. }
  1667. // Treat the target specially for the map
  1668. if (i == target_index)
  1669. {
  1670. LLVector3d global_pos(mOriginGlobal);
  1671. global_pos.mdV[VX] += (F64)x_pos * scale_factor;
  1672. global_pos.mdV[VY] += (F64)y_pos * scale_factor;
  1673. global_pos.mdV[VZ] += (F64)z_pos * 4.0;
  1674. gAvatarTracker.setTrackedCoarseLocation(global_pos);
  1675. }
  1676. // Do not add self
  1677. if (i != agent_index)
  1678. {
  1679. pos = 0x0;
  1680. pos |= x_pos;
  1681. pos <<= 8;
  1682. pos |= y_pos;
  1683. pos <<= 8;
  1684. pos |= z_pos;
  1685. mMapAvatars.push_back(pos);
  1686. if (has_agent_data)
  1687. {
  1688. mMapAvatarIDs.emplace_back(agent_id);
  1689. }
  1690. else
  1691. {
  1692. // Maintain strict coherency in indices bewteen the mMapAvatars
  1693. // and mMapAvatarIDs vectors, else things could get messy in
  1694. // LLWorld::getAvatars()... HB
  1695. mMapAvatarIDs.emplace_back(LLUUID::null);
  1696. }
  1697. }
  1698. }
  1699. }
  1700. void LLViewerRegion::getInfo(LLSD& info)
  1701. {
  1702. info["Region"]["Host"] = mHost.getIPandPort();
  1703. info["Region"]["Name"] = mName;
  1704. U32 x, y;
  1705. from_region_handle(getHandle(), &x, &y);
  1706. info["Region"]["Handle"]["x"] = (LLSD::Integer)x;
  1707. info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
  1708. }
  1709. //static
  1710. void LLViewerRegion::requestBaseCapabilitiesCoro(U64 region_handle)
  1711. {
  1712. LLViewerRegion* self = gWorld.getRegionFromHandle(region_handle);
  1713. if (!self)
  1714. {
  1715. // Region was since disconnected. Ignore and abort.
  1716. return;
  1717. }
  1718. LLCoreHttpUtil::HttpCoroutineAdapter adapter("BaseCapabilitiesRequest");
  1719. LLSD result;
  1720. // This loop is used for retrying a capabilities request.
  1721. do
  1722. {
  1723. const std::string& url = self->getCapability("Seed");
  1724. if (url.empty())
  1725. {
  1726. llwarns << "No Seed capability for region: "
  1727. << self->getIdentity() << ". Aborted." << llendl;
  1728. self->setCapabilitiesError();
  1729. break;
  1730. }
  1731. EStartupState state = LLStartUp::getStartupState();
  1732. if (state < STATE_WORLD_INIT)
  1733. {
  1734. llinfos << "Aborting capabilities request, reason: returned to login screen"
  1735. << llendl;
  1736. break;
  1737. }
  1738. if (++self->mSeedCapAttempts > MAX_CAP_REQUEST_ATTEMPTS)
  1739. {
  1740. // *TODO: Give a user pop-up about this error ?
  1741. llwarns << "Failed to get seed capability from '" << url
  1742. << "' after " << self->mSeedCapAttempts
  1743. << " attempts, for region: " << self->getIdentity()
  1744. << ". Giving up !" << llendl;
  1745. self->setCapabilitiesError();
  1746. break;
  1747. }
  1748. U32 id = ++self->mHttpResponderID;
  1749. LLSD cap_names = LLSD::emptyArray();
  1750. buildCapabilityNames(cap_names);
  1751. llinfos << "Attempt #" << self->mSeedCapAttempts
  1752. << " at requesting seed for region " << self->getIdentity()
  1753. << " from: " << url << llendl;
  1754. result = adapter.postAndSuspend(url, cap_names, sHttpOptions,
  1755. sHttpHeaders);
  1756. state = LLStartUp::getStartupState();
  1757. if (state < STATE_WORLD_INIT)
  1758. {
  1759. llinfos << "Aborting capabilities request, reason: returned to login screen"
  1760. << llendl;
  1761. break;
  1762. }
  1763. // Abort now if we are quitting
  1764. if (LLApp::isExiting() || gDisconnected)
  1765. {
  1766. break;
  1767. }
  1768. self = gWorld.getRegionFromHandle(region_handle);
  1769. if (!self)
  1770. {
  1771. llwarns << "Received a capability response for a disconnected region. Ignored."
  1772. << llendl;
  1773. break;
  1774. }
  1775. if (id != self->mHttpResponderID)
  1776. {
  1777. llwarns << "Received a staled capability response. Ignored."
  1778. << llendl;
  1779. continue;
  1780. }
  1781. if (!result.isMap() || result.has("error"))
  1782. {
  1783. llwarns << "Malformed response. Ignored." << llendl;
  1784. continue;
  1785. }
  1786. LLCore::HttpStatus status =
  1787. LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(result);
  1788. if (!status)
  1789. {
  1790. llwarns << "HTTP error fetching capabilities for region: "
  1791. << self->getIdentity() << ". Will retry..."
  1792. << llendl;
  1793. continue;
  1794. }
  1795. // Remove the http_result from the llsd
  1796. result.erase("http_result");
  1797. for (LLSD::map_const_iterator iter = result.beginMap(),
  1798. end = result.endMap();
  1799. iter != end; ++iter)
  1800. {
  1801. self->setCapability(iter->first, iter->second);
  1802. LL_DEBUGS("Capabilities") << "Got capability '" << iter->first
  1803. << "' for region: "
  1804. << self->getIdentity() << LL_ENDL;
  1805. }
  1806. self->setCapabilitiesReceived(true);
  1807. break;
  1808. }
  1809. while (true);
  1810. }
  1811. //static
  1812. void LLViewerRegion::requestBaseCapabilitiesCompleteCoro(U64 region_handle)
  1813. {
  1814. LLViewerRegion* self = gWorld.getRegionFromHandle(region_handle);
  1815. if (!self)
  1816. {
  1817. // Region was since disconnected. Ignore and abort.
  1818. return;
  1819. }
  1820. const std::string& url = self->getCapability("Seed");
  1821. if (url.empty())
  1822. {
  1823. llwarns << "No 'Seed' capability for region: " << self->getIdentity()
  1824. << ". Aborted." << llendl;
  1825. // Note: initial attempt failed to get this cap as well...
  1826. self->setCapabilitiesError();
  1827. return;
  1828. }
  1829. LLSD cap_names = LLSD::emptyArray();
  1830. buildCapabilityNames(cap_names);
  1831. llinfos << "Requesting second 'Seed' capability for region "
  1832. << self->getIdentity() << " from: " << url << llendl;
  1833. LLCoreHttpUtil::HttpCoroutineAdapter adapter("BaseCapabilitiesRequest");
  1834. LLSD result = adapter.postAndSuspend(url, cap_names, sHttpOptions,
  1835. sHttpHeaders);
  1836. // Abort now if we are quitting
  1837. if (LLApp::isExiting() || gDisconnected)
  1838. {
  1839. return;
  1840. }
  1841. self = gWorld.getRegionFromHandle(region_handle);
  1842. if (!self)
  1843. {
  1844. llwarns << "Received a capability response for a disconnected region. Ignored."
  1845. << llendl;
  1846. return;
  1847. }
  1848. LLCore::HttpStatus status =
  1849. LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(result);
  1850. if (!status)
  1851. {
  1852. llwarns << "HTTP error fetching second capabilities for region: "
  1853. << self->getIdentity() << llendl;
  1854. return;
  1855. }
  1856. // Remove the http_result from the LLSD
  1857. result.erase("http_result");
  1858. bool set_cap = gSavedSettings.getBool("RegisterChangedCaps");
  1859. U32 old_count = (U32)self->getCapabilitiesCount();
  1860. U32 count = 0;
  1861. std::string new_caps_list;
  1862. std::string changed_caps_list;
  1863. for (LLSD::map_const_iterator iter = result.beginMap(),
  1864. end = result.endMap();
  1865. iter != end; ++iter)
  1866. {
  1867. const std::string name = iter->first;
  1868. const std::string url = iter->second;
  1869. if (self->isSpecialCapabilityName(name))
  1870. {
  1871. // Do not count special capabilities that are not kept in the map.
  1872. LL_DEBUGS("Capabilities") << "Got special capability: " << name
  1873. << " - " << url << LL_ENDL;
  1874. continue;
  1875. }
  1876. const std::string& old_url = self->getCapability(name.c_str());
  1877. if (old_url.empty())
  1878. {
  1879. if (!new_caps_list.empty())
  1880. {
  1881. new_caps_list += ", ";
  1882. }
  1883. new_caps_list += name;
  1884. if (set_cap)
  1885. {
  1886. self->setCapability(name, url);
  1887. }
  1888. LL_DEBUGS("Capabilities") << "New capability '" << name
  1889. << "' - URL: " << url << LL_ENDL;
  1890. }
  1891. else if (old_url != url)
  1892. {
  1893. if (!changed_caps_list.empty())
  1894. {
  1895. changed_caps_list += ", ";
  1896. }
  1897. changed_caps_list += name;
  1898. if (set_cap)
  1899. {
  1900. self->setCapability(name, url);
  1901. }
  1902. LL_DEBUGS("Capabilities") << "Changed capability '" << name
  1903. << "' - Old URL: " << old_url
  1904. << " - New URL: " << url << LL_ENDL;
  1905. }
  1906. else
  1907. {
  1908. LL_DEBUGS("Capabilities") << "Got duplicate capability (same url): "
  1909. << name << LL_ENDL;
  1910. }
  1911. ++count;
  1912. }
  1913. self->onCapabilitiesReceived();
  1914. if (!new_caps_list.empty())
  1915. {
  1916. if (set_cap)
  1917. {
  1918. llinfos << "Simulator " << self->getIdentity()
  1919. << " sent the following new capabilities: "
  1920. << new_caps_list << llendl;
  1921. }
  1922. else
  1923. {
  1924. llwarns_once << "Simulator " << self->getIdentity()
  1925. << " sent the following new capabilities: "
  1926. << new_caps_list << ". Ignoring." << llendl;
  1927. }
  1928. }
  1929. if (!changed_caps_list.empty())
  1930. {
  1931. if (set_cap)
  1932. {
  1933. llinfos << "Simulator " << self->getIdentity()
  1934. << " sent new URLs for capabilities: "
  1935. << changed_caps_list << llendl;
  1936. }
  1937. else
  1938. {
  1939. llwarns_once << "Simulator " << self->getIdentity()
  1940. << " sent new URLs for capabilities: "
  1941. << changed_caps_list << ". Ignoring." << llendl;
  1942. }
  1943. }
  1944. if (count != old_count + (U32)new_caps_list.size())
  1945. {
  1946. // There are some capabilities missing in the new set (which seems
  1947. // to be a very common occurrence, thus the LL_DEBUGS instead of a
  1948. // llwarns).
  1949. LL_DEBUGS("Capabilities") << "Simulator " << self->getIdentity()
  1950. << " sent a new, smaller set of capabilities."
  1951. << LL_ENDL;
  1952. }
  1953. }
  1954. //static
  1955. void LLViewerRegion::requestSimulatorFeatureCoro(std::string url,
  1956. U64 region_handle)
  1957. {
  1958. LLViewerRegion* self = gWorld.getRegionFromHandle(region_handle);
  1959. if (!self)
  1960. {
  1961. // Region was since disconnected. Ignore and abort.
  1962. return;
  1963. }
  1964. LLCoreHttpUtil::HttpCoroutineAdapter adapter("SimFeatureRequest");
  1965. U32 attempt = 0;
  1966. LLSD result;
  1967. // This loop is used for retrying a capabilities request.
  1968. do
  1969. {
  1970. if (++attempt > MAX_CAP_REQUEST_ATTEMPTS)
  1971. {
  1972. llwarns << "Retries count exceeded attempting to get simulator feature for region "
  1973. << self->getIdentity() << " from: " << url << llendl;
  1974. break;
  1975. }
  1976. result = adapter.getAndSuspend(url, sHttpOptions, sHttpHeaders);
  1977. // Abort now if we are quitting
  1978. if (LLApp::isExiting() || gDisconnected)
  1979. {
  1980. break;
  1981. }
  1982. self = gWorld.getRegionFromHandle(region_handle);
  1983. if (!self)
  1984. {
  1985. // Region was since disconnected. Ignore and abort.
  1986. llwarns << "Received a simulator feature for a disconnected region. Ignored."
  1987. << llendl;
  1988. break;
  1989. }
  1990. LLCore::HttpStatus status =
  1991. LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(result);
  1992. if (!status)
  1993. {
  1994. llwarns << "HTTP error fetching simulator feature for region: "
  1995. << self->getIdentity() << ". Will retry..." << llendl;
  1996. continue;
  1997. }
  1998. // Remove the http_result from the LLSD
  1999. result.erase("http_result");
  2000. self->setSimulatorFeatures(result);
  2001. break;
  2002. }
  2003. while (true);
  2004. }
  2005. void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
  2006. {
  2007. llinfos << "Received simulator features for region: " << getIdentity()
  2008. << llendl;
  2009. LL_DEBUGS("SimulatorFeatures") << "\n";
  2010. std::stringstream str;
  2011. LLSDSerialize::toPrettyXML(sim_features, str);
  2012. LL_CONT << str.str() << LL_ENDL;
  2013. mSimulatorFeatures = sim_features;
  2014. mFeaturesReceived = true;
  2015. if (mSimulatorFeatures.has("HostName"))
  2016. {
  2017. mHostName = mSimulatorFeatures["HostName"].asString();
  2018. if (!gIsInSecondLife &&
  2019. // AWS server reporting the alias for SL sim hostname. HB
  2020. mHostName.find("secondlife.io") != std::string::npos)
  2021. {
  2022. llwarns << "Second Life sim detected while supposedly logged in OpenSim !"
  2023. << llendl;
  2024. gIsInSecondLife = true,
  2025. gIsInSecondLifeBetaGrid =
  2026. mHostName.find("aditi") != std::string::npos;
  2027. gIsInProductionGrid = gIsInSecondLifeProductionGrid =
  2028. !gIsInSecondLifeBetaGrid;
  2029. if (gViewerWindowp)
  2030. {
  2031. gViewerWindowp->setMenuBackgroundColor();
  2032. }
  2033. llinfos << "Switched to Second Life mode/policy." << llendl;
  2034. }
  2035. }
  2036. // Cache physics shape types availability flag. HB
  2037. mPhysicsShapeTypes = mSimulatorFeatures.has("PhysicsShapeTypes");
  2038. LL_DEBUGS("SimulatorFeatures") << "Physics shape types"
  2039. << (mPhysicsShapeTypes ? " " : " not ")
  2040. << "supported"
  2041. << LL_ENDL;
  2042. // Avatar Hover Height support. HB
  2043. mHoverHeigthFeature = !getCapability("AgentPreferences").empty() &&
  2044. mSimulatorFeatures.has("AvatarHoverHeightEnabled") &&
  2045. mSimulatorFeatures["AvatarHoverHeightEnabled"].asBoolean();
  2046. // Cache mesh support data. HB
  2047. mMeshRezEnabled = mSimulatorFeatures.has("MeshRezEnabled") &&
  2048. mSimulatorFeatures["MeshRezEnabled"].asBoolean();
  2049. mMeshUploadEnabled = mSimulatorFeatures.has("MeshUploadEnabled") &&
  2050. mSimulatorFeatures["MeshUploadEnabled"].asBoolean();
  2051. LL_DEBUGS("SimulatorFeatures") << "Mesh rezzing "
  2052. << (mMeshRezEnabled ? "enabled"
  2053. : " disabled")
  2054. << " - Mesh upload "
  2055. << (mMeshUploadEnabled ? "enabled"
  2056. : " disabled")
  2057. << LL_ENDL;
  2058. // Materials-related features. HB
  2059. if (mSimulatorFeatures.has("MaxMaterialsPerTransaction") &&
  2060. mSimulatorFeatures["MaxMaterialsPerTransaction"].isInteger())
  2061. {
  2062. mMaxMaterialsPerTransaction =
  2063. mSimulatorFeatures["MaxMaterialsPerTransaction"].asInteger();
  2064. }
  2065. else
  2066. {
  2067. LL_DEBUGS("Materials") << "Region " << getIdentity()
  2068. << " did not return MaxMaterialsPerTransaction, using default: 50"
  2069. << LL_ENDL;
  2070. }
  2071. if (mSimulatorFeatures.has("RenderMaterialsCapability") &&
  2072. mSimulatorFeatures["RenderMaterialsCapability"].isReal())
  2073. {
  2074. F32 value = mSimulatorFeatures["RenderMaterialsCapability"].asReal();
  2075. if (value > 0.f)
  2076. {
  2077. mRenderMaterialsCapability = 1.f / value;
  2078. LL_DEBUGS("Materials") << "Region " << getIdentity()
  2079. << " RenderMaterialsCapability = " << value
  2080. << " req/s." << LL_ENDL;
  2081. }
  2082. else
  2083. {
  2084. llwarns << "Region " << getIdentity()
  2085. << " returned invalid RenderMaterialsCapability; using default (1 request/s)."
  2086. << llendl;
  2087. }
  2088. }
  2089. else
  2090. {
  2091. LL_DEBUGS("Materials") << "Region " << getIdentity()
  2092. << " did not return RenderMaterialsCapability, using default (1 request/s)."
  2093. << LL_ENDL;
  2094. }
  2095. // Mega-textures support.
  2096. if (mSimulatorFeatures.has("MaxTextureResolution"))
  2097. {
  2098. mMaxTextureSize =
  2099. llclamp(mSimulatorFeatures["MaxTextureResolution"].asInteger(),
  2100. // Make sure we stay within our limits. HB
  2101. 1024, MAX_IMAGE_SIZE / 2);
  2102. if (mMaxTextureSize > gMaxImageSizeDefault)
  2103. {
  2104. llinfos << "Detected a larger image size limit for region "
  2105. << getIdentity() << " (" << mMaxTextureSize << " vs "
  2106. << gMaxImageSizeDefault
  2107. << "): adopting it as the new limit." << llendl;
  2108. gMaxImageSizeDefault = mMaxTextureSize;
  2109. update_upload_costs_in_menus();
  2110. }
  2111. }
  2112. // PBR terrain support
  2113. if (mSimulatorFeatures.has("GLTFEnabled"))
  2114. {
  2115. mGLTFEnabled = true;
  2116. }
  2117. if (mGLTFEnabled || mSimulatorFeatures.has("PBRTerrainEnabled"))
  2118. {
  2119. mHasPBRTerrain = true;
  2120. }
  2121. // Cache path finding support data. HB
  2122. mDynamicPathfinding = mSimulatorFeatures.has("DynamicPathfindingEnabled");
  2123. mDynamicPathfindingEnabled = mDynamicPathfinding &&
  2124. mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean();
  2125. LL_DEBUGS("SimulatorFeatures") << "Dynamic pathfinding "
  2126. << (mDynamicPathfinding ?
  2127. (mDynamicPathfindingEnabled ? "enabled"
  2128. : " disabled")
  2129. : " not supported")
  2130. << LL_ENDL;
  2131. mBakesOnMeshEnabled = mSimulatorFeatures.has("BakesOnMeshEnabled") &&
  2132. mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean();
  2133. if (gAgent.getRegion() == this)
  2134. {
  2135. gAgent.setUploadedBakesLimit();
  2136. }
  2137. LL_DEBUGS("SimulatorFeatures") << "Bake on mesh "
  2138. << (mBakesOnMeshEnabled ? "enabled"
  2139. : "disabled")
  2140. << LL_ENDL;
  2141. // We will not erase URLs passed on login (see below)...
  2142. // This poses a problem for cross-grid TPs, when the arrival grid does not
  2143. // provide the URLs for the corresponding services via the simulator
  2144. // features and the departure grid did provide them via the login.cgi
  2145. // script (and not via the simulator features either), but it is still
  2146. // better than not erasing the sim-provided URLs when the arrival grid
  2147. // does not provide the same services... HB
  2148. // *TODO: detect cross-grid TPs and erase the URLs only when they occur...
  2149. bool got_map_url = LLWorldMap::wasMapURLSetOnLogin();
  2150. bool got_search_url = HBFloaterSearch::wasSearchURLSetOnLogin();
  2151. // Cache OpenSim specific data. HB
  2152. // See: http://opensimulator.org/wiki/SimulatorFeatures_Extras
  2153. if (mSimulatorFeatures.has("OpenSimExtras"))
  2154. {
  2155. if (gIsInSecondLife)
  2156. {
  2157. llwarns << "OpenSim features detected while supposedly logged in Second Life !"
  2158. << llendl;
  2159. gIsInSecondLife = false,
  2160. gIsInProductionGrid = true;
  2161. gIsInSecondLifeBetaGrid = gIsInSecondLifeProductionGrid = false;
  2162. if (gViewerWindowp)
  2163. {
  2164. gViewerWindowp->setMenuBackgroundColor();
  2165. }
  2166. llinfos << "Switched to OpenSim mode/policy." << llendl;
  2167. }
  2168. const LLSD& extras = mSimulatorFeatures["OpenSimExtras"];
  2169. // Export permission support
  2170. bool old_value = mOSExportPermSupported;
  2171. mOSExportPermSupported = extras.has("ExportSupported") &&
  2172. extras["ExportSupported"].asBoolean();
  2173. if (mOSExportPermSupported != old_value)
  2174. {
  2175. dialog_refresh_all();
  2176. }
  2177. if (extras.has("map-server-url"))
  2178. {
  2179. LLWorldMap::gotMapServerURL(true);
  2180. LLWorldMap::setMapServerURL(extras["map-server-url"].asString());
  2181. LL_DEBUGS("SimulatorFeatures") << "Map server URL set to: "
  2182. << extras["map-server-url"].asString()
  2183. << LL_ENDL;
  2184. got_map_url = true;
  2185. }
  2186. if (extras.has("search-server-url"))
  2187. {
  2188. std::string url = extras["search-server-url"].asString();
  2189. HBFloaterSearch::setSearchURL(url);
  2190. LL_DEBUGS("SimulatorFeatures") << "Search URL: " << url << LL_ENDL;
  2191. got_search_url = true;
  2192. }
  2193. // Whisper/chat/shout ranges: seen in OS Grid...
  2194. if (extras.has("whisper-range"))
  2195. {
  2196. mWhisperRange = (U32)extras["whisper-range"].asInteger();
  2197. LL_DEBUGS("SimulatorFeatures") << "Whisper range: "
  2198. << mWhisperRange << "m"
  2199. << LL_ENDL;
  2200. }
  2201. if (extras.has("say-range"))
  2202. {
  2203. mChatRange = (U32)extras["say-range"].asInteger();
  2204. gAgent.setNearChatRadius((F32)mChatRange * 0.5f);
  2205. LL_DEBUGS("SimulatorFeatures") << "Chat range: " << mChatRange
  2206. << "m" << LL_ENDL;
  2207. }
  2208. if (extras.has("shout-range"))
  2209. {
  2210. mShoutRange = (U32)extras["shout-range"].asInteger();
  2211. LL_DEBUGS("SimulatorFeatures") << "Shout range: " << mShoutRange
  2212. << "m" << LL_ENDL;
  2213. }
  2214. }
  2215. if (mSimulatorFeatures.has("GridServices"))
  2216. {
  2217. const LLSD& services = mSimulatorFeatures["GridServices"];
  2218. // Seen in Speculoos...
  2219. if (services.has("search"))
  2220. {
  2221. std::string url = services["search"].asString();
  2222. HBFloaterSearch::setSearchURL(url);
  2223. LL_DEBUGS("SimulatorFeatures") << "Search URL: " << url << LL_ENDL;
  2224. got_search_url = true;
  2225. }
  2226. }
  2227. // When in OpenSim, erase the map and search URLs if not found in sim
  2228. // features and not set at login time (see above). HB
  2229. // *TODO: detect cross-grid TPs and erase the URLs only when they occur...
  2230. if (!gIsInSecondLife)
  2231. {
  2232. if (!got_map_url)
  2233. {
  2234. LLWorldMap::gotMapServerURL(false);
  2235. }
  2236. if (!got_search_url)
  2237. {
  2238. HBFloaterSearch::setSearchURL("");
  2239. }
  2240. }
  2241. mFeaturesReceivedSignal(getRegionID());
  2242. // This is a single-shot signal. Forget callbacks to save resources.
  2243. mFeaturesReceivedSignal.disconnect_all_slots();
  2244. }
  2245. boost::signals2::connection LLViewerRegion::setFeaturesReceivedCB(const caps_received_cb_t& cb)
  2246. {
  2247. return mFeaturesReceivedSignal.connect(cb);
  2248. }
  2249. // This is called when the parent is not cacheable. Moves all orphan children
  2250. // out of the cache and inserts them into the rendering octree.
  2251. void LLViewerRegion::findOrphans(U32 parent_id)
  2252. {
  2253. orphan_list_t::iterator iter = mOrphanMap.find(parent_id);
  2254. if (iter != mOrphanMap.end())
  2255. {
  2256. std::vector<U32>* children = &mOrphanMap[parent_id];
  2257. for (S32 i = 0, count = children->size(); i < count; ++i)
  2258. {
  2259. // Parent is visible, so is the child.
  2260. addVisibleChildCacheEntry(NULL, getCacheEntry((*children)[i]));
  2261. }
  2262. children->clear();
  2263. mOrphanMap.erase(parent_id);
  2264. }
  2265. }
  2266. void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
  2267. {
  2268. if (!sVOCacheCullingEnabled)
  2269. {
  2270. gObjectList.processObjectUpdateFromCache(entry, this);
  2271. return;
  2272. }
  2273. if (!entry || !entry->isValid())
  2274. {
  2275. return;
  2276. }
  2277. if (!entry->getEntry())
  2278. {
  2279. entry->setOctreeEntry(NULL);
  2280. }
  2281. if (!entry->getDP())
  2282. {
  2283. return;
  2284. }
  2285. if (entry->getEntry()->hasDrawable())
  2286. {
  2287. // Already in the rendering pipeline
  2288. LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable();
  2289. if (drawablep)
  2290. {
  2291. LLViewerRegion* old_regionp = drawablep->getRegion();
  2292. if (old_regionp != this)
  2293. {
  2294. LLViewerObject* objp = drawablep->getVObj();
  2295. if (objp)
  2296. {
  2297. // Remove from old region
  2298. if (old_regionp)
  2299. {
  2300. old_regionp->killCacheEntry(objp->getLocalID());
  2301. }
  2302. // Change region
  2303. objp->setRegion(this);
  2304. }
  2305. }
  2306. }
  2307. addActiveCacheEntry(entry);
  2308. // Set parent id
  2309. U32 parent_id = 0;
  2310. LLViewerObject::unpackParentID(entry->getDP(), parent_id);
  2311. if (parent_id != entry->getParentID())
  2312. {
  2313. entry->setParentID(parent_id);
  2314. }
  2315. // Update the object
  2316. gObjectList.processObjectUpdateFromCache(entry, this);
  2317. return; // done
  2318. }
  2319. // Must not be active.
  2320. llassert_always(!entry->isState(LLVOCacheEntry::ACTIVE));
  2321. removeFromVOCacheTree(entry); // remove from cache octree if it is in.
  2322. LLVector3 pos, scale;
  2323. LLQuaternion rot;
  2324. // Decode spatial info and parent info
  2325. U32 parent_id = LLViewerObject::extractSpatialExtents(entry->getDP(),
  2326. pos, scale, rot);
  2327. U32 old_parent_id = entry->getParentID();
  2328. bool same_old_parent = parent_id == old_parent_id;
  2329. if (!same_old_parent) // Parent changed.
  2330. {
  2331. if (old_parent_id > 0) // Has an old parent, disconnect it
  2332. {
  2333. LLVOCacheEntry* old_parent = getCacheEntry(old_parent_id);
  2334. if (old_parent)
  2335. {
  2336. old_parent->removeChild(entry);
  2337. if (!old_parent->isState(LLVOCacheEntry::INACTIVE))
  2338. {
  2339. mVisibleEntries.erase(entry);
  2340. entry->setState(LLVOCacheEntry::INACTIVE);
  2341. }
  2342. }
  2343. }
  2344. entry->setParentID(parent_id);
  2345. }
  2346. if (parent_id > 0) // Got a new parent
  2347. {
  2348. // 1.- Find the parent in cache
  2349. LLVOCacheEntry* parent = getCacheEntry(parent_id);
  2350. // 2.- Parent is not in the cache, put into the orphan list.
  2351. if (!parent)
  2352. {
  2353. if (!same_old_parent)
  2354. {
  2355. // Check if parent is non-cacheable and already created
  2356. if (isNonCacheableObjectCreated(parent_id))
  2357. {
  2358. // Parent is visible, so is the child.
  2359. addVisibleChildCacheEntry(NULL, entry);
  2360. }
  2361. else
  2362. {
  2363. entry->setBoundingInfo(pos, scale);
  2364. mOrphanMap[parent_id].push_back(entry->getLocalID());
  2365. }
  2366. }
  2367. else
  2368. {
  2369. entry->setBoundingInfo(pos, scale);
  2370. }
  2371. }
  2372. // Not in cache.
  2373. else if (!parent->isState(LLVOCacheEntry::INACTIVE))
  2374. {
  2375. // Parent is visible, so is the child.
  2376. addVisibleChildCacheEntry(parent, entry);
  2377. }
  2378. else
  2379. {
  2380. entry->setBoundingInfo(pos, scale);
  2381. parent->addChild(entry);
  2382. if (parent->getGroup())
  2383. {
  2384. // Re-insert parent to vo-cache tree because its bounding info
  2385. // changed.
  2386. removeFromVOCacheTree(parent);
  2387. addToVOCacheTree(parent);
  2388. }
  2389. }
  2390. return;
  2391. }
  2392. //
  2393. // No parent
  2394. //
  2395. entry->setBoundingInfo(pos, scale);
  2396. if (!parent_id) // a potential parent
  2397. {
  2398. // Find all children and update their bounding info
  2399. orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID());
  2400. if (iter != mOrphanMap.end())
  2401. {
  2402. std::vector<U32>* orphans = &mOrphanMap[entry->getLocalID()];
  2403. for (S32 i = 0, count = orphans->size(); i < count; ++i)
  2404. {
  2405. LLVOCacheEntry* child = getCacheEntry((*orphans)[i]);
  2406. if (child)
  2407. {
  2408. entry->addChild(child);
  2409. }
  2410. }
  2411. orphans->clear();
  2412. mOrphanMap.erase(entry->getLocalID());
  2413. }
  2414. }
  2415. if (!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE))
  2416. {
  2417. addToVOCacheTree(entry);
  2418. }
  2419. }
  2420. LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer& dp,
  2421. U32 flags)
  2422. {
  2423. eCacheUpdateResult result;
  2424. U32 crc, local_id;
  2425. LLViewerObject::unpackU32(&dp, local_id, "LocalID");
  2426. LLViewerObject::unpackU32(&dp, crc, "CRC");
  2427. LLVOCacheEntry* entry = getCacheEntry(local_id, false);
  2428. if (entry)
  2429. {
  2430. entry->setValid();
  2431. // We have seen this object before
  2432. if (entry->getCRC() == crc)
  2433. {
  2434. // Record a hit
  2435. entry->recordDupe();
  2436. result = CACHE_UPDATE_DUPE;
  2437. }
  2438. else // CRC changed
  2439. {
  2440. // Update the cache entry
  2441. entry->updateEntry(crc, dp);
  2442. decodeBoundingInfo(entry);
  2443. result = CACHE_UPDATE_CHANGED;
  2444. }
  2445. }
  2446. else
  2447. {
  2448. // We have not seen this object before; create new entry and add to map
  2449. LLPointer<LLVOCacheEntry> new_entry = new LLVOCacheEntry(local_id, crc,
  2450. dp);
  2451. mCacheMap[local_id] = new_entry;
  2452. decodeBoundingInfo(new_entry);
  2453. entry = new_entry;
  2454. result = CACHE_UPDATE_ADDED;
  2455. }
  2456. if (flags != 0xffffffff)
  2457. {
  2458. entry->setUpdateFlags(flags);
  2459. LLUUID fullid;
  2460. gObjectList.getUUIDFromLocal(fullid, local_id,
  2461. gMessageSystemp->getSenderIP(),
  2462. gMessageSystemp->getSenderPort());
  2463. if (fullid.notNull())
  2464. {
  2465. LL_DEBUGS("ObjectCacheSpam") << "Set cache entry flags for object "
  2466. << fullid << " to: " << flags
  2467. << LL_ENDL;
  2468. // We MUST also update the corresponding object when it exists ! HB
  2469. LLViewerObject* objectp = gObjectList.findObject(fullid);
  2470. if (objectp)
  2471. {
  2472. objectp->loadFlags(flags);
  2473. }
  2474. }
  2475. }
  2476. return result;
  2477. }
  2478. void LLViewerRegion::cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry& data)
  2479. {
  2480. mGLTFOverrides[data.mLocalId] = data;
  2481. }
  2482. LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id)
  2483. {
  2484. if (!sVOCacheCullingEnabled)
  2485. {
  2486. return NULL;
  2487. }
  2488. LLVOCacheEntry* entryp = getCacheEntry(local_id);
  2489. removeFromVOCacheTree(entryp);
  2490. return entryp;
  2491. }
  2492. LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id, bool valid)
  2493. {
  2494. LLVOCacheEntry::map_t::iterator iter = mCacheMap.find(local_id);
  2495. if (iter != mCacheMap.end() && (!valid || iter->second->isValid()))
  2496. {
  2497. return iter->second;
  2498. }
  2499. return NULL;
  2500. }
  2501. void LLViewerRegion::addCacheMiss(U32 id,
  2502. LLViewerRegion::eCacheMissType miss_type)
  2503. {
  2504. #if 0
  2505. mCacheMissList[id] = miss_type;
  2506. #else
  2507. mCacheMissList.emplace_back(id, miss_type);
  2508. #endif
  2509. }
  2510. // Checks if a non-cacheable object is already created.
  2511. bool LLViewerRegion::isNonCacheableObjectCreated(U32 local_id)
  2512. {
  2513. return local_id > 0 && mNonCacheableCreatedList.count(local_id) != 0;
  2514. }
  2515. void LLViewerRegion::removeFromCreatedList(U32 local_id)
  2516. {
  2517. if (local_id > 0)
  2518. {
  2519. non_cacheable_list_t::iterator iter =
  2520. mNonCacheableCreatedList.find(local_id);
  2521. if (iter != mNonCacheableCreatedList.end())
  2522. {
  2523. mNonCacheableCreatedList.hset_erase(iter);
  2524. }
  2525. }
  2526. }
  2527. void LLViewerRegion::addToCreatedList(U32 local_id)
  2528. {
  2529. if (local_id > 0)
  2530. {
  2531. mNonCacheableCreatedList.insert(local_id);
  2532. }
  2533. }
  2534. // Get data packer for this object, if we have cached data AND the CRC matches.
  2535. bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags,
  2536. U8& cache_miss_type)
  2537. {
  2538. LLVOCacheEntry* entryp = getCacheEntry(local_id, false);
  2539. if (!entryp)
  2540. {
  2541. addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);
  2542. return false;
  2543. }
  2544. if (entryp->getCRC() != crc)
  2545. {
  2546. addCacheMiss(local_id, CACHE_MISS_TYPE_CRC);
  2547. return false;
  2548. }
  2549. cache_miss_type = CACHE_MISS_TYPE_NONE;
  2550. // We have seen this object before; record a hit.
  2551. entryp->recordHit();
  2552. if (flags != 0xffffffff)
  2553. {
  2554. LL_DEBUGS("ObjectCacheSpam") << "Setting cache entry flags for object ";
  2555. LLUUID fullid;
  2556. gObjectList.getUUIDFromLocal(fullid, local_id,
  2557. gMessageSystemp->getSenderIP(),
  2558. gMessageSystemp->getSenderPort());
  2559. if (fullid.notNull())
  2560. {
  2561. LL_CONT << fullid;
  2562. }
  2563. else
  2564. {
  2565. LL_CONT << " with local Id/from server " << local_id << "/"
  2566. << gMessageSystemp->getSender();
  2567. }
  2568. LL_CONT << " to: 0x" << std::hex << flags << std::dec << LL_ENDL;
  2569. }
  2570. entryp->setUpdateFlags(flags);
  2571. if (entryp->isState(LLVOCacheEntry::ACTIVE))
  2572. {
  2573. LLDrawable* drawablep = (LLDrawable*)entryp->getEntry()->getDrawable();
  2574. if (drawablep)
  2575. {
  2576. LLViewerObject* objp = drawablep->getVObj();
  2577. if (objp)
  2578. {
  2579. objp->loadFlags(flags);
  2580. }
  2581. }
  2582. }
  2583. else if (!entryp->isValid()) // If not already probed
  2584. {
  2585. entryp->setValid();
  2586. decodeBoundingInfo(entryp);
  2587. }
  2588. return true;
  2589. }
  2590. void LLViewerRegion::addCacheMissFull(U32 local_id)
  2591. {
  2592. addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);
  2593. }
  2594. void LLViewerRegion::requestCacheMisses()
  2595. {
  2596. if (mCacheMissList.empty())
  2597. {
  2598. return;
  2599. }
  2600. LLMessageSystem* msg = gMessageSystemp;
  2601. bool start_new_message = true;
  2602. S32 blocks = 0;
  2603. // Send requests for all cache-missed objects
  2604. for (CacheMissItem::cache_miss_list_t::iterator
  2605. iter = mCacheMissList.begin(), end = mCacheMissList.end();
  2606. iter != end; ++iter)
  2607. {
  2608. if (start_new_message)
  2609. {
  2610. msg->newMessageFast(_PREHASH_RequestMultipleObjects);
  2611. msg->nextBlockFast(_PREHASH_AgentData);
  2612. msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
  2613. msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
  2614. start_new_message = false;
  2615. }
  2616. msg->nextBlockFast(_PREHASH_ObjectData);
  2617. msg->addU8Fast(_PREHASH_CacheMissType, iter->mType);
  2618. msg->addU32Fast(_PREHASH_ID, iter->mID);
  2619. if (++blocks >= 255)
  2620. {
  2621. sendReliableMessage();
  2622. start_new_message = true;
  2623. blocks = 0;
  2624. }
  2625. }
  2626. // Finish any pending message
  2627. if (!start_new_message)
  2628. {
  2629. sendReliableMessage();
  2630. }
  2631. mCacheDirty = true;
  2632. mCacheMissList.clear();
  2633. }
  2634. void LLViewerRegion::dumpCache()
  2635. {
  2636. constexpr S32 BINS = 4;
  2637. S32 hit_bin[BINS];
  2638. S32 change_bin[BINS];
  2639. for (S32 i = 0; i < BINS; ++i)
  2640. {
  2641. hit_bin[i] = 0;
  2642. change_bin[i] = 0;
  2643. }
  2644. for (LLVOCacheEntry::map_t::iterator iter = mCacheMap.begin(),
  2645. end = mCacheMap.end();
  2646. iter != end; ++iter)
  2647. {
  2648. LLVOCacheEntry* entry = iter->second;
  2649. S32 hits = entry->getHitCount();
  2650. S32 changes = entry->getCRCChangeCount();
  2651. hits = llclamp(hits, 0, BINS - 1);
  2652. changes = llclamp(changes, 0, BINS - 1);
  2653. ++hit_bin[hits];
  2654. ++change_bin[changes];
  2655. }
  2656. llinfos << "Count " << mCacheMap.size() << llendl;
  2657. for (S32 i = 0; i < BINS; ++i)
  2658. {
  2659. llinfos << "Hits " << i << " " << hit_bin[i] << llendl;
  2660. }
  2661. for (S32 i = 0; i < BINS; ++i)
  2662. {
  2663. llinfos << "Changes " << i << " " << change_bin[i] << llendl;
  2664. }
  2665. }
  2666. void LLViewerRegion::unpackRegionHandshake()
  2667. {
  2668. LLMessageSystem* msg = gMessageSystemp;
  2669. U8 sim_access;
  2670. msg->getU8(_PREHASH_RegionInfo, _PREHASH_SimAccess, sim_access);
  2671. std::string sim_name;
  2672. msg->getString(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name);
  2673. LLUUID sim_owner;
  2674. msg->getUUID(_PREHASH_RegionInfo, _PREHASH_SimOwner, sim_owner);
  2675. bool manager;
  2676. msg->getBool(_PREHASH_RegionInfo, _PREHASH_IsEstateManager, manager);
  2677. F32 water_height;
  2678. msg->getF32(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
  2679. F32 billable_factor;
  2680. msg->getF32(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor);
  2681. LLUUID cache_id;
  2682. msg->getUUID(_PREHASH_RegionInfo, _PREHASH_CacheID, cache_id);
  2683. U64 region_flags = 0;
  2684. U64 region_protocols = 0;
  2685. if (msg->has(_PREHASH_RegionInfo4))
  2686. {
  2687. msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended,
  2688. region_flags);
  2689. msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols,
  2690. region_protocols);
  2691. }
  2692. else
  2693. {
  2694. U32 flags = 0;
  2695. msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
  2696. region_flags = flags;
  2697. }
  2698. setRegionProtocols(region_protocols);
  2699. setRegionFlags(region_flags);
  2700. setSimAccess(sim_access);
  2701. setRegionNameAndZone(sim_name);
  2702. setOwner(sim_owner);
  2703. setIsEstateManager(manager);
  2704. setWaterHeight(water_height);
  2705. setBillableFactor(billable_factor);
  2706. setCacheID(cache_id);
  2707. LL_DEBUGS("ObjectCache") << "Got hanshake message for region: " << mName
  2708. << " - Cache Id: " << mCacheID << LL_ENDL;
  2709. LLUUID region_id;
  2710. msg->getUUID(_PREHASH_RegionInfo2, _PREHASH_RegionID, region_id);
  2711. setRegionID(region_id);
  2712. // Retrieve the CR-53 (Homestead/Land SKU) information. The only reasonable
  2713. // way to decide if we actually have any data is to check to see if any of
  2714. // these fields have positive sizes.
  2715. if (msg->getSize(_PREHASH_RegionInfo3, _PREHASH_ColoName) > 0 ||
  2716. msg->getSize(_PREHASH_RegionInfo3, _PREHASH_ProductSKU) > 0 ||
  2717. msg->getSize(_PREHASH_RegionInfo3, _PREHASH_ProductName) > 0)
  2718. {
  2719. msg->getS32(_PREHASH_RegionInfo3, _PREHASH_CPUClassID, mClassID);
  2720. msg->getS32(_PREHASH_RegionInfo3, _PREHASH_CPURatio, mCPURatio);
  2721. msg->getString(_PREHASH_RegionInfo3, _PREHASH_ColoName, mColoName);
  2722. msg->getString(_PREHASH_RegionInfo3, _PREHASH_ProductSKU, mProductSKU);
  2723. msg->getString(_PREHASH_RegionInfo3, _PREHASH_ProductName,
  2724. mProductName);
  2725. }
  2726. mCentralBakeVersion = region_protocols & 1;
  2727. if (!gIsInSecondLife && !mBakesOnMeshEnabled)
  2728. {
  2729. mBakesOnMeshEnabled = region_protocols & 0x8000000000000000ll;
  2730. }
  2731. // Get the 4 textures for land
  2732. LLUUID tmp_id;
  2733. msg->getUUID(_PREHASH_RegionInfo, _PREHASH_TerrainDetail0, tmp_id);
  2734. bool changed = tmp_id != mCompositionp->getDetailAssetID(0);
  2735. mCompositionp->setDetailAssetID(0, tmp_id);
  2736. msg->getUUID(_PREHASH_RegionInfo, _PREHASH_TerrainDetail1, tmp_id);
  2737. changed |= tmp_id != mCompositionp->getDetailAssetID(1);
  2738. mCompositionp->setDetailAssetID(1, tmp_id);
  2739. msg->getUUID(_PREHASH_RegionInfo, _PREHASH_TerrainDetail2, tmp_id);
  2740. changed |= tmp_id != mCompositionp->getDetailAssetID(2);
  2741. mCompositionp->setDetailAssetID(2, tmp_id);
  2742. msg->getUUID(_PREHASH_RegionInfo, _PREHASH_TerrainDetail3, tmp_id);
  2743. changed |= tmp_id != mCompositionp->getDetailAssetID(3);
  2744. mCompositionp->setDetailAssetID(3, tmp_id);
  2745. // Get the start altitude and range values for land textures
  2746. F32 tmp_f32;
  2747. msg->getF32(_PREHASH_RegionInfo, _PREHASH_TerrainStartHeight00, tmp_f32);
  2748. changed |= tmp_f32 != mCompositionp->getStartHeight(0);
  2749. mCompositionp->setStartHeight(0, tmp_f32);
  2750. msg->getF32(_PREHASH_RegionInfo, _PREHASH_TerrainStartHeight01, tmp_f32);
  2751. changed |= tmp_f32 != mCompositionp->getStartHeight(1);
  2752. mCompositionp->setStartHeight(1, tmp_f32);
  2753. msg->getF32(_PREHASH_RegionInfo, _PREHASH_TerrainStartHeight10, tmp_f32);
  2754. changed |= tmp_f32 != mCompositionp->getStartHeight(2);
  2755. mCompositionp->setStartHeight(2, tmp_f32);
  2756. msg->getF32(_PREHASH_RegionInfo, _PREHASH_TerrainStartHeight11, tmp_f32);
  2757. changed |= tmp_f32 != mCompositionp->getStartHeight(3);
  2758. mCompositionp->setStartHeight(3, tmp_f32);
  2759. msg->getF32(_PREHASH_RegionInfo, _PREHASH_TerrainHeightRange00, tmp_f32);
  2760. changed |= tmp_f32 != mCompositionp->getHeightRange(0);
  2761. mCompositionp->setHeightRange(0, tmp_f32);
  2762. msg->getF32(_PREHASH_RegionInfo, _PREHASH_TerrainHeightRange01, tmp_f32);
  2763. changed |= tmp_f32 != mCompositionp->getHeightRange(1);
  2764. mCompositionp->setHeightRange(1, tmp_f32);
  2765. msg->getF32(_PREHASH_RegionInfo, _PREHASH_TerrainHeightRange10, tmp_f32);
  2766. changed |= tmp_f32 != mCompositionp->getHeightRange(2);
  2767. mCompositionp->setHeightRange(2, tmp_f32);
  2768. msg->getF32(_PREHASH_RegionInfo, _PREHASH_TerrainHeightRange11, tmp_f32);
  2769. changed |= tmp_f32 != mCompositionp->getHeightRange(3);
  2770. mCompositionp->setHeightRange(3, tmp_f32);
  2771. bool was_ready = mCompositionp->getParamsReady();
  2772. if (!was_ready)
  2773. {
  2774. mCompositionp->setParamsReady();
  2775. }
  2776. else if (changed)
  2777. {
  2778. mLandp->dirtyAllPatches();
  2779. }
  2780. // Update if the land changed
  2781. LL_DEBUGS("RegionTexture") << "Region: " << sim_name
  2782. << " - Composition did "
  2783. << (changed ? "" : "not ")
  2784. << "change and parameters were "
  2785. << (was_ready ? "" : "not " ) << "ready."
  2786. << LL_ENDL;
  2787. // Now that we have the name, we can load the cache file off disk.
  2788. loadObjectCache();
  2789. // Reply to the handshake, but not while we already have a threaded cache
  2790. // read in flight. In this latter case, just register a new pending
  2791. // handshake reply until the cache got read. HB
  2792. ++mPendingHandshakes;
  2793. if (!mCacheLoading)
  2794. {
  2795. sendHandshakeReply();
  2796. }
  2797. }
  2798. // *TODO: Send all upstream viewer->sim handshake info here.
  2799. void LLViewerRegion::sendHandshakeReply()
  2800. {
  2801. if (!mPendingHandshakes)
  2802. {
  2803. return;
  2804. }
  2805. --mPendingHandshakes;
  2806. LL_DEBUGS("ObjectCache") << "Sending handshake reply for region: "
  2807. << mName << LL_ENDL;
  2808. LLMessageSystem* msg = gMessageSystemp;
  2809. msg->newMessage(_PREHASH_RegionHandshakeReply);
  2810. msg->nextBlock(_PREHASH_AgentData);
  2811. msg->addUUID(_PREHASH_AgentID, gAgentID);
  2812. msg->addUUID(_PREHASH_SessionID, gAgentSessionID);
  2813. msg->nextBlock(_PREHASH_RegionInfo);
  2814. U32 flags = REGION_HANDSHAKE_SUPPORTS_SELF_APPEARANCE;
  2815. if (sVOCacheCullingEnabled)
  2816. {
  2817. // Set the bit 0 to be 1 to ask sim to send all cacheable objects.
  2818. flags |= 0x00000001;
  2819. }
  2820. if (mCacheMap.empty())
  2821. {
  2822. // Set the bit 1 to be 1 to tell sim the cache file is empty, no need
  2823. // to send cache probes.
  2824. flags |= 0x00000002;
  2825. }
  2826. msg->addU32(_PREHASH_Flags, flags);
  2827. msg->sendReliable(mHost);
  2828. }
  2829. //static
  2830. void LLViewerRegion::buildCapabilityNames(LLSD& cap_names)
  2831. {
  2832. cap_names.append("AbuseCategories");
  2833. cap_names.append("AcceptFriendship");
  2834. cap_names.append("AcceptGroupInvite"); // For use with ReadOfflineMsgs
  2835. cap_names.append("AgentExperiences");
  2836. cap_names.append("AgentPreferences");
  2837. cap_names.append("AgentProfile");
  2838. cap_names.append("AgentState");
  2839. #if 0 // *TODO: implement attachments scripts count ?
  2840. cap_names.append("AttachmentResources");
  2841. #endif
  2842. cap_names.append("AvatarPickerSearch");
  2843. cap_names.append("AvatarRenderInfo");
  2844. cap_names.append("CharacterProperties");
  2845. cap_names.append("ChatSessionRequest");
  2846. cap_names.append("CopyInventoryFromNotecard");
  2847. cap_names.append("CreateInventoryCategory");
  2848. cap_names.append("DeclineFriendship"); // For use with ReadOfflineMsgs
  2849. cap_names.append("DeclineGroupInvite");
  2850. cap_names.append("DirectDelivery");
  2851. cap_names.append("DispatchRegionInfo");
  2852. #if 0 // Windlight region settings (deprecated, not used by this viewer)
  2853. cap_names.append("EnvironmentSettings");
  2854. #endif
  2855. cap_names.append("EstateAccess");
  2856. cap_names.append("EstateChangeInfo");
  2857. cap_names.append("EventQueueGet");
  2858. if (gIsInSecondLife || gSavedSettings.getBool("UseHTTPInventory"))
  2859. {
  2860. cap_names.append("FetchInventory2");
  2861. cap_names.append("FetchInventoryDescendents2");
  2862. cap_names.append("FetchLib2");
  2863. cap_names.append("FetchLibDescendents2");
  2864. cap_names.append("InventoryAPIv3");
  2865. cap_names.append("LibraryAPIv3");
  2866. }
  2867. cap_names.append("ExperiencePreferences");
  2868. cap_names.append("ExperienceQuery");
  2869. cap_names.append("ExtEnvironment");
  2870. cap_names.append("FindExperienceByName");
  2871. cap_names.append("GetAdminExperiences");
  2872. cap_names.append("GetCreatorExperiences");
  2873. cap_names.append("GetExperiences");
  2874. cap_names.append("GetExperienceInfo");
  2875. cap_names.append("GetDisplayNames");
  2876. cap_names.append("GetMesh");
  2877. cap_names.append("GetMesh2");
  2878. cap_names.append("GetMetadata");
  2879. cap_names.append("GetObjectCost");
  2880. cap_names.append("GetObjectPhysicsData");
  2881. cap_names.append("GetTexture");
  2882. cap_names.append("GroupAPIv1");
  2883. cap_names.append("GroupExperiences");
  2884. cap_names.append("GroupMemberData");
  2885. cap_names.append("HomeLocation");
  2886. // For 360° snapshots which are not implemented in this viewer, but we can
  2887. // still request a 360° interest list if wanted, from the Advanced menu. HB
  2888. cap_names.append("InterestList");
  2889. cap_names.append("InventoryThumbnailUpload");
  2890. cap_names.append("IsExperienceAdmin");
  2891. cap_names.append("IsExperienceContributor");
  2892. cap_names.append("MapLayer");
  2893. cap_names.append("MapLayerGod");
  2894. cap_names.append("MeshUploadFlag");
  2895. cap_names.append("ModifyMaterialParams");
  2896. cap_names.append("NavMeshGenerationStatus");
  2897. cap_names.append("NewFileAgentInventory");
  2898. // Requesting this cap triggers the sending of UDP messages for puppets:
  2899. cap_names.append("ObjectAnimation");
  2900. cap_names.append("ObjectMedia");
  2901. cap_names.append("ObjectMediaNavigate");
  2902. cap_names.append("ObjectNavMeshProperties");
  2903. cap_names.append("ParcelNavigateMedia");
  2904. cap_names.append("ParcelPropertiesUpdate");
  2905. cap_names.append("ParcelVoiceInfoRequest");
  2906. cap_names.append("ProductInfoRequest");
  2907. cap_names.append("ProvisionVoiceAccountRequest");
  2908. cap_names.append("Puppetry");
  2909. // Needs AcceptGroupInvite & DeclineGroupInvite:
  2910. cap_names.append("ReadOfflineMsgs");
  2911. cap_names.append("RegionExperiences");
  2912. cap_names.append("RegionObjects"); // Replaces "ObjectNavMeshProperties"
  2913. cap_names.append("RemoteParcelRequest");
  2914. cap_names.append("RenderMaterials");
  2915. cap_names.append("RequestTextureDownload");
  2916. #if 0 // *TODO: implement in llfloaterobjectweights.cpp ?
  2917. cap_names.append("ResourceCostSelected");
  2918. #endif
  2919. cap_names.append("RetrieveNavMeshSrc");
  2920. cap_names.append("SearchStatRequest");
  2921. cap_names.append("SearchStatTracking");
  2922. cap_names.append("SendPostcard");
  2923. cap_names.append("SendUserReport");
  2924. cap_names.append("SendUserReportWithScreenshot");
  2925. cap_names.append("ServerReleaseNotes");
  2926. cap_names.append("SetDisplayName");
  2927. cap_names.append("SimConsole");
  2928. cap_names.append("SimConsoleAsync");
  2929. cap_names.append("SimulatorFeatures");
  2930. cap_names.append("TerrainNavMeshProperties");
  2931. cap_names.append("UntrustedSimulatorMessage");
  2932. cap_names.append("UpdateAgentInformation");
  2933. cap_names.append("UpdateAgentLanguage");
  2934. cap_names.append("UpdateAvatarAppearance");
  2935. cap_names.append("UpdateExperience");
  2936. cap_names.append("UpdateGestureAgentInventory");
  2937. cap_names.append("UpdateGestureTaskInventory");
  2938. cap_names.append("UpdateMaterialAgentInventory");
  2939. cap_names.append("UpdateMaterialTaskInventory");
  2940. cap_names.append("UpdateNotecardAgentInventory");
  2941. cap_names.append("UpdateNotecardTaskInventory");
  2942. cap_names.append("UpdateScriptAgent");
  2943. cap_names.append("UpdateScriptTask");
  2944. cap_names.append("UpdateSettingsAgentInventory");
  2945. cap_names.append("UpdateSettingsTaskInventory");
  2946. cap_names.append("UploadBakedTexture");
  2947. cap_names.append("UserInfo");
  2948. static LLCachedControl<U32> advertize(gSavedSettings,
  2949. "OSAdvertizePBRTerrain");
  2950. if (!gIsInSecondLife && advertize)
  2951. {
  2952. // Capability telling OpenSim we do support PBR terrain. HB
  2953. cap_names.append(advertize > 1 ? "VETPBR" : "VTPBR");
  2954. }
  2955. cap_names.append("ViewerAsset");
  2956. cap_names.append("ViewerBenefits");
  2957. cap_names.append("ViewerStartAuction");
  2958. cap_names.append("ViewerStats");
  2959. cap_names.append("VoiceSignalingRequest");
  2960. }
  2961. std::string LLViewerRegion::getIdentity() const
  2962. {
  2963. std::string name;
  2964. if (mName.empty())
  2965. {
  2966. #if 0 // This can lead to long hiccups or "pauses" when the host is unknown
  2967. // and the DNS resolves too slowly... HB
  2968. name = mHost.getHostName();
  2969. #else
  2970. name = mHost.getIPString();
  2971. #endif
  2972. }
  2973. else
  2974. {
  2975. name = mName;
  2976. }
  2977. if (mRegionID.isNull())
  2978. {
  2979. return name;
  2980. }
  2981. return name + " (" + mRegionID.asString() + ")";
  2982. }
  2983. void LLViewerRegion::setSeedCapability(const std::string& url)
  2984. {
  2985. if (getCapability("Seed") == url)
  2986. {
  2987. std::string coro =
  2988. gCoros.launch("LLViewerRegion::requestBaseCapabilitiesCompleteCoro",
  2989. boost::bind(&LLViewerRegion::requestBaseCapabilitiesCompleteCoro,
  2990. mHandle));
  2991. llinfos << "Coroutine " << coro
  2992. << " launched for duplicate Seed for region " << getIdentity()
  2993. << llendl;
  2994. return;
  2995. }
  2996. delete mEventPoll;
  2997. mEventPoll = NULL;
  2998. mFeaturesReceived = mHoverHeigthFeature = false;
  2999. mSimulatorFeatures.clear();
  3000. mCapabilities.clear();
  3001. static const std::string seed_cap("Seed");
  3002. setCapability(seed_cap, url);
  3003. std::string coro =
  3004. gCoros.launch("LLViewerRegion::requestBaseCapabilitiesCoro",
  3005. boost::bind(&LLViewerRegion::requestBaseCapabilitiesCoro,
  3006. mHandle));
  3007. llinfos << "Coroutine " << coro
  3008. << " launched for capabilities request for region " << getIdentity()
  3009. << " to seed: " << url << llendl;
  3010. }
  3011. std::string add_trailing_slash_to_cap(const std::string& url)
  3012. {
  3013. if (!url.empty() && *url.rbegin() != '/')
  3014. {
  3015. return url + "/";
  3016. }
  3017. return url;
  3018. }
  3019. void LLViewerRegion::setCapability(const std::string& name,
  3020. const std::string& url)
  3021. {
  3022. // Guards against a crash seen when exiting the viewer shortly after a far
  3023. // TP, during the shut down 'mainloop' pumping to exit coroutines: a
  3024. // SimulatorFeatures reply may then arrive and trigger a call to gCoros
  3025. // below, causing a crash due to the use of destroyed mutex. HB
  3026. if (LLApp::isExiting() || gDisconnected)
  3027. {
  3028. return;
  3029. }
  3030. if (name == "EventQueueGet")
  3031. {
  3032. // *HACK: remember the event poll request URL to be able to relaunch it
  3033. // for the TP race workaround. HB
  3034. mCapabilities[name] = url;
  3035. if (mEventPoll)
  3036. {
  3037. delete mEventPoll;
  3038. }
  3039. mEventPoll = new LLEventPoll(mHandle, mHost, url);
  3040. // When restarting an event poll, we already have a sim name... HB
  3041. if (!mName.empty())
  3042. {
  3043. mEventPoll->setRegionName(mName);
  3044. }
  3045. }
  3046. else if (name == "UntrustedSimulatorMessage")
  3047. {
  3048. mHost.setUntrustedSimulatorCap(url);
  3049. }
  3050. else if (name == "SimulatorFeatures")
  3051. {
  3052. mCapabilities[name] = url;
  3053. // Kick off a request for simulator features
  3054. std::string coro_name =
  3055. gCoros.launch("LLViewerRegion::requestSimulatorFeatureCoro",
  3056. boost::bind(&LLViewerRegion::requestSimulatorFeatureCoro,
  3057. url, mHandle));
  3058. llinfos << "Coroutine " << coro_name
  3059. << " launched to request simulator features for region "
  3060. << getIdentity() << " from: " << url << llendl;
  3061. // At this point, we should have a region name for this simulator. HB
  3062. if (mEventPoll && !mName.empty())
  3063. {
  3064. mEventPoll->setRegionName(mName);
  3065. }
  3066. }
  3067. else if (name == "Metadata")
  3068. {
  3069. LL_DEBUGS("Capabilities") << "Got special capability Metadata, content = "
  3070. << url << LL_ENDL;
  3071. }
  3072. // Some cached capabilities need to have a trailing slash. HB
  3073. else if (name == "GetTexture")
  3074. {
  3075. mGetTextureUrl = add_trailing_slash_to_cap(url);
  3076. mCapabilities[name] = mGetTextureUrl;
  3077. }
  3078. else if (name == "GetMesh")
  3079. {
  3080. mGetMeshUrl = add_trailing_slash_to_cap(url);
  3081. mCapabilities[name] = mGetMeshUrl;
  3082. }
  3083. else if (name == "GetMesh2")
  3084. {
  3085. mGetMesh2Url = add_trailing_slash_to_cap(url);
  3086. mCapabilities[name] = mGetMesh2Url;
  3087. }
  3088. else if (name == "ViewerAsset")
  3089. {
  3090. mViewerAssetUrl = add_trailing_slash_to_cap(url);
  3091. mCapabilities[name] = mViewerAssetUrl;
  3092. }
  3093. else if (name == "GetDisplayNames" || name == "GetExperienceInfo")
  3094. {
  3095. mCapabilities[name] = add_trailing_slash_to_cap(url);
  3096. }
  3097. else
  3098. {
  3099. mCapabilities[name] = url;
  3100. }
  3101. if (name == "InterestList")
  3102. {
  3103. setInterestListMode();
  3104. }
  3105. }
  3106. bool LLViewerRegion::setInterestListMode(bool set_default) const
  3107. {
  3108. if (gAgent.getRegion() != this)
  3109. {
  3110. // Not our agent region: do not touch anything...
  3111. return false;
  3112. }
  3113. const std::string& cap_url = getCapability("InterestList");
  3114. if (cap_url.empty())
  3115. {
  3116. // No such capability, nothing to do.
  3117. return false;
  3118. }
  3119. static LLCachedControl<bool> use_360(gSavedSettings, "Use360InterestList");
  3120. LLSD body;
  3121. body["mode"] = LLSD::String(!set_default && use_360 ? "360" : "default");
  3122. return gAgent.requestPostCapability("InterestList", body);
  3123. }
  3124. // NOTE: do make sure to call this method only after the region capabilities
  3125. // have been received !
  3126. const std::string& LLViewerRegion::getTextureUrl() const
  3127. {
  3128. bool no_asset_cap = mViewerAssetUrl.empty();
  3129. if (no_asset_cap && gIsInSecondLife)
  3130. {
  3131. if (mCapabilitiesState == CAPABILITIES_STATE_RECEIVED)
  3132. {
  3133. llwarns_once << "Region '" << getIdentity()
  3134. << "' is missing ViewerAsset capability." << llendl;
  3135. }
  3136. else // This should not happen if the note above is respected
  3137. {
  3138. llwarns_once << "Region '" << getIdentity()
  3139. << "' did not yet send the ViewerAsset capability."
  3140. << llendl;
  3141. llassert(false);
  3142. }
  3143. }
  3144. static LLCachedControl<bool> use_viewerasset(gSavedSettings,
  3145. "UseViewerAssetCap");
  3146. if (use_viewerasset && !no_asset_cap)
  3147. {
  3148. LL_DEBUGS_ONCE("Capabilities") << "Using the ViewerAsset capability for region "
  3149. << getIdentity() << LL_ENDL;
  3150. return mViewerAssetUrl;
  3151. }
  3152. LL_DEBUGS_ONCE("Capabilities") << "Using the GetTexture capability for region "
  3153. << getIdentity() << LL_ENDL;
  3154. return mGetTextureUrl;
  3155. }
  3156. // NOTE: do make sure to call this method only after the region capabilities
  3157. // have been received !
  3158. const std::string& LLViewerRegion::getMeshUrl(bool* is_mesh2) const
  3159. {
  3160. bool no_asset_cap = mViewerAssetUrl.empty();
  3161. if (no_asset_cap && gIsInSecondLife)
  3162. {
  3163. if (mCapabilitiesState == CAPABILITIES_STATE_RECEIVED)
  3164. {
  3165. llwarns_once << "Region '" << getIdentity()
  3166. << "' is missing ViewerAsset capability." << llendl;
  3167. }
  3168. else // This should not happen if the note above is respected
  3169. {
  3170. llwarns_once << "Region '" << getIdentity()
  3171. << "' did not yet send the ViewerAsset capability."
  3172. << llendl;
  3173. llassert(false);
  3174. }
  3175. }
  3176. if (is_mesh2)
  3177. {
  3178. *is_mesh2 = true;
  3179. }
  3180. static LLCachedControl<bool> use_getmesh2(gSavedSettings,
  3181. "UseGetMesh2Cap");
  3182. static LLCachedControl<bool> use_viewerasset(gSavedSettings,
  3183. "UseViewerAssetCap");
  3184. if (use_viewerasset && !no_asset_cap)
  3185. {
  3186. LL_DEBUGS_ONCE("Capabilities") << "Using the ViewerAsset capability for region "
  3187. << getIdentity() << LL_ENDL;
  3188. return mViewerAssetUrl;
  3189. }
  3190. if ((gIsInSecondLife || use_getmesh2) && !mGetMesh2Url.empty())
  3191. {
  3192. LL_DEBUGS_ONCE("Capabilities") << "Using the GetMesh2Url capability for region "
  3193. << getIdentity() << LL_ENDL;
  3194. return mGetMesh2Url;
  3195. }
  3196. if (is_mesh2)
  3197. {
  3198. *is_mesh2 = false;
  3199. }
  3200. LL_DEBUGS_ONCE("Capabilities") << "Using the GetMeshUrl capability for region "
  3201. << getIdentity() << LL_ENDL;
  3202. return mGetMeshUrl;
  3203. }
  3204. bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
  3205. {
  3206. return name == "EventQueueGet" || name == "UntrustedSimulatorMessage" ||
  3207. name == "Metadata" || name == "SimulatorFeatures";
  3208. }
  3209. const std::string& LLViewerRegion::getCapability(const char* name) const
  3210. {
  3211. capability_map_t::const_iterator iter = mCapabilities.find(name);
  3212. if (iter == mCapabilities.end())
  3213. {
  3214. return LLStringUtil::null;
  3215. }
  3216. return iter->second;
  3217. }
  3218. void LLViewerRegion::onCapabilitiesReceived()
  3219. {
  3220. if (getCapability("SimulatorFeatures").empty())
  3221. {
  3222. llinfos << "No SimulatorFeatures capability for region: "
  3223. << getIdentity() << llendl;
  3224. mMeshRezEnabled = !getCapability("GetMesh").empty() ||
  3225. !getCapability("GetMesh2").empty();
  3226. mMeshUploadEnabled = !getCapability("MeshUploadFlag").empty();
  3227. // There is no need holding back the sim features signal callbacks...
  3228. // Just fire and disconnect them.
  3229. mFeaturesReceived = true;
  3230. mFeaturesReceivedSignal(getRegionID());
  3231. mFeaturesReceivedSignal.disconnect_all_slots();
  3232. }
  3233. }
  3234. void LLViewerRegion::setCapabilitiesReceived(bool received)
  3235. {
  3236. mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED
  3237. : CAPABILITIES_STATE_INIT;
  3238. // Tell interested parties that we've received capabilities,
  3239. // so that they can safely use getCapability().
  3240. if (received)
  3241. {
  3242. onCapabilitiesReceived();
  3243. mCapabilitiesReceivedSignal(getRegionID());
  3244. // This is a single-shot signal. Forget callbacks to save resources.
  3245. mCapabilitiesReceivedSignal.disconnect_all_slots();
  3246. }
  3247. }
  3248. boost::signals2::connection LLViewerRegion::setCapsReceivedCB(const caps_received_cb_t& cb)
  3249. {
  3250. return mCapabilitiesReceivedSignal.connect(cb);
  3251. }
  3252. void LLViewerRegion::logActiveCapabilities() const
  3253. {
  3254. U32 count = 0;
  3255. for (capability_map_t::const_iterator iter = mCapabilities.begin(),
  3256. end = mCapabilities.end();
  3257. iter != end; ++iter)
  3258. {
  3259. if (!iter->second.empty())
  3260. {
  3261. llinfos << iter->first << " URL is " << iter->second << llendl;
  3262. ++count;
  3263. }
  3264. }
  3265. llinfos << "Dumped " << count << " entries." << llendl;
  3266. }
  3267. std::string LLViewerRegion::getSimHostName()
  3268. {
  3269. return mHostName.empty() ? mHost.getHostName() : mHostName;
  3270. }
  3271. LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
  3272. {
  3273. if (type < mObjectPartition.size() && type < PARTITION_VO_CACHE)
  3274. {
  3275. return (LLSpatialPartition*)mObjectPartition[type];
  3276. }
  3277. return NULL;
  3278. }
  3279. LLVOCachePartition* LLViewerRegion::getVOCachePartition()
  3280. {
  3281. // No need to check for mObjectPartition.size() against PARTITION_VO_CACHE
  3282. // in release builds since mObjectPartition is always initialized in the
  3283. // constructor of LLViewerRegion and not modified until the destructor is
  3284. // called... HB
  3285. llassert(mObjectPartition.size() > PARTITION_VO_CACHE);
  3286. return (LLVOCachePartition*)mObjectPartition[PARTITION_VO_CACHE];
  3287. }
  3288. // The viewer can not yet distinquish between normal and estate-owned objects
  3289. // so we collapse these two bits and enable the UI if either are set
  3290. constexpr U64 ALLOW_RETURN_ENCROACHING_OBJECT =
  3291. REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT |
  3292. REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
  3293. bool LLViewerRegion::objectIsReturnable(const LLVector3& pos,
  3294. const std::vector<LLBBox>& boxes) const
  3295. {
  3296. return mParcelOverlay &&
  3297. (mParcelOverlay->isOwnedSelf(pos) ||
  3298. mParcelOverlay->isOwnedGroup(pos) ||
  3299. (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT) &&
  3300. mParcelOverlay->encroachesOwned(boxes)));
  3301. }
  3302. bool LLViewerRegion::childrenObjectReturnable(const std::vector<LLBBox>& boxes) const
  3303. {
  3304. return mParcelOverlay && mParcelOverlay->encroachesOnUnowned(boxes);
  3305. }
  3306. void LLViewerRegion::getNeighboringRegions(std::vector<LLViewerRegion*>& regions)
  3307. {
  3308. mLandp->getNeighboringRegions(regions);
  3309. }
  3310. void LLViewerRegion::getNeighboringRegionsStatus(std::vector<S32>& regions)
  3311. {
  3312. mLandp->getNeighboringRegionsStatus(regions);
  3313. }
  3314. void LLViewerRegion::dumpSettings()
  3315. {
  3316. llinfos << "Damage: " << (getAllowDamage() ? "on" : "off")
  3317. << llendl;
  3318. llinfos << "Landmark: " << (getAllowLandmark() ? "on" : "off")
  3319. << llendl;
  3320. llinfos << "SetHome: " << (getAllowSetHome() ? "on" : "off")
  3321. << llendl;
  3322. llinfos << "ResetHome: " << (getResetHomeOnTeleport() ? "on" : "off")
  3323. << llendl;
  3324. llinfos << "SunFixed: " << (getSunFixed() ? "on" : "off") << llendl;
  3325. llinfos << "Clouds updates: " << (mGotClouds ? "yes" : "no") << llendl;
  3326. llinfos << "BlockFly: " << (getBlockFly() ? "on" : "off") << llendl;
  3327. llinfos << "AllowDirectTP: " << (getAllowDirectTeleport() ? "on" : "off")
  3328. << llendl;
  3329. llinfos << "Terraform: " << (getAllowTerraform() ? "on" : "off")
  3330. << llendl;
  3331. llinfos << "RestrictPush: " << (getRestrictPushObject() ? "on" : "off")
  3332. << llendl;
  3333. llinfos << "Voice: " << (isVoiceEnabled() ? "on" : "off")
  3334. << llendl;
  3335. llinfos << "Prelude: " << (isPrelude() ? "on" : "off") << llendl;
  3336. llinfos << "Water: " << getWaterHeight() << "m" << llendl;
  3337. llinfos << "Region size: " << mWidth << "m" << llendl;
  3338. llinfos << "Max primitives: " << mMaxTasks << llendl;
  3339. llinfos << "MeshRezEnabled: " << (mMeshRezEnabled ? "yes" : "no") << llendl;
  3340. llinfos << "MeshRezUpload: " << (mMeshUploadEnabled ? "yes" : "no")
  3341. << llendl;
  3342. llinfos << "PathFinding: " << (mDynamicPathfinding ? "yes" : "no")
  3343. << llendl;
  3344. llinfos << "HoverHeight: " << (mHoverHeigthFeature ? "yes" : "no")
  3345. << llendl;
  3346. llinfos << "OS export perm: " << (isOSExportPermSupported() ? "yes" : "no")
  3347. << llendl;
  3348. llinfos << "WhisperRange: " << mWhisperRange << "m" << llendl;
  3349. llinfos << "ChatRange: " << mChatRange << "m" << llendl;
  3350. llinfos << "ShoutRange: " << mShoutRange << "m" << llendl;
  3351. }