1
0

ScenePresence.cs 263 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Reflection;
  30. using System.Threading;
  31. using OpenMetaverse;
  32. using log4net;
  33. using Nini.Config;
  34. using OpenSim.Framework;
  35. using OpenSim.Framework.Client;
  36. using OpenSim.Region.Framework.Interfaces;
  37. using OpenSim.Region.Framework.Scenes.Animation;
  38. using OpenSim.Region.Framework.Scenes.Types;
  39. using OpenSim.Region.PhysicsModules.SharedBase;
  40. using GridRegion = OpenSim.Services.Interfaces.GridRegion;
  41. using OpenSim.Services.Interfaces;
  42. using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
  43. using ACFlags = OpenMetaverse.AgentManager.ControlFlags;
  44. namespace OpenSim.Region.Framework.Scenes
  45. {
  46. [Flags]
  47. enum ScriptControlled : uint
  48. {
  49. CONTROL_ZERO = 0,
  50. CONTROL_FWD = 1,
  51. CONTROL_BACK = 2,
  52. CONTROL_LEFT = 4,
  53. CONTROL_RIGHT = 8,
  54. CONTROL_UP = 16,
  55. CONTROL_DOWN = 32,
  56. CONTROL_ROT_LEFT = 256,
  57. CONTROL_ROT_RIGHT = 512,
  58. CONTROL_LBUTTON = 268435456,
  59. CONTROL_ML_LBUTTON = 1073741824
  60. }
  61. struct ScriptControllers
  62. {
  63. public UUID objectID;
  64. public UUID itemID;
  65. public ScriptControlled ignoreControls;
  66. public ScriptControlled eventControls;
  67. }
  68. enum AgentUpdateFlags: byte
  69. {
  70. None = 0,
  71. HideTitle = 0x01,
  72. CliAutoPilot = 0x02,
  73. MuteCollisions = 0x80
  74. }
  75. public delegate void SendCoarseLocationsMethod(UUID scene, ScenePresence presence, List<Vector3> coarseLocations, List<UUID> avatarUUIDs);
  76. public class ScenePresence : EntityBase, IScenePresence, IDisposable
  77. {
  78. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  79. //~ScenePresence()
  80. //{
  81. // m_log.DebugFormat("[SCENE PRESENCE]: Destructor called on {0}", Name);
  82. //}
  83. public bool GotAttachmentsData = false;
  84. public int EnvironmentVersion = -1;
  85. private ViewerEnvironment m_environment = null;
  86. public ViewerEnvironment Environment
  87. {
  88. get
  89. {
  90. return m_environment;
  91. }
  92. set
  93. {
  94. m_environment = value;
  95. if (value == null)
  96. EnvironmentVersion = -1;
  97. else
  98. {
  99. if(EnvironmentVersion <= 0)
  100. EnvironmentVersion = 0x7000000 | Random.Shared.Next();
  101. else
  102. ++EnvironmentVersion;
  103. m_environment.version = EnvironmentVersion;
  104. }
  105. }
  106. }
  107. public void TriggerScenePresenceUpdated()
  108. {
  109. m_scene?.EventManager.TriggerScenePresenceUpdated(this);
  110. }
  111. public bool IsNPC { get; private set; }
  112. // simple yes or no isGOD from god level >= 200
  113. // should only be set by GodController
  114. // we have two to suport legacy behaviour
  115. // IsViewerUIGod was controlled by viewer in older versions
  116. // IsGod may now be also controled by viewer acording to options
  117. public bool IsViewerUIGod { get; set; }
  118. public bool IsGod { get; set; }
  119. private bool m_gotRegionHandShake = false;
  120. private PresenceType m_presenceType;
  121. public PresenceType PresenceType
  122. {
  123. get {return m_presenceType;}
  124. private set
  125. {
  126. m_presenceType = value;
  127. IsNPC = (m_presenceType == PresenceType.Npc);
  128. }
  129. }
  130. public bool HideTitle;
  131. public bool MuteCollisions;
  132. private readonly ScenePresenceStateMachine m_stateMachine;
  133. /// <summary>
  134. /// The current state of this presence. Governs only the existence lifecycle. See ScenePresenceStateMachine
  135. /// for more details.
  136. /// </summary>
  137. public ScenePresenceState LifecycleState
  138. {
  139. get
  140. {
  141. return m_stateMachine.GetState();
  142. }
  143. set
  144. {
  145. m_stateMachine.SetState(value);
  146. }
  147. }
  148. /// <summary>
  149. /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and
  150. /// the viewer fires these in quick succession.
  151. /// </summary>
  152. /// <remarks>
  153. /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement
  154. /// regulation done there.
  155. /// </remarks>
  156. private readonly object m_completeMovementLock = new();
  157. /// <summary>
  158. /// Experimentally determined "fudge factor" to make sit-target positions
  159. /// the same as in SecondLife. Fudge factor was tested for 36 different
  160. /// test cases including prims of type box, sphere, cylinder, and torus,
  161. /// with varying parameters for sit target location, prim size, prim
  162. /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
  163. /// issue #1716
  164. /// </summary>
  165. public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new(0.0f, 0.0f, 0.4f);
  166. public readonly bool LegacySitOffsets = true;
  167. /// <summary>
  168. /// Movement updates for agents in neighboring regions are sent directly to clients.
  169. /// This value only affects how often agent positions are sent to neighbor regions
  170. /// for things such as distance-based update prioritization
  171. /// this are the square of real distances
  172. /// </summary>
  173. public const float MOVEMENT = .25f;
  174. public const float SIGNIFICANT_MOVEMENT = 16.0f;
  175. public const float CHILDUPDATES_MOVEMENT = 100.0f;
  176. public const float CHILDAGENTSCHECK_MOVEMENT = 1024f; // 32m
  177. public const float CHILDUPDATES_TIME = 2000f; // min time between child updates (ms)
  178. private UUID m_previusParcelUUID = UUID.Zero;
  179. private UUID m_currentParcelUUID = UUID.Zero;
  180. private bool m_previusParcelHide = false;
  181. private bool m_currentParcelHide = false;
  182. private readonly object parcelLock = new();
  183. public double ParcelDwellTickMS;
  184. public UUID currentParcelUUID
  185. {
  186. get { return m_currentParcelUUID; }
  187. set
  188. {
  189. lock (parcelLock)
  190. {
  191. bool oldhide = m_currentParcelHide;
  192. bool checksame = true;
  193. if (value != m_currentParcelUUID)
  194. {
  195. ParcelDwellTickMS = Util.GetTimeStampMS();
  196. m_previusParcelHide = m_currentParcelHide;
  197. m_previusParcelUUID = m_currentParcelUUID;
  198. checksame = false;
  199. }
  200. m_currentParcelUUID = value;
  201. m_currentParcelHide = false;
  202. ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
  203. if (land != null)
  204. m_currentParcelHide = !land.LandData.SeeAVs;
  205. if (!m_previusParcelUUID.IsZero() || checksame)
  206. ParcelCrossCheck(m_currentParcelUUID, m_previusParcelUUID, m_currentParcelHide, m_previusParcelHide, oldhide,checksame);
  207. }
  208. }
  209. }
  210. public void sitSOGmoved()
  211. {
  212. /*
  213. if (IsDeleted || !IsSatOnObject)
  214. //what me? nahh
  215. return;
  216. if (IsInTransit)
  217. return;
  218. ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
  219. if (land == null)
  220. return; //??
  221. UUID parcelID = land.LandData.GlobalID;
  222. if (m_currentParcelUUID.NotEqual(parcelID))
  223. currentParcelUUID = parcelID;
  224. */
  225. }
  226. public bool ParcelAllowThisAvatarSounds
  227. {
  228. get
  229. {
  230. try
  231. {
  232. lock (parcelLock)
  233. {
  234. ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
  235. if (land == null)
  236. return true;
  237. if (land.LandData.AnyAVSounds)
  238. return true;
  239. if (!land.LandData.GroupAVSounds)
  240. return false;
  241. return ControllingClient.IsGroupMember(land.LandData.GroupID);
  242. }
  243. }
  244. catch
  245. {
  246. return true;
  247. }
  248. }
  249. }
  250. public bool ParcelHideThisAvatar
  251. {
  252. get
  253. {
  254. return m_currentParcelHide;
  255. }
  256. }
  257. /// <value>
  258. /// The animator for this avatar
  259. /// </value>
  260. public ScenePresenceAnimator Animator { get; private set; }
  261. /// <value>
  262. /// Server Side Animation Override
  263. /// </value>
  264. public MovementAnimationOverrides Overrides { get; private set; }
  265. public String sitAnimation = "SIT";
  266. /// <summary>
  267. /// Attachments recorded on this avatar.
  268. /// </summary>
  269. /// <remarks>
  270. /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is
  271. /// necessary.
  272. /// </remarks>
  273. private readonly List<SceneObjectGroup> m_attachments = new();
  274. public Object AttachmentsSyncLock { get; private set; }
  275. private readonly Dictionary<UUID, ScriptControllers> scriptedcontrols = new();
  276. private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO;
  277. private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO;
  278. private bool MouseDown = false;
  279. public Vector3 lastKnownAllowedPosition;
  280. public bool sentMessageAboutRestrictedParcelFlyingDown;
  281. public Vector4 CollisionPlane = Vector4.UnitW;
  282. public Vector4 m_lastCollisionPlane = Vector4.UnitW;
  283. private byte m_lastState;
  284. private Vector3 m_lastPosition;
  285. private Quaternion m_lastRotation;
  286. private Vector3 m_lastVelocity;
  287. private Vector3 m_lastSize = new(0.45f, 0.6f, 1.9f);
  288. private int NeedInitialData = 1;
  289. private int m_userFlags;
  290. public int UserFlags
  291. {
  292. get { return m_userFlags; }
  293. }
  294. // Flying
  295. public bool Flying
  296. {
  297. get { return PhysicsActor != null && PhysicsActor.Flying; }
  298. set
  299. {
  300. if(PhysicsActor != null)
  301. PhysicsActor.Flying = value;
  302. }
  303. }
  304. public bool IsColliding
  305. {
  306. get { return PhysicsActor != null && PhysicsActor.IsColliding; }
  307. // We would expect setting IsColliding to be private but it's used by a hack in Scene
  308. set { PhysicsActor.IsColliding = value; }
  309. }
  310. private List<uint> m_lastColliders = new();
  311. private bool m_lastLandCollide;
  312. private TeleportFlags m_teleportFlags;
  313. public TeleportFlags TeleportFlags
  314. {
  315. get { return m_teleportFlags; }
  316. set { m_teleportFlags = value; }
  317. }
  318. private uint m_requestedSitTargetID;
  319. /// <summary>
  320. /// Are we sitting on the ground?
  321. /// </summary>
  322. public bool SitGround { get; private set; }
  323. private SendCoarseLocationsMethod m_sendCoarseLocationsMethod;
  324. //private Vector3 m_requestedSitOffset = new Vector3();
  325. private Vector3 m_LastFinitePos;
  326. private float m_sitAvatarHeight = 2.0f;
  327. private bool m_childUpdatesBusy = false;
  328. private int m_lastChildUpdatesTime;
  329. private int m_lastChildAgentUpdateGodLevel;
  330. private float m_lastChildAgentUpdateDrawDistance;
  331. private float m_lastRegionsDrawDistance;
  332. private Vector3 m_lastChildAgentUpdatePosition;
  333. private Vector3 m_lastChildAgentCheckPosition;
  334. // private Vector3 m_lastChildAgentUpdateCamPosition;
  335. private Vector3 m_lastCameraRayCastCam;
  336. private Vector3 m_lastCameraRayCastPos;
  337. private float m_FOV = 1.04f;
  338. private const float FLY_ROLL_MAX_RADIANS = 1.1f;
  339. private const float FLY_ROLL_RADIANS_PER_UPDATE = 0.06f;
  340. private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f;
  341. private float m_health = 100f;
  342. private float m_healRate = 1f;
  343. private float m_healRatePerFrame = 0.05f;
  344. private static readonly Vector3[] Dir_Vectors = new Vector3[6] {
  345. new Vector3(1.0f, 0, 0), //FORWARD
  346. new Vector3(-1.0f,0,0), //BACK
  347. new Vector3(0, 1.0f,0), //LEFT
  348. new Vector3(0,-1.0f,0), //RIGHT
  349. new Vector3(0,0, 1.0f), //UP
  350. new Vector3(0,0,-1.0f) //DOWN
  351. };
  352. private enum Dir_ControlFlags : uint
  353. {
  354. DIR_CONTROL_FLAG_FORWARD = ACFlags.AGENT_CONTROL_AT_POS,
  355. DIR_CONTROL_FLAG_BACK = ACFlags.AGENT_CONTROL_AT_NEG,
  356. DIR_CONTROL_FLAG_LEFT = ACFlags.AGENT_CONTROL_LEFT_POS,
  357. DIR_CONTROL_FLAG_RIGHT = ACFlags.AGENT_CONTROL_LEFT_NEG,
  358. DIR_CONTROL_FLAG_UP = ACFlags.AGENT_CONTROL_UP_POS,
  359. DIR_CONTROL_FLAG_DOWN = ACFlags.AGENT_CONTROL_UP_NEG,
  360. DIR_CONTROL_FLAG_FORWARD_NUDGE = ACFlags.AGENT_CONTROL_NUDGE_AT_POS,
  361. DIR_CONTROL_FLAG_BACKWARD_NUDGE = ACFlags.AGENT_CONTROL_NUDGE_AT_NEG,
  362. DIR_CONTROL_FLAG_LEFT_NUDGE = ACFlags.AGENT_CONTROL_NUDGE_LEFT_POS,
  363. DIR_CONTROL_FLAG_RIGHT_NUDGE = ACFlags.AGENT_CONTROL_NUDGE_LEFT_NEG,
  364. DIR_CONTROL_FLAG_UP_NUDGE = ACFlags.AGENT_CONTROL_NUDGE_UP_POS,
  365. DIR_CONTROL_FLAG_DOWN_NUDGE = ACFlags.AGENT_CONTROL_NUDGE_UP_NEG
  366. }
  367. const uint CONTROL_FLAG_NORM_MASK = (uint)(ACFlags.AGENT_CONTROL_AT_POS |
  368. ACFlags.AGENT_CONTROL_AT_NEG |
  369. ACFlags.AGENT_CONTROL_LEFT_POS |
  370. ACFlags.AGENT_CONTROL_LEFT_NEG |
  371. ACFlags.AGENT_CONTROL_UP_POS |
  372. ACFlags.AGENT_CONTROL_UP_NEG);
  373. const uint CONTROL_FLAG_NUDGE_MASK = (uint)(ACFlags.AGENT_CONTROL_NUDGE_AT_POS |
  374. ACFlags.AGENT_CONTROL_NUDGE_AT_NEG |
  375. ACFlags.AGENT_CONTROL_NUDGE_LEFT_POS |
  376. ACFlags.AGENT_CONTROL_NUDGE_LEFT_NEG |
  377. ACFlags.AGENT_CONTROL_NUDGE_UP_POS |
  378. ACFlags.AGENT_CONTROL_NUDGE_UP_NEG);
  379. protected int m_reprioritizationLastTime;
  380. protected bool m_reprioritizationBusy;
  381. protected Vector3 m_reprioritizationLastPosition;
  382. protected float m_reprioritizationLastDrawDistance;
  383. private Quaternion m_headrotation = Quaternion.Identity;
  384. //PauPaw:Proper PID Controler for autopilot************
  385. private bool m_movingToTarget;
  386. public bool MovingToTarget
  387. {
  388. get {return m_movingToTarget;}
  389. private set {m_movingToTarget = value; }
  390. }
  391. private Vector3 m_moveToPositionTarget;
  392. public Vector3 MoveToPositionTarget
  393. {
  394. get {return m_moveToPositionTarget;}
  395. private set {m_moveToPositionTarget = value; }
  396. }
  397. private float m_moveToSpeed;
  398. public float MoveToSpeed
  399. {
  400. get {return m_moveToSpeed;}
  401. private set {m_moveToSpeed = value; }
  402. }
  403. private double m_delayedStop = -1.0;
  404. /// <summary>
  405. /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying).
  406. /// </summary>
  407. public bool LandAtTarget { get; private set; }
  408. private bool CameraConstraintActive;
  409. private readonly object m_collisionEventLock = new();
  410. private int m_movementAnimationUpdateCounter = 0;
  411. public Vector3 PrevSitOffset { get; set; }
  412. protected AvatarAppearance m_appearance;
  413. public AvatarAppearance Appearance
  414. {
  415. get { return m_appearance; }
  416. set
  417. {
  418. m_appearance = value;
  419. // m_log.DebugFormat("[SCENE PRESENCE]: Set appearance for {0} to {1}", Name, value);
  420. }
  421. }
  422. /// <summary>
  423. /// Copy of the script states while the agent is in transit. This state may
  424. /// need to be placed back in case of transfer fail.
  425. /// </summary>
  426. public List<string> InTransitScriptStates
  427. {
  428. get { return m_InTransitScriptStates; }
  429. private set { m_InTransitScriptStates = value; }
  430. }
  431. private List<string> m_InTransitScriptStates = new();
  432. /// <summary>
  433. /// Position at which a significant movement was made
  434. /// </summary>
  435. private Vector3 posLastSignificantMove;
  436. private Vector3 posLastMove;
  437. #region For teleports and crossings callbacks
  438. /// <summary>
  439. /// the destination simulator sends ReleaseAgent to this address, for very long range tps, HG.
  440. /// </summary>
  441. private string m_callbackURI; // to remove with v1 support
  442. private string m_newCallbackURI;
  443. /// <summary>
  444. /// Records the region from which this presence originated, if not from login.
  445. /// </summary>
  446. /// <remarks>
  447. /// Also acts as a signal in the teleport V2 process to release UpdateAgent after a viewer has triggered
  448. /// CompleteMovement and made the previous child agent a root agent.
  449. /// </remarks>
  450. private UUID m_originRegionID;
  451. /// <summary>
  452. /// This object is used as a lock before accessing m_originRegionID to make sure that every thread is seeing
  453. /// the very latest value and not using some cached version. Cannot make m_originRegionID itself volatite as
  454. /// it is a value type.
  455. /// </summary>
  456. private readonly object m_originRegionIDAccessLock = new();
  457. private AutoResetEvent m_updateAgentReceivedAfterTransferEvent = new(false);
  458. /// <summary>
  459. /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
  460. /// teleport is reusing the connection.
  461. /// </summary>
  462. /// <remarks>May be refactored or move somewhere else soon.</remarks>
  463. public bool DoNotCloseAfterTeleport { get; set; }
  464. #endregion
  465. /// <value>
  466. /// Script engines present in the scene
  467. /// </value>
  468. private IScriptModule[] m_scriptEngines;
  469. private enum LandingPointBehavior
  470. {
  471. OS = 1,
  472. SL = 2
  473. }
  474. private readonly LandingPointBehavior m_LandingPointBehavior = LandingPointBehavior.OS;
  475. #region Properties
  476. /// <summary>
  477. /// Physical scene representation of this Avatar.
  478. /// </summary>
  479. PhysicsActor m_physActor;
  480. public PhysicsActor PhysicsActor
  481. {
  482. get
  483. {
  484. return m_physActor;
  485. }
  486. private set
  487. {
  488. m_physActor = value;
  489. }
  490. }
  491. /// <summary>
  492. /// Record user movement inputs.
  493. /// </summary>
  494. public uint MovementFlags { get; private set; }
  495. /// <summary>
  496. /// Is the agent stop control flag currently active?
  497. /// </summary>
  498. public bool AgentControlStopActive { get; private set; }
  499. private bool m_invulnerable = true;
  500. public bool Invulnerable
  501. {
  502. set
  503. {
  504. m_invulnerable = value;
  505. if(value && Health != 100.0f)
  506. Health = 100.0f;
  507. }
  508. get { return m_invulnerable; }
  509. }
  510. public GodController GodController { get; private set; }
  511. private ulong m_rootRegionHandle;
  512. private Vector3 m_rootRegionPosition = new();
  513. public ulong RegionHandle
  514. {
  515. get { return m_rootRegionHandle; }
  516. private set
  517. {
  518. m_rootRegionHandle = value;
  519. // position rounded to lower multiple of 256m
  520. m_rootRegionPosition.X = (float)((m_rootRegionHandle >> 32) & 0xffffff00);
  521. m_rootRegionPosition.Y = (float)(m_rootRegionHandle & 0xffffff00);
  522. }
  523. }
  524. #region Client Camera
  525. /// <summary>
  526. /// Position of agent's camera in world (region cordinates)
  527. /// </summary>
  528. // protected Vector3 m_lastCameraPosition;
  529. private Vector4 m_lastCameraCollisionPlane = new(0f, 0f, 0f, 1);
  530. private bool m_doingCamRayCast = false;
  531. public Vector3 CameraPosition { get; set; }
  532. public Quaternion CameraRotation { get; private set; }
  533. // Use these three vectors to figure out what the agent is looking at
  534. // Convert it to a Matrix and/or Quaternion
  535. //
  536. public Vector3 CameraAtAxis { get; set; }
  537. public Vector3 CameraLeftAxis { get; set; }
  538. public Vector3 CameraUpAxis { get; set; }
  539. public Vector3 Lookat
  540. {
  541. get
  542. {
  543. Vector3 a = new(CameraAtAxis.X, CameraAtAxis.Y, 0);
  544. a.Normalize();
  545. return a;
  546. }
  547. }
  548. #endregion
  549. public string Firstname { get; private set; }
  550. public string Lastname { get; private set; }
  551. public bool m_haveGroupInformation;
  552. public bool m_gotCrossUpdate;
  553. public byte m_crossingFlags;
  554. public string Grouptitle
  555. {
  556. get { return m_groupTitle; }
  557. set { m_groupTitle = value; }
  558. }
  559. private string m_groupTitle;
  560. // Agent's Draw distance.
  561. private float m_drawDistance = 255f;
  562. public float DrawDistance
  563. {
  564. get
  565. {
  566. return m_drawDistance;
  567. }
  568. set
  569. {
  570. m_drawDistance = Utils.Clamp(value, 32f, m_scene.MaxDrawDistance);
  571. }
  572. }
  573. public float RegionViewDistance
  574. {
  575. get
  576. {
  577. return Utils.Clamp(m_drawDistance + 64f, m_scene.MinRegionViewDistance, m_scene.MaxRegionViewDistance);
  578. }
  579. }
  580. public bool AllowMovement { get; set; }
  581. private bool m_setAlwaysRun;
  582. public bool SetAlwaysRun
  583. {
  584. get
  585. {
  586. if (PhysicsActor != null)
  587. {
  588. return PhysicsActor.SetAlwaysRun;
  589. }
  590. else
  591. {
  592. return m_setAlwaysRun;
  593. }
  594. }
  595. set
  596. {
  597. m_setAlwaysRun = value;
  598. if (PhysicsActor != null)
  599. {
  600. PhysicsActor.SetAlwaysRun = value;
  601. }
  602. }
  603. }
  604. public byte State { get; set; }
  605. private ACFlags m_AgentControlFlags;
  606. public uint AgentControlFlags
  607. {
  608. get { return (uint)m_AgentControlFlags; }
  609. set { m_AgentControlFlags = (ACFlags)value; }
  610. }
  611. public IClientAPI ControllingClient { get; set; }
  612. // dead end do not use
  613. public IClientCore ClientView
  614. {
  615. get { return (IClientCore)ControllingClient; }
  616. }
  617. //public UUID COF { get; set; }
  618. // public Vector3 ParentPosition { get; set; }
  619. /// <summary>
  620. /// Position of this avatar relative to the region the avatar is in
  621. /// </summary>
  622. public override Vector3 AbsolutePosition
  623. {
  624. get
  625. {
  626. if (PhysicsActor != null)
  627. {
  628. m_pos = PhysicsActor.Position;
  629. // m_log.DebugFormat(
  630. // "[SCENE PRESENCE]: Set position of {0} in {1} to {2} via getting AbsolutePosition!",
  631. // Name, Scene.Name, m_pos);
  632. }
  633. else
  634. {
  635. // m_log.DebugFormat("[SCENE PRESENCE]: Fetching abs pos where PhysicsActor == null and parent part {0} for {1}", Name, Scene.Name);
  636. // Obtain the correct position of a seated avatar.
  637. // In addition to providing the correct position while
  638. // the avatar is seated, this value will also
  639. // be used as the location to unsit to.
  640. //
  641. // If ParentID is not 0, assume we are a seated avatar
  642. // and we should return the position based on the sittarget
  643. // offset and rotation of the prim we are seated on.
  644. //
  645. // Generally, m_pos will contain the position of the avatar
  646. // in the sim unless the avatar is on a sit target. While
  647. // on a sit target, m_pos will contain the desired offset
  648. // without the parent rotation applied.
  649. if (ParentPart != null)
  650. {
  651. SceneObjectPart rootPart = ParentPart.ParentGroup.RootPart;
  652. // if (sitPart != null)
  653. // return sitPart.AbsolutePosition + (m_pos * sitPart.GetWorldRotation());
  654. if (rootPart != null)
  655. return rootPart.AbsolutePosition + (m_pos * rootPart.GetWorldRotation());
  656. }
  657. }
  658. return m_pos;
  659. }
  660. set
  661. {
  662. // m_log.DebugFormat("[SCENE PRESENCE]: Setting position of {0} to {1} in {2}", Name, value, Scene.Name);
  663. // Util.PrintCallStack();
  664. if (PhysicsActor != null)
  665. {
  666. try
  667. {
  668. PhysicsActor.Position = value;
  669. }
  670. catch (Exception e)
  671. {
  672. m_log.Error("[SCENE PRESENCE]: ABSOLUTE POSITION " + e.Message);
  673. }
  674. }
  675. // Don't update while sitting. The PhysicsActor above is null whilst sitting.
  676. if (ParentID == 0)
  677. m_pos = value;
  678. //m_log.DebugFormat(
  679. // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
  680. // Scene.RegionInfo.RegionName, Name, m_pos);
  681. TriggerScenePresenceUpdated();
  682. }
  683. }
  684. /// <summary>
  685. /// If sitting, returns the offset position from the prim the avatar is sitting on.
  686. /// Otherwise, returns absolute position in the scene.
  687. /// </summary>
  688. public Vector3 OffsetPosition
  689. {
  690. get { return m_pos; }
  691. // Don't remove setter. It's not currently used in core but
  692. // upcoming Avination code needs it.
  693. set
  694. {
  695. // There is no offset position when not seated
  696. if (ParentID == 0)
  697. return;
  698. m_pos = value;
  699. TriggerScenePresenceUpdated();
  700. }
  701. }
  702. /// <summary>
  703. /// Current velocity of the avatar.
  704. /// </summary>
  705. public override Vector3 Velocity
  706. {
  707. get
  708. {
  709. if (PhysicsActor != null)
  710. {
  711. m_velocity = PhysicsActor.Velocity;
  712. // m_log.DebugFormat(
  713. // "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
  714. // m_velocity, Name, Scene.RegionInfo.RegionName);
  715. }
  716. return m_velocity;
  717. }
  718. set
  719. {
  720. if (PhysicsActor != null)
  721. {
  722. try
  723. {
  724. PhysicsActor.TargetVelocity = value;
  725. }
  726. catch (Exception e)
  727. {
  728. m_log.Error("[SCENE PRESENCE]: VELOCITY " + e.Message);
  729. }
  730. }
  731. m_velocity = value;
  732. // m_log.DebugFormat(
  733. // "[SCENE PRESENCE]: In {0} set velocity of {1} to {2}",
  734. // Scene.RegionInfo.RegionName, Name, m_velocity);
  735. }
  736. }
  737. // requested Velocity for physics engines avatar motors
  738. // only makes sense if there is a physical rep
  739. public Vector3 TargetVelocity
  740. {
  741. get
  742. {
  743. if (PhysicsActor != null)
  744. return PhysicsActor.TargetVelocity;
  745. else
  746. return Vector3.Zero;
  747. }
  748. set
  749. {
  750. if (PhysicsActor != null)
  751. {
  752. try
  753. {
  754. PhysicsActor.TargetVelocity = value;
  755. }
  756. catch (Exception e)
  757. {
  758. m_log.Error("[SCENE PRESENCE]: TARGETVELOCITY " + e.Message);
  759. }
  760. }
  761. }
  762. }
  763. private Quaternion m_bodyRot = Quaternion.Identity;
  764. /// <summary>
  765. /// The rotation of the avatar.
  766. /// </summary>
  767. /// <remarks>
  768. /// If the avatar is not sitting, this is with respect to the world
  769. /// If the avatar is sitting, this is a with respect to the part that it's sitting upon (a local rotation).
  770. /// If you always want the world rotation, use GetWorldRotation()
  771. /// </remarks>
  772. public Quaternion Rotation
  773. {
  774. get
  775. {
  776. return m_bodyRot;
  777. }
  778. set
  779. {
  780. m_bodyRot = value;
  781. if (PhysicsActor != null)
  782. {
  783. try
  784. {
  785. PhysicsActor.Orientation = m_bodyRot;
  786. }
  787. catch (Exception e)
  788. {
  789. m_log.Error("[SCENE PRESENCE]: Orientation " + e.Message);
  790. }
  791. }
  792. // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot);
  793. }
  794. }
  795. // Used for limited viewer 'fake' user rotations.
  796. private Vector3 m_AngularVelocity = Vector3.Zero;
  797. public Vector3 AngularVelocity
  798. {
  799. get { return m_AngularVelocity; }
  800. }
  801. public bool IsChildAgent { get; set; }
  802. /// <summary>
  803. /// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
  804. /// </summary>
  805. public uint ParentID { get; set; }
  806. public UUID ParentUUID
  807. {
  808. get { return m_parentUUID; }
  809. set { m_parentUUID = value; }
  810. }
  811. private UUID m_parentUUID = UUID.Zero;
  812. /// <summary>
  813. /// Are we sitting on an object?
  814. /// </summary>
  815. /// <remarks>A more readable way of testing presence sit status than ParentID == 0</remarks>
  816. public bool IsSatOnObject { get { return ParentID != 0; } }
  817. public bool IsSitting { get {return SitGround || IsSatOnObject; }}
  818. /// <summary>
  819. /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null.
  820. /// </summary>
  821. /// <remarks>
  822. /// If you use this property then you must take a reference since another thread could set it to null.
  823. /// </remarks>
  824. public SceneObjectPart ParentPart { get; set; }
  825. public float Health
  826. {
  827. get { return m_health; }
  828. set { m_health = value; }
  829. }
  830. public float HealRate
  831. {
  832. get { return m_healRate; }
  833. set
  834. {
  835. if(value > 100.0f)
  836. m_healRate = 100.0f;
  837. else if (value <= 0.0)
  838. m_healRate = 0.0f;
  839. else
  840. m_healRate = value;
  841. if(Scene != null)
  842. m_healRatePerFrame = m_healRate * Scene.FrameTime;
  843. else
  844. m_healRatePerFrame = 0.05f;
  845. }
  846. }
  847. /// <summary>
  848. /// Gets the world rotation of this presence.
  849. /// </summary>
  850. /// <remarks>
  851. /// Unlike Rotation, this returns the world rotation no matter whether the avatar is sitting on a prim or not.
  852. /// </remarks>
  853. /// <returns></returns>
  854. public Quaternion GetWorldRotation()
  855. {
  856. if (IsSatOnObject)
  857. {
  858. SceneObjectPart sitPart = ParentPart;
  859. if (sitPart != null)
  860. return sitPart.GetWorldRotation() * Rotation;
  861. }
  862. return Rotation;
  863. }
  864. /// <summary>
  865. /// Get velocity relative to the world.
  866. /// </summary>
  867. public Vector3 GetWorldVelocity()
  868. {
  869. SceneObjectPart sitPart = ParentPart;
  870. if (sitPart != null)
  871. return sitPart.ParentGroup.Velocity;
  872. return Velocity;
  873. }
  874. public void AdjustKnownSeeds()
  875. {
  876. Dictionary<ulong, string> seeds;
  877. if (Scene.CapsModule != null)
  878. seeds = Scene.CapsModule.GetChildrenSeeds(UUID);
  879. else
  880. seeds = new Dictionary<ulong, string>();
  881. KnownRegions = seeds;
  882. }
  883. public void DumpKnownRegions()
  884. {
  885. m_log.Info("================ KnownRegions "+Scene.RegionInfo.RegionName+" ================");
  886. foreach (KeyValuePair<ulong, string> kvp in KnownRegions)
  887. {
  888. Util.RegionHandleToRegionLoc(kvp.Key, out uint x, out uint y);
  889. m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
  890. }
  891. }
  892. private bool m_mouseLook;
  893. private bool m_leftButtonDown;
  894. private bool m_inTransit;
  895. /// <summary>
  896. /// This signals whether the presence is in transit between neighbouring regions.
  897. /// </summary>
  898. /// <remarks>
  899. /// It is not set when the presence is teleporting or logging in/out directly to a region.
  900. /// </remarks>
  901. public bool IsInTransit
  902. {
  903. get { return m_inTransit; }
  904. set {
  905. if(value)
  906. {
  907. if (Flying)
  908. m_AgentControlFlags |= ACFlags.AGENT_CONTROL_FLY;
  909. else
  910. m_AgentControlFlags &= ~ACFlags.AGENT_CONTROL_FLY;
  911. }
  912. m_inTransit = value;
  913. }
  914. }
  915. // this is is only valid if IsInTransit is true
  916. // only false on HG tps
  917. // used work arounf viewers asking source region about destination user
  918. public bool IsInLocalTransit {get; set; }
  919. // velocities
  920. private const float AgentControlStopSlowVel = 0.2f * 4.096f;
  921. public const float AgentControlMidVel = 0.6f * 4.096f;
  922. public const float AgentControlNormalVel = 1.0f * 4.096f;
  923. // old normal speed was tuned to match sl normal plus Fast modifiers
  924. // so we need to rescale it
  925. private float m_speedModifier = 1.0f;
  926. public float SpeedModifier
  927. {
  928. get { return m_speedModifier; }
  929. set { m_speedModifier = value; }
  930. }
  931. private bool m_forceFly;
  932. public bool ForceFly
  933. {
  934. get { return m_forceFly; }
  935. set { m_forceFly = value; }
  936. }
  937. private bool m_flyDisabled;
  938. public bool FlyDisabled
  939. {
  940. get { return m_flyDisabled; }
  941. set { m_flyDisabled = value; }
  942. }
  943. public string Viewer
  944. {
  945. get { return Util.GetViewerName(m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode)); }
  946. }
  947. #endregion
  948. #region Constructor(s)
  949. public ScenePresence(IClientAPI client, Scene world, AvatarAppearance appearance, PresenceType type)
  950. {
  951. m_scene = world;
  952. AttachmentsSyncLock = new Object();
  953. AllowMovement = true;
  954. IsChildAgent = true;
  955. m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
  956. Animator = new ScenePresenceAnimator(this);
  957. Overrides = new MovementAnimationOverrides();
  958. PresenceType = type;
  959. m_drawDistance = client.StartFar;
  960. if(m_drawDistance > 32)
  961. {
  962. if(m_drawDistance > world.MaxDrawDistance)
  963. m_drawDistance = world.MaxDrawDistance;
  964. }
  965. else
  966. m_drawDistance = world.DefaultDrawDistance;
  967. RegionHandle = world.RegionInfo.RegionHandle;
  968. ControllingClient = client;
  969. Firstname = ControllingClient.FirstName;
  970. Lastname = ControllingClient.LastName;
  971. Name = String.Format("{0} {1}", Firstname, Lastname);
  972. m_uuid = client.AgentId;
  973. LocalId = m_scene.AllocateLocalId();
  974. LegacySitOffsets = m_scene.LegacySitOffsets;
  975. IsInLocalTransit = true;
  976. UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
  977. if (account is not null)
  978. {
  979. m_userFlags = account.UserFlags;
  980. GodController = new GodController(world, this, account.UserLevel);
  981. }
  982. else
  983. {
  984. m_userFlags = 0;
  985. GodController = new GodController(world, this, 0);
  986. }
  987. //IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
  988. //if (gm != null)
  989. // Grouptitle = gm.GetGroupTitle(m_uuid);
  990. m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>();
  991. AbsolutePosition = posLastMove = posLastSignificantMove = CameraPosition =
  992. m_reprioritizationLastPosition = ControllingClient.StartPos;
  993. m_reprioritizationLastDrawDistance = -1000;
  994. // disable updates workjobs for now
  995. m_childUpdatesBusy = true;
  996. m_reprioritizationBusy = true;
  997. AdjustKnownSeeds();
  998. RegisterToClientEvents();
  999. Appearance = appearance;
  1000. m_stateMachine = new ScenePresenceStateMachine(this);
  1001. HealRate = 0.5f;
  1002. IConfig sconfig = m_scene.Config.Configs["EntityTransfer"];
  1003. if (sconfig != null)
  1004. {
  1005. string lpb = sconfig.GetString("LandingPointBehavior", "LandingPointBehavior_OS");
  1006. if (lpb == "LandingPointBehavior_SL")
  1007. m_LandingPointBehavior = LandingPointBehavior.SL;
  1008. }
  1009. ControllingClient.RefreshGroupMembership();
  1010. }
  1011. ~ScenePresence()
  1012. {
  1013. Dispose(false);
  1014. }
  1015. private bool disposed = false;
  1016. public void Dispose()
  1017. {
  1018. Dispose(true);
  1019. GC.SuppressFinalize(this);
  1020. }
  1021. protected void Dispose(bool disposing)
  1022. {
  1023. // Check to see if Dispose has already been called.
  1024. if (!disposed)
  1025. {
  1026. disposed = true;
  1027. IsDeleted = true;
  1028. if (m_updateAgentReceivedAfterTransferEvent != null)
  1029. {
  1030. m_updateAgentReceivedAfterTransferEvent.Dispose();
  1031. m_updateAgentReceivedAfterTransferEvent = null;
  1032. }
  1033. RemoveFromPhysicalScene();
  1034. // Clear known regions
  1035. KnownRegions = null;
  1036. m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
  1037. RemoveClientEvents();
  1038. Animator = null;
  1039. Appearance = null;
  1040. /* temporary out: timming issues
  1041. if(m_attachments != null)
  1042. {
  1043. foreach(SceneObjectGroup sog in m_attachments)
  1044. sog.Dispose();
  1045. m_attachments = null;
  1046. }
  1047. */
  1048. scriptedcontrols.Clear();
  1049. // gc gets confused with this cycling
  1050. ControllingClient = null;
  1051. GodController = null; // gc gets confused with this cycling
  1052. }
  1053. }
  1054. private float lastHealthSent = 0;
  1055. private void RegionHeartbeatEnd(Scene scene)
  1056. {
  1057. if (IsChildAgent)
  1058. return;
  1059. m_movementAnimationUpdateCounter ++;
  1060. if (m_movementAnimationUpdateCounter >= 2)
  1061. {
  1062. m_movementAnimationUpdateCounter = 0;
  1063. if (Animator != null)
  1064. {
  1065. // If the parentID == 0 we are not sitting
  1066. // if !SitGournd then we are not sitting on the ground
  1067. // Fairly straightforward, now here comes the twist
  1068. // if ParentUUID is NOT UUID.Zero, we are looking to
  1069. // be sat on an object that isn't there yet. Should
  1070. // be treated as if sat.
  1071. if(ParentID == 0 && !SitGround && ParentUUID.IsZero()) // skip it if sitting
  1072. Animator.UpdateMovementAnimations();
  1073. }
  1074. else
  1075. {
  1076. // m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
  1077. }
  1078. }
  1079. if(m_healRatePerFrame != 0f && Health != 100.0f)
  1080. {
  1081. Health += m_healRatePerFrame;
  1082. if(Health > 100.0f)
  1083. {
  1084. Health = 100.0f;
  1085. lastHealthSent = Health;
  1086. ControllingClient.SendHealth(Health);
  1087. }
  1088. else if(Math.Abs(Health - lastHealthSent) > 1.0)
  1089. {
  1090. lastHealthSent = Health;
  1091. ControllingClient.SendHealth(Health);
  1092. }
  1093. }
  1094. }
  1095. public void RegisterToClientEvents()
  1096. {
  1097. ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
  1098. ControllingClient.OnAgentUpdate += HandleAgentUpdate;
  1099. ControllingClient.OnAgentCameraUpdate += HandleAgentCamerasUpdate;
  1100. ControllingClient.OnAgentRequestSit += HandleAgentRequestSit;
  1101. ControllingClient.OnAgentSit += HandleAgentSit;
  1102. ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun;
  1103. ControllingClient.OnStartAnim += HandleStartAnim;
  1104. ControllingClient.OnStopAnim += HandleStopAnim;
  1105. ControllingClient.OnChangeAnim += avnHandleChangeAnim;
  1106. ControllingClient.OnForceReleaseControls += HandleForceReleaseControls;
  1107. ControllingClient.OnAutoPilotGo += MoveToTargetHandle;
  1108. ControllingClient.OnRegionHandShakeReply += RegionHandShakeReply;
  1109. // ControllingClient.OnAgentFOV += HandleAgentFOV;
  1110. // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
  1111. // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
  1112. }
  1113. public void RemoveClientEvents()
  1114. {
  1115. ControllingClient.OnCompleteMovementToRegion -= CompleteMovement;
  1116. ControllingClient.OnAgentUpdate -= HandleAgentUpdate;
  1117. ControllingClient.OnAgentCameraUpdate -= HandleAgentCamerasUpdate;
  1118. ControllingClient.OnAgentRequestSit -= HandleAgentRequestSit;
  1119. ControllingClient.OnAgentSit -= HandleAgentSit;
  1120. ControllingClient.OnSetAlwaysRun -= HandleSetAlwaysRun;
  1121. ControllingClient.OnStartAnim -= HandleStartAnim;
  1122. ControllingClient.OnStopAnim -= HandleStopAnim;
  1123. ControllingClient.OnChangeAnim -= avnHandleChangeAnim;
  1124. ControllingClient.OnForceReleaseControls -= HandleForceReleaseControls;
  1125. ControllingClient.OnAutoPilotGo -= MoveToTargetHandle;
  1126. ControllingClient.OnRegionHandShakeReply -= RegionHandShakeReply;
  1127. // ControllingClient.OnAgentFOV += HandleAgentFOV;
  1128. }
  1129. #endregion
  1130. #region Status Methods
  1131. /// <summary>
  1132. /// Turns a child agent into a root agent.
  1133. /// </summary>
  1134. /// <remarks>
  1135. /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the
  1136. /// avatar is actual in the sim. They can perform all actions.
  1137. /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim,
  1138. /// teleporting in or on initial login.
  1139. ///
  1140. /// This method is on the critical path for transferring an avatar from one region to another. Delay here
  1141. /// delays that crossing.
  1142. /// </remarks>
  1143. // constants for physics position search
  1144. const float PhysSearchHeight = 300f;
  1145. const float PhysMinSkipGap = 20f;
  1146. const float PhysSkipGapDelta = 30f;
  1147. const int PhysNumberCollisions = 30;
  1148. // only in use as part of completemovement
  1149. // other uses need fix
  1150. private bool MakeRootAgent(Vector3 pos, bool isFlying, ref Vector3 lookat)
  1151. {
  1152. //int ts = Util.EnvironmentTickCount();
  1153. lock (m_completeMovementLock)
  1154. {
  1155. if (!IsChildAgent)
  1156. return false;
  1157. //m_log.DebugFormat("[MakeRootAgent] enter lock: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  1158. //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
  1159. // m_log.InfoFormat(
  1160. // "[SCENE]: Upgrading child to root agent for {0} in {1}",
  1161. // Name, m_scene.RegionInfo.RegionName);
  1162. if (!ParentUUID.IsZero())
  1163. {
  1164. m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
  1165. SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
  1166. if (part == null)
  1167. {
  1168. m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
  1169. ParentID = 0;
  1170. ParentPart = null;
  1171. PrevSitOffset = Vector3.Zero;
  1172. HandleForceReleaseControls(ControllingClient, UUID); // needs testing
  1173. }
  1174. else
  1175. {
  1176. part.AddSittingAvatar(this);
  1177. // if not actually on the target invalidate it
  1178. if(m_gotCrossUpdate && (m_crossingFlags & 0x04) == 0)
  1179. part.SitTargetAvatar = UUID.Zero;
  1180. ParentID = part.LocalId;
  1181. ParentPart = part;
  1182. m_pos = PrevSitOffset;
  1183. pos = part.GetWorldPosition();
  1184. PhysicsActor partPhysActor = part.PhysActor;
  1185. if(partPhysActor != null)
  1186. {
  1187. partPhysActor.OnPhysicsRequestingCameraData -= physActor_OnPhysicsRequestingCameraData;
  1188. partPhysActor.OnPhysicsRequestingCameraData += physActor_OnPhysicsRequestingCameraData;
  1189. }
  1190. }
  1191. ParentUUID = UUID.Zero;
  1192. }
  1193. IsChildAgent = false;
  1194. }
  1195. //m_log.DebugFormat("[MakeRootAgent] out lock: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  1196. // Must reset this here so that a teleport to a region next to an existing region does not keep the flag
  1197. // set and prevent the close of the connection on a subsequent re-teleport.
  1198. // Should not be needed if we are not trying to tell this region to close
  1199. // DoNotCloseAfterTeleport = false;
  1200. RegionHandle = m_scene.RegionInfo.RegionHandle;
  1201. m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
  1202. //m_log.DebugFormat("[MakeRootAgent] TriggerSetRootAgentScene: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  1203. if (ParentID == 0)
  1204. {
  1205. bool positionChanged = false;
  1206. bool success = true;
  1207. if (m_LandingPointBehavior == LandingPointBehavior.OS)
  1208. success = CheckAndAdjustLandingPoint_OS(ref pos, ref lookat, ref positionChanged);
  1209. else
  1210. success = CheckAndAdjustLandingPoint_SL(ref pos, ref lookat, ref positionChanged);
  1211. if (!success)
  1212. m_log.DebugFormat("[SCENE PRESENCE MakeRootAgent]: houston we have a problem.. {0} ({1} got banned)", Name, UUID);
  1213. if (pos.X < 0f || pos.Y < 0f
  1214. || pos.X >= m_scene.RegionInfo.RegionSizeX
  1215. || pos.Y >= m_scene.RegionInfo.RegionSizeY)
  1216. {
  1217. m_log.WarnFormat(
  1218. "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
  1219. pos, Name, UUID);
  1220. if (pos.X < 0f)
  1221. pos.X = 0.5f;
  1222. else if(pos.X >= m_scene.RegionInfo.RegionSizeX)
  1223. pos.X = m_scene.RegionInfo.RegionSizeX - 0.5f;
  1224. if (pos.Y < 0f)
  1225. pos.Y = 0.5f;
  1226. else if(pos.Y >= m_scene.RegionInfo.RegionSizeY)
  1227. pos.Y = m_scene.RegionInfo.RegionSizeY - 0.5f;
  1228. }
  1229. float groundHeight = m_scene.GetGroundHeight(pos.X, pos.Y) + .01f;
  1230. float physTestHeight;
  1231. if(PhysSearchHeight < groundHeight + 100f)
  1232. physTestHeight = groundHeight + 100f;
  1233. else
  1234. physTestHeight = PhysSearchHeight;
  1235. float localAVHalfHeight = 0.8f;
  1236. if (Appearance != null && Appearance.AvatarHeight > 0)
  1237. localAVHalfHeight = 0.5f * Appearance.AvatarHeight;
  1238. groundHeight += localAVHalfHeight;
  1239. if (groundHeight > pos.Z)
  1240. pos.Z = groundHeight;
  1241. bool checkPhysics = !positionChanged &&
  1242. m_scene.SupportsRayCastFiltered() &&
  1243. pos.Z < physTestHeight &&
  1244. ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
  1245. (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)
  1246. || (m_teleportFlags & TeleportFlags.ViaLocation) != 0
  1247. || (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0);
  1248. if(checkPhysics)
  1249. {
  1250. // land check was done above
  1251. RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
  1252. rayfilter |= RayFilterFlags.PrimsNonPhantomAgents;
  1253. int physcount = PhysNumberCollisions;
  1254. float dist = physTestHeight - groundHeight + localAVHalfHeight;
  1255. Vector3 direction = new(0f, 0f, -1f);
  1256. Vector3 RayStart = pos;
  1257. RayStart.Z = physTestHeight;
  1258. List<ContactResult> physresults =
  1259. (List<ContactResult>)m_scene.RayCastFiltered(RayStart, direction, dist, physcount, rayfilter);
  1260. while (physresults != null && physresults.Count > 0)
  1261. {
  1262. float dest = physresults[0].Pos.Z;
  1263. if (dest - groundHeight > PhysMinSkipGap + PhysSkipGapDelta)
  1264. break;
  1265. if (physresults.Count > 1)
  1266. {
  1267. physresults.Sort(delegate(ContactResult a, ContactResult b)
  1268. {
  1269. return a.Depth.CompareTo(b.Depth);
  1270. });
  1271. int sel = 0;
  1272. int count = physresults.Count;
  1273. float curd = physresults[0].Depth;
  1274. float nextd = curd + PhysMinSkipGap;
  1275. float maxDepth = dist - pos.Z;
  1276. for(int i = 1; i < count; i++)
  1277. {
  1278. curd = physresults[i].Depth;
  1279. if(curd >= nextd)
  1280. {
  1281. sel = i;
  1282. if(curd >= maxDepth || curd >= nextd + PhysSkipGapDelta)
  1283. break;
  1284. }
  1285. nextd = curd + PhysMinSkipGap;
  1286. }
  1287. dest = physresults[sel].Pos.Z;
  1288. }
  1289. dest += localAVHalfHeight;
  1290. if(dest > pos.Z)
  1291. pos.Z = dest;
  1292. break;
  1293. }
  1294. }
  1295. AbsolutePosition = pos;
  1296. // m_log.DebugFormat(
  1297. // "Set pos {0}, vel {1} in {1} to {2} from input position of {3} on MakeRootAgent",
  1298. // Name, Scene.Name, AbsolutePosition, pos);
  1299. //
  1300. if (m_teleportFlags == TeleportFlags.Default)
  1301. {
  1302. Vector3 vel = Velocity;
  1303. AddToPhysicalScene(isFlying);
  1304. PhysicsActor?.SetMomentum(vel);
  1305. }
  1306. else
  1307. {
  1308. AddToPhysicalScene(isFlying);
  1309. // reset camera to avatar pos
  1310. CameraPosition = pos;
  1311. }
  1312. if (ForceFly)
  1313. {
  1314. Flying = true;
  1315. }
  1316. else if (FlyDisabled)
  1317. {
  1318. Flying = false;
  1319. }
  1320. }
  1321. //m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  1322. m_scene.SwapRootAgentCount(false, IsNPC);
  1323. // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will
  1324. // stall on the border crossing since the existing child agent will still have the last movement
  1325. // recorded, which stops the input from being processed.
  1326. MovementFlags = 0;
  1327. m_scene.AuthenticateHandler.UpdateAgentChildStatus(ControllingClient.CircuitCode, false);
  1328. m_scene.EventManager.TriggerOnMakeRootAgent(this);
  1329. //m_log.DebugFormat("[MakeRootAgent] TriggerOnMakeRootAgent and done: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  1330. return true;
  1331. }
  1332. private void RestartAttachmentScripts()
  1333. {
  1334. // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
  1335. // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
  1336. // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
  1337. // not transporting the required data.
  1338. //
  1339. // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
  1340. // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
  1341. // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
  1342. //
  1343. // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
  1344. // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
  1345. // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
  1346. // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
  1347. List<SceneObjectGroup> attachments = GetAttachments();
  1348. m_log.DebugFormat(
  1349. "[SCENE PRESENCE]: Restarting scripts in {0} attachments for {1} in {2}", attachments.Count, Name, Scene.Name);
  1350. // Resume scripts
  1351. foreach (SceneObjectGroup sog in attachments)
  1352. {
  1353. sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
  1354. sog.ResumeScripts();
  1355. sog.ScheduleGroupForFullUpdate();
  1356. }
  1357. }
  1358. private static bool IsRealLogin(TeleportFlags teleportFlags)
  1359. {
  1360. return (teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaHGLogin)) == TeleportFlags.ViaLogin;
  1361. }
  1362. /// <summary>
  1363. /// Force viewers to show the avatar's current name.
  1364. /// </summary>
  1365. /// <remarks>
  1366. /// The avatar name that is shown above the avatar in the viewers is sent in ObjectUpdate packets,
  1367. /// and they get the name from the ScenePresence. Unfortunately, viewers have a bug (as of April 2014)
  1368. /// where they ignore changes to the avatar name. However, tey don't ignore changes to the avatar's
  1369. /// Group Title. So the following trick makes viewers update the avatar's name by briefly changing
  1370. /// the group title (to "(Loading)"), and then restoring it.
  1371. /// </remarks>
  1372. /*
  1373. public void ForceViewersUpdateName()
  1374. {
  1375. m_log.DebugFormat("[SCENE PRESENCE]: Forcing viewers to update the avatar name for " + Name);
  1376. UseFakeGroupTitle = true;
  1377. Util.FireAndForget(o =>
  1378. {
  1379. // Viewers only update the avatar name when idle. Therefore, we must wait long
  1380. // enough for the viewer to show the fake name that we had set above, and only
  1381. // then switch back to the true name. This delay was chosen because it has a high
  1382. // chance of succeeding (we don't want to choose a value that's too low).
  1383. Thread.Sleep(5000);
  1384. UseFakeGroupTitle = false;
  1385. SendAvatarDataToAllClients(false);
  1386. }, null, "Scenepresence.ForceViewersUpdateName");
  1387. }
  1388. */
  1389. public int GetStateSource()
  1390. {
  1391. return m_teleportFlags == TeleportFlags.Default ? 2 : 5; // StateSource.PrimCrossing : StateSource.Teleporting
  1392. }
  1393. /// <summary>
  1394. /// This turns a root agent into a child agent
  1395. /// </summary>
  1396. /// <remarks>
  1397. /// when an agent departs this region for a neighbor, this gets called.
  1398. ///
  1399. /// It doesn't get called for a teleport. Reason being, an agent that
  1400. /// teleports out may not end up anywhere near this region
  1401. /// </remarks>
  1402. public void MakeChildAgent(ulong newRegionHandle)
  1403. {
  1404. m_updateAgentReceivedAfterTransferEvent.Reset();
  1405. m_haveGroupInformation = false;
  1406. m_gotCrossUpdate = false;
  1407. m_crossingFlags = 0;
  1408. m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
  1409. RegionHandle = newRegionHandle;
  1410. m_log.DebugFormat("[SCENE PRESENCE]: Making {0} a child agent in {1} from root region {2}",
  1411. Name, Scene.RegionInfo.RegionName, newRegionHandle);
  1412. // Reset the m_originRegionID as it has dual use as a flag to signal that the UpdateAgent() call orignating
  1413. // from the source simulator has completed on a V2 teleport.
  1414. lock (m_originRegionIDAccessLock)
  1415. m_originRegionID = UUID.Zero;
  1416. // Reset these so that teleporting in and walking out isn't seen
  1417. // as teleporting back
  1418. TeleportFlags = TeleportFlags.Default;
  1419. MovementFlags = 0;
  1420. // It looks like Animator is set to null somewhere, and MakeChild
  1421. // is called after that. Probably in aborted teleports.
  1422. if (Animator == null)
  1423. Animator = new ScenePresenceAnimator(this);
  1424. else
  1425. Animator.ResetAnimations();
  1426. Environment = null;
  1427. // m_log.DebugFormat(
  1428. // "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}",
  1429. // Name, UUID, m_scene.RegionInfo.RegionName);
  1430. // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing,
  1431. // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated.
  1432. //Velocity = new Vector3(0, 0, 0);
  1433. IsChildAgent = true;
  1434. m_scene.SwapRootAgentCount(true, IsNPC);
  1435. RemoveFromPhysicalScene();
  1436. ParentID = 0; // Child agents can't be sitting
  1437. // we dont have land information for child
  1438. m_previusParcelHide = false;
  1439. m_previusParcelUUID = UUID.Zero;
  1440. m_currentParcelHide = false;
  1441. m_currentParcelUUID = UUID.Zero;
  1442. CollisionPlane = Vector4.UnitW;
  1443. // we need to kill this on agents that do not see the new region
  1444. m_scene.ForEachRootScenePresence(delegate(ScenePresence p)
  1445. {
  1446. if (!p.knowsNeighbourRegion(newRegionHandle))
  1447. {
  1448. SendKillTo(p);
  1449. }
  1450. });
  1451. m_scene.AuthenticateHandler.UpdateAgentChildStatus(ControllingClient.CircuitCode, true);
  1452. m_scene.EventManager.TriggerOnMakeChildAgent(this);
  1453. }
  1454. /// <summary>
  1455. /// Removes physics plugin scene representation of this agent if it exists.
  1456. /// </summary>
  1457. public void RemoveFromPhysicalScene()
  1458. {
  1459. PhysicsActor pa = Interlocked.Exchange(ref m_physActor, null);
  1460. if (pa != null)
  1461. {
  1462. //PhysicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients;
  1463. pa.OnOutOfBounds -= OutOfBoundsCall;
  1464. pa.OnCollisionUpdate -= PhysicsCollisionUpdate;
  1465. pa.UnSubscribeEvents();
  1466. m_scene.PhysicsScene.RemoveAvatar(pa);
  1467. }
  1468. }
  1469. public void Teleport(Vector3 pos)
  1470. {
  1471. TeleportWithMomentum(pos, Vector3.Zero);
  1472. }
  1473. public void TeleportWithMomentum(Vector3 pos, Vector3? v)
  1474. {
  1475. if(!CheckLocalTPLandingPoint(ref pos))
  1476. return;
  1477. if (IsSitting)
  1478. StandUp(false);
  1479. bool isFlying = Flying;
  1480. Vector3 vel = Velocity;
  1481. RemoveFromPhysicalScene();
  1482. AbsolutePosition = pos;
  1483. AddToPhysicalScene(isFlying);
  1484. PhysicsActor?.SetMomentum(v ?? vel);
  1485. SendTerseUpdateToAllClients();
  1486. }
  1487. public void TeleportOnEject(Vector3 pos)
  1488. {
  1489. if (IsSitting )
  1490. StandUp(false);
  1491. bool isFlying = Flying;
  1492. RemoveFromPhysicalScene();
  1493. AbsolutePosition = pos;
  1494. AddToPhysicalScene(isFlying);
  1495. SendTerseUpdateToAllClients();
  1496. }
  1497. public void LocalTeleport(Vector3 newpos, Vector3 newvel, Vector3 newlookat, int flags)
  1498. {
  1499. if (newpos.X <= 0)
  1500. {
  1501. newpos.X = 0.1f;
  1502. if (newvel.X < 0)
  1503. newvel.X = 0;
  1504. }
  1505. else if (newpos.X >= Scene.RegionInfo.RegionSizeX)
  1506. {
  1507. newpos.X = Scene.RegionInfo.RegionSizeX - 0.1f;
  1508. if (newvel.X > 0)
  1509. newvel.X = 0;
  1510. }
  1511. if (newpos.Y <= 0)
  1512. {
  1513. newpos.Y = 0.1f;
  1514. if (newvel.Y < 0)
  1515. newvel.Y = 0;
  1516. }
  1517. else if (newpos.Y >= Scene.RegionInfo.RegionSizeY)
  1518. {
  1519. newpos.Y = Scene.RegionInfo.RegionSizeY - 0.1f;
  1520. if (newvel.Y > 0)
  1521. newvel.Y = 0;
  1522. }
  1523. if (!m_scene.TestLandRestrictions(UUID, out string _, ref newpos.X, ref newpos.Y))
  1524. return ;
  1525. if (IsSitting)
  1526. StandUp();
  1527. if(m_movingToTarget)
  1528. ResetMoveToTarget();
  1529. float localHalfAVHeight = Appearance is null ? 0.8f : Appearance.AvatarHeight * 0.5f;
  1530. float posZLimit = Scene.GetGroundHeight(newpos.X, newpos.Y);
  1531. posZLimit += localHalfAVHeight + 0.1f;
  1532. if (newpos.Z < posZLimit)
  1533. newpos.Z = posZLimit;
  1534. if((flags & 0x1e) != 0)
  1535. {
  1536. if ((flags & 8) != 0)
  1537. Flying = true;
  1538. else if ((flags & 16) != 0)
  1539. Flying = false;
  1540. uint tpflags = (uint)TeleportFlags.ViaLocation;
  1541. if(Flying)
  1542. tpflags |= (uint)TeleportFlags.IsFlying;
  1543. Vector3 lookat = Lookat;
  1544. if ((flags & 2) != 0)
  1545. {
  1546. newlookat.Z = 0;
  1547. newlookat.Normalize();
  1548. if (MathF.Abs(newlookat.X) > 0.001f || MathF.Abs(newlookat.Y) > 0.001f)
  1549. lookat = newlookat;
  1550. }
  1551. else if((flags & 4) != 0)
  1552. {
  1553. if((flags & 1) != 0)
  1554. newlookat = newvel;
  1555. else
  1556. newlookat = m_velocity;
  1557. newlookat.Z = 0;
  1558. newlookat.Normalize();
  1559. if (MathF.Abs(newlookat.X) > 0.001f || MathF.Abs(newlookat.Y) > 0.001f)
  1560. lookat = newlookat;
  1561. }
  1562. AbsolutePosition = newpos;
  1563. ControllingClient.SendLocalTeleport(newpos, lookat, tpflags);
  1564. }
  1565. else
  1566. AbsolutePosition = newpos;
  1567. if ((flags & 1) != 0)
  1568. {
  1569. PhysicsActor?.SetMomentum(newvel);
  1570. m_velocity = newvel;
  1571. }
  1572. SendTerseUpdateToAllClients();
  1573. }
  1574. public void StopFlying()
  1575. {
  1576. if (IsInTransit)
  1577. return;
  1578. Vector3 pos = AbsolutePosition;
  1579. if (Appearance.AvatarHeight != 127.0f)
  1580. pos += new Vector3(0f, 0f, (Appearance.AvatarHeight / 6f));
  1581. else
  1582. pos += new Vector3(0f, 0f, (1.56f / 6f));
  1583. AbsolutePosition = pos;
  1584. // attach a suitable collision plane regardless of the actual situation to force the LLClient to land.
  1585. // Collision plane below the avatar's position a 6th of the avatar's height is suitable.
  1586. // Mind you, that this method doesn't get called if the avatar's velocity magnitude is greater then a
  1587. // certain amount.. because the LLClient wouldn't land in that situation anyway.
  1588. // why are we still testing for this really old height value default???
  1589. if (Appearance.AvatarHeight != 127.0f)
  1590. CollisionPlane = new Vector4(0, 0, 0, pos.Z - Appearance.AvatarHeight / 6f);
  1591. else
  1592. CollisionPlane = new Vector4(0, 0, 0, pos.Z - (1.56f / 6f));
  1593. SendAgentTerseUpdate(this);
  1594. }
  1595. /// <summary>
  1596. /// Applies a roll accumulator to the avatar's angular velocity for the avatar fly roll effect.
  1597. /// </summary>
  1598. /// <param name="amount">Postive or negative roll amount in radians</param>
  1599. private void ApplyFlyingRoll(float amount, bool PressingUp, bool PressingDown)
  1600. {
  1601. float rollAmount = Utils.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS);
  1602. m_AngularVelocity.Z = rollAmount;
  1603. // APPLY EXTRA consideration for flying up and flying down during this time.
  1604. // if we're turning left
  1605. if (amount > 0)
  1606. {
  1607. // If we're at the max roll and pressing up, we want to swing BACK a bit
  1608. // Automatically adds noise
  1609. if (PressingUp)
  1610. {
  1611. if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS - 0.04f)
  1612. m_AngularVelocity.Z -= 0.9f;
  1613. }
  1614. // If we're at the max roll and pressing down, we want to swing MORE a bit
  1615. if (PressingDown)
  1616. {
  1617. if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS && m_AngularVelocity.Z < FLY_ROLL_MAX_RADIANS + 0.6f)
  1618. m_AngularVelocity.Z += 0.6f;
  1619. }
  1620. }
  1621. else // we're turning right.
  1622. {
  1623. // If we're at the max roll and pressing up, we want to swing BACK a bit
  1624. // Automatically adds noise
  1625. if (PressingUp)
  1626. {
  1627. if (m_AngularVelocity.Z <= (-FLY_ROLL_MAX_RADIANS))
  1628. m_AngularVelocity.Z += 0.6f;
  1629. }
  1630. // If we're at the max roll and pressing down, we want to swing MORE a bit
  1631. if (PressingDown)
  1632. {
  1633. if (m_AngularVelocity.Z >= -FLY_ROLL_MAX_RADIANS - 0.6f)
  1634. m_AngularVelocity.Z -= 0.6f;
  1635. }
  1636. }
  1637. }
  1638. /// <summary>
  1639. /// incrementally sets roll amount to zero
  1640. /// </summary>
  1641. /// <param name="amount">Positive roll amount in radians</param>
  1642. /// <returns></returns>
  1643. private float CalculateFlyingRollResetToZero(float amount)
  1644. {
  1645. const float rollMinRadians = 0f;
  1646. if (m_AngularVelocity.Z > 0)
  1647. {
  1648. float leftOverToMin = m_AngularVelocity.Z - rollMinRadians;
  1649. if (amount > leftOverToMin)
  1650. return -leftOverToMin;
  1651. else
  1652. return -amount;
  1653. }
  1654. else
  1655. {
  1656. float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians;
  1657. if (amount > leftOverToMin)
  1658. return leftOverToMin;
  1659. else
  1660. return amount;
  1661. }
  1662. }
  1663. // neighbouring regions we have enabled a child agent in
  1664. // holds the seed cap for the child agent in that region
  1665. private Dictionary<ulong, string> m_knownChildRegions = new();
  1666. struct spRegionSizeInfo
  1667. {
  1668. public int sizeX;
  1669. public int sizeY;
  1670. public spRegionSizeInfo(int x, int y)
  1671. {
  1672. sizeX = x;
  1673. sizeY = y;
  1674. }
  1675. }
  1676. private readonly Dictionary<ulong, spRegionSizeInfo> m_knownChildRegionsSizeInfo = new();
  1677. public void AddNeighbourRegion(GridRegion region, string capsPath)
  1678. {
  1679. lock (m_knownChildRegions)
  1680. {
  1681. ulong regionHandle = region.RegionHandle;
  1682. m_knownChildRegions[regionHandle] = capsPath;
  1683. m_knownChildRegionsSizeInfo[regionHandle] = new spRegionSizeInfo(region.RegionSizeX, region.RegionSizeY);
  1684. }
  1685. }
  1686. public void AddNeighbourRegionSizeInfo(GridRegion region)
  1687. {
  1688. lock (m_knownChildRegions)
  1689. {
  1690. m_knownChildRegionsSizeInfo[region.RegionHandle] = new spRegionSizeInfo(region.RegionSizeX, region.RegionSizeY);
  1691. }
  1692. }
  1693. public void SetNeighbourRegionSizeInfo(List<GridRegion> regionsList)
  1694. {
  1695. lock (m_knownChildRegions)
  1696. {
  1697. m_knownChildRegionsSizeInfo.Clear();
  1698. foreach (GridRegion region in regionsList)
  1699. {
  1700. m_knownChildRegionsSizeInfo[region.RegionHandle] = new spRegionSizeInfo(region.RegionSizeX, region.RegionSizeY);
  1701. }
  1702. }
  1703. }
  1704. public void RemoveNeighbourRegion(ulong regionHandle)
  1705. {
  1706. lock (m_knownChildRegions)
  1707. {
  1708. // Checking ContainsKey is redundant as Remove works either way and returns a bool
  1709. // This is here to allow the Debug output to be conditional on removal
  1710. //if (m_knownChildRegions.ContainsKey(regionHandle))
  1711. // m_log.DebugFormat(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count);
  1712. m_knownChildRegions.Remove(regionHandle);
  1713. m_knownChildRegionsSizeInfo.Remove(regionHandle);
  1714. }
  1715. }
  1716. public bool knowsNeighbourRegion(ulong regionHandle)
  1717. {
  1718. lock (m_knownChildRegions)
  1719. return m_knownChildRegions.ContainsKey(regionHandle);
  1720. }
  1721. public void DropOldNeighbours(List<ulong> oldRegions)
  1722. {
  1723. foreach (ulong handle in oldRegions)
  1724. {
  1725. RemoveNeighbourRegion(handle);
  1726. Scene.CapsModule.DropChildSeed(UUID, handle);
  1727. }
  1728. }
  1729. public void DropThisRootRegionFromNeighbours()
  1730. {
  1731. ulong handle = m_scene.RegionInfo.RegionHandle;
  1732. RemoveNeighbourRegion(handle);
  1733. Scene.CapsModule.DropChildSeed(UUID, handle);
  1734. }
  1735. public Dictionary<ulong, string> KnownRegions
  1736. {
  1737. get
  1738. {
  1739. lock (m_knownChildRegions)
  1740. return new Dictionary<ulong, string>(m_knownChildRegions);
  1741. }
  1742. set
  1743. {
  1744. // Replacing the reference is atomic but we still need to lock on
  1745. // the original dictionary object which may be in use elsewhere
  1746. lock (m_knownChildRegions)
  1747. m_knownChildRegions = value;
  1748. }
  1749. }
  1750. public List<ulong> KnownRegionHandles
  1751. {
  1752. get
  1753. {
  1754. lock (m_knownChildRegions)
  1755. return new List<ulong>(m_knownChildRegions.Keys);
  1756. }
  1757. }
  1758. public int KnownRegionCount
  1759. {
  1760. get
  1761. {
  1762. lock (m_knownChildRegions)
  1763. return m_knownChildRegions.Count;
  1764. }
  1765. }
  1766. #endregion
  1767. #region Event Handlers
  1768. /// <summary>
  1769. /// Sets avatar height in the physics plugin
  1770. /// </summary>
  1771. /// <param name="height">New height of avatar</param>
  1772. public void SetHeight(float height)
  1773. {
  1774. if (PhysicsActor != null && !IsChildAgent)
  1775. PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
  1776. }
  1777. public void SetSize(Vector3 size, float feetoffset)
  1778. {
  1779. if (PhysicsActor != null && !IsChildAgent)
  1780. PhysicsActor.setAvatarSize(size, feetoffset);
  1781. }
  1782. private bool WaitForUpdateAgent(IClientAPI client)
  1783. {
  1784. // Before the source region executes UpdateAgent
  1785. // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination,
  1786. // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the
  1787. // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero
  1788. try
  1789. {
  1790. if(m_updateAgentReceivedAfterTransferEvent.WaitOne(10000))
  1791. {
  1792. UUID originID = UUID.Zero;
  1793. lock (m_originRegionIDAccessLock)
  1794. originID = m_originRegionID;
  1795. if (originID.Equals(UUID.Zero))
  1796. {
  1797. // Movement into region will fail
  1798. m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} at {1} got invalid origin region id ", client.Name, Scene.Name);
  1799. return false;
  1800. }
  1801. return true;
  1802. }
  1803. else
  1804. {
  1805. m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} at {1} did not receive agent update ", client.Name, Scene.Name);
  1806. return false;
  1807. }
  1808. }
  1809. catch { }
  1810. finally
  1811. {
  1812. m_updateAgentReceivedAfterTransferEvent?.Reset();
  1813. }
  1814. return false;
  1815. }
  1816. public void RotateToLookAt(Vector3 lookAt)
  1817. {
  1818. if(ParentID == 0)
  1819. {
  1820. float n = lookAt.X * lookAt.X + lookAt.Y * lookAt.Y;
  1821. if(n < 0.0001f)
  1822. {
  1823. Rotation = Quaternion.Identity;
  1824. return;
  1825. }
  1826. n = lookAt.X/MathF.Sqrt(n);
  1827. float angle = MathF.Acos(n);
  1828. angle *= 0.5f;
  1829. float s = lookAt.Y >= 0 ? MathF.Sin(angle) : -MathF.Sin(angle);
  1830. Rotation = new Quaternion(0f, 0f, s, MathF.Cos(angle));
  1831. }
  1832. }
  1833. /// <summary>
  1834. /// Complete Avatar's movement into the region.
  1835. /// </summary>
  1836. /// <param name="client"></param>
  1837. /// <param name="openChildAgents">
  1838. /// If true, send notification to neighbour regions to expect
  1839. /// a child agent from the client. These neighbours can be some distance away, depending right now on the
  1840. /// configuration of DefaultDrawDistance in the [Startup] section of config
  1841. /// </param>
  1842. public void CompleteMovement(IClientAPI client, bool openChildAgents)
  1843. {
  1844. int ts = Util.EnvironmentTickCount();
  1845. m_log.InfoFormat(
  1846. "[SCENE PRESENCE]: Complete movement of {0} into {1} {2}",
  1847. client.Name, Scene.Name, AbsolutePosition);
  1848. m_inTransit = true;
  1849. try
  1850. {
  1851. // Make sure it's not a login agent. We don't want to wait for updates during login
  1852. if (!IsNPC && !IsRealLogin(m_teleportFlags))
  1853. {
  1854. // Let's wait until UpdateAgent (called by departing region) is done
  1855. if (!WaitForUpdateAgent(client))
  1856. // The sending region never sent the UpdateAgent data, we have to refuse
  1857. return;
  1858. }
  1859. //m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  1860. bool flying = ((m_AgentControlFlags & ACFlags.AGENT_CONTROL_FLY) != 0);
  1861. Vector3 look = Lookat;
  1862. look.Z = 0f;
  1863. look.Normalize();
  1864. if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01))
  1865. {
  1866. look = Velocity;
  1867. look.Z = 0f;
  1868. look.Normalize();
  1869. if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01) )
  1870. look = new Vector3(0.99f, 0.042f, 0);
  1871. }
  1872. // Check Default Location (Also See EntityTransferModule.TeleportAgentWithinRegion)
  1873. if (AbsolutePosition.X == 128f && AbsolutePosition.Y == 128f && AbsolutePosition.Z == 22.5f)
  1874. AbsolutePosition = Scene.RegionInfo.DefaultLandingPoint;
  1875. if (!MakeRootAgent(AbsolutePosition, flying, ref look))
  1876. {
  1877. m_log.DebugFormat(
  1878. "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root",
  1879. Name, Scene.Name);
  1880. return;
  1881. }
  1882. if(IsChildAgent)
  1883. {
  1884. return; // how?
  1885. }
  1886. //m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  1887. if (!IsNPC)
  1888. {
  1889. if (!m_haveGroupInformation)
  1890. {
  1891. IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
  1892. if (gm != null)
  1893. Grouptitle = gm.GetGroupTitle(m_uuid);
  1894. //m_log.DebugFormat("[CompleteMovement] Missing Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  1895. /*
  1896. InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (FolderType)46);
  1897. if (cof == null)
  1898. COF = UUID.Zero;
  1899. else
  1900. COF = cof.ID;
  1901. m_log.DebugFormat("[CompleteMovement]: Missing COF for {0} is {1}", client.AgentId, COF);
  1902. */
  1903. }
  1904. }
  1905. if (m_teleportFlags > 0)
  1906. m_gotCrossUpdate = false; // sanity check
  1907. if (!m_gotCrossUpdate)
  1908. RotateToLookAt(look);
  1909. m_previusParcelHide = false;
  1910. m_previusParcelUUID = UUID.Zero;
  1911. m_currentParcelHide = false;
  1912. m_currentParcelUUID = UUID.Zero;
  1913. ParcelDwellTickMS = Util.GetTimeStampMS();
  1914. m_inTransit = false;
  1915. ILandChannel landch = m_scene.LandChannel;
  1916. if (landch != null)
  1917. {
  1918. ILandObject landover = m_scene.LandChannel.GetLandObject(AbsolutePosition.X, AbsolutePosition.Y);
  1919. if (landover != null)
  1920. {
  1921. m_currentParcelHide = !landover.LandData.SeeAVs;
  1922. m_currentParcelUUID = landover.LandData.GlobalID;
  1923. }
  1924. }
  1925. // Tell the client that we're ready to send rest
  1926. if (!m_gotCrossUpdate)
  1927. {
  1928. m_gotRegionHandShake = false; // allow it if not a crossing
  1929. ControllingClient.SendRegionHandshake();
  1930. }
  1931. ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
  1932. bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0;
  1933. if(!IsNPC)
  1934. {
  1935. if( ParentPart != null && (m_crossingFlags & 0x08) != 0)
  1936. {
  1937. ParentPart.ParentGroup.SendFullAnimUpdateToClient(ControllingClient);
  1938. }
  1939. // verify baked textures and cache
  1940. if (m_scene.AvatarFactory != null && !isHGTP)
  1941. {
  1942. if (!m_scene.AvatarFactory.ValidateBakedTextureCache(this))
  1943. m_scene.AvatarFactory.QueueAppearanceSave(UUID);
  1944. }
  1945. }
  1946. if(isHGTP)
  1947. {
  1948. // ControllingClient.SendNameReply(m_uuid, Firstname, Lastname);
  1949. m_log.DebugFormat("[CompleteMovement] HG");
  1950. }
  1951. if (!IsNPC)
  1952. {
  1953. GodController.SyncViewerState();
  1954. // start sending terrain patchs
  1955. if (!m_gotCrossUpdate)
  1956. Scene.SendLayerData(ControllingClient);
  1957. // send initial land overlay and parcel
  1958. landch?.sendClientInitialLandInfo(client, !m_gotCrossUpdate);
  1959. }
  1960. List<ScenePresence> allpresences = m_scene.GetScenePresences();
  1961. // send avatar object to all presences including us, so they cross it into region
  1962. // then hide if necessary
  1963. SendInitialAvatarDataToAllAgents(allpresences);
  1964. // send this look
  1965. if (!IsNPC)
  1966. SendAppearanceToAgent(this);
  1967. // send this animations
  1968. UUID[] animIDs = null;
  1969. int[] animseqs = null;
  1970. UUID[] animsobjs = null;
  1971. Animator?.GetArrays(out animIDs, out animseqs, out animsobjs);
  1972. bool haveAnims = (animIDs != null && animseqs != null && animsobjs != null);
  1973. if (!IsNPC && haveAnims)
  1974. SendAnimPackToAgent(this, animIDs, animseqs, animsobjs);
  1975. // send look and animations to others
  1976. // if not cached we send greys
  1977. // uncomented if will wait till avatar does baking
  1978. //if (cachedbaked)
  1979. {
  1980. foreach (ScenePresence p in allpresences)
  1981. {
  1982. if (p == this)
  1983. continue;
  1984. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  1985. continue;
  1986. SendAppearanceToAgentNF(p);
  1987. if (haveAnims)
  1988. SendAnimPackToAgentNF(p, animIDs, animseqs, animsobjs);
  1989. }
  1990. }
  1991. // attachments
  1992. if (IsNPC || IsRealLogin(m_teleportFlags))
  1993. {
  1994. if (Scene.AttachmentsModule != null)
  1995. {
  1996. if(IsNPC)
  1997. {
  1998. Util.FireAndForget(x =>
  1999. {
  2000. Scene.AttachmentsModule.RezAttachments(this);
  2001. });
  2002. }
  2003. else
  2004. Scene.AttachmentsModule.RezAttachments(this);
  2005. }
  2006. }
  2007. else
  2008. {
  2009. if (m_attachments.Count > 0)
  2010. {
  2011. foreach (SceneObjectGroup sog in m_attachments)
  2012. {
  2013. sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
  2014. sog.ResumeScripts();
  2015. }
  2016. foreach (ScenePresence p in allpresences)
  2017. {
  2018. if (p == this)
  2019. {
  2020. SendAttachmentsToAgentNF(this);
  2021. continue;
  2022. }
  2023. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  2024. continue;
  2025. SendAttachmentsToAgentNF(p);
  2026. }
  2027. }
  2028. }
  2029. if (!IsNPC)
  2030. {
  2031. if(m_gotCrossUpdate)
  2032. {
  2033. SendOtherAgentsAvatarFullToMe();
  2034. // Create child agents in neighbouring regions
  2035. IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
  2036. m_agentTransfer?.EnableChildAgents(this);
  2037. m_lastChildUpdatesTime = Util.EnvironmentTickCount() + 10000;
  2038. m_lastChildAgentUpdatePosition = AbsolutePosition;
  2039. m_lastChildAgentCheckPosition = m_lastChildAgentUpdatePosition;
  2040. m_lastChildAgentUpdateDrawDistance = DrawDistance;
  2041. m_lastRegionsDrawDistance = RegionViewDistance;
  2042. m_lastChildAgentUpdateGodLevel = GodController.ViwerUIGodLevel;
  2043. m_childUpdatesBusy = false; // allow them
  2044. }
  2045. // send the rest of the world
  2046. //if (m_teleportFlags > 0 || m_currentParcelHide)
  2047. //SendInitialDataToMe();
  2048. //SendOtherAgentsAvatarFullToMe();
  2049. // priority uses avatar position only
  2050. // m_reprioritizationLastPosition = AbsolutePosition;
  2051. // m_reprioritizationLastDrawDistance = DrawDistance;
  2052. // m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it
  2053. // m_reprioritizationBusy = false;
  2054. if (openChildAgents)
  2055. {
  2056. IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
  2057. if (friendsModule != null)
  2058. {
  2059. if(m_gotCrossUpdate)
  2060. friendsModule.IsNowRoot(this);
  2061. else
  2062. friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
  2063. }
  2064. //m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  2065. }
  2066. }
  2067. else
  2068. NeedInitialData = -1;
  2069. }
  2070. finally
  2071. {
  2072. m_haveGroupInformation = false;
  2073. m_gotCrossUpdate = false;
  2074. m_crossingFlags = 0;
  2075. m_inTransit = false;
  2076. }
  2077. m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
  2078. m_log.DebugFormat("[CompleteMovement] end: {0}ms", Util.EnvironmentTickCountSubtract(ts));
  2079. }
  2080. /// <summary>
  2081. /// Callback for the Camera view block check. Gets called with the results of the camera view block test
  2082. /// hitYN is true when there's something in the way.
  2083. /// </summary>
  2084. /// <param name="hitYN"></param>
  2085. /// <param name="collisionPoint"></param>
  2086. /// <param name="localid"></param>
  2087. /// <param name="distance"></param>
  2088. ///
  2089. private void checkCameraCollision()
  2090. {
  2091. if(m_doingCamRayCast || !m_scene.PhysicsScene.SupportsRayCast())
  2092. return;
  2093. if(m_mouseLook || ParentID != 0)
  2094. {
  2095. if (CameraConstraintActive)
  2096. {
  2097. Vector4 plane = new(0.9f, 0.0f, 0.361f, -10000f); // not right...
  2098. UpdateCameraCollisionPlane(plane);
  2099. CameraConstraintActive = false;
  2100. }
  2101. return;
  2102. }
  2103. Vector3 posAdjusted = AbsolutePosition;
  2104. posAdjusted.Z += 1.0f; // viewer current camera focus point
  2105. if(posAdjusted.ApproxEquals(m_lastCameraRayCastPos, 0.2f) &&
  2106. CameraPosition.ApproxEquals(m_lastCameraRayCastCam, 0.2f))
  2107. return;
  2108. m_lastCameraRayCastCam = CameraPosition;
  2109. m_lastCameraRayCastPos = posAdjusted;
  2110. Vector3 tocam = CameraPosition - posAdjusted;
  2111. float distTocamlen = tocam.LengthSquared();
  2112. if (distTocamlen > 0.01f && distTocamlen < 400)
  2113. {
  2114. distTocamlen = (float)Math.Sqrt(distTocamlen);
  2115. tocam *= (1.0f / distTocamlen);
  2116. m_doingCamRayCast = true;
  2117. m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
  2118. return;
  2119. }
  2120. if (CameraConstraintActive)
  2121. {
  2122. Vector4 plane = new(0.9f, 0.0f, 0.361f, -10000f); // not right...
  2123. UpdateCameraCollisionPlane(plane);
  2124. CameraConstraintActive = false;
  2125. }
  2126. }
  2127. private void UpdateCameraCollisionPlane(Vector4 plane)
  2128. {
  2129. if (m_lastCameraCollisionPlane.NotEqual(plane))
  2130. {
  2131. m_lastCameraCollisionPlane = plane;
  2132. ControllingClient.SendCameraConstraint(plane);
  2133. }
  2134. }
  2135. public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
  2136. {
  2137. if (hitYN && localid != LocalId)
  2138. {
  2139. if (localid != 0)
  2140. {
  2141. SceneObjectPart part = m_scene.GetSceneObjectPart(localid);
  2142. if (part != null && !part.VolumeDetectActive)
  2143. {
  2144. CameraConstraintActive = true;
  2145. pNormal.X = (float) Math.Round(pNormal.X, 2);
  2146. pNormal.Y = (float) Math.Round(pNormal.Y, 2);
  2147. pNormal.Z = (float) Math.Round(pNormal.Z, 2);
  2148. pNormal.Normalize();
  2149. collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
  2150. collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
  2151. collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
  2152. Vector4 plane = new(pNormal.X, pNormal.Y, pNormal.Z, collisionPoint.Dot(pNormal));
  2153. UpdateCameraCollisionPlane(plane);
  2154. }
  2155. }
  2156. else
  2157. {
  2158. CameraConstraintActive = true;
  2159. pNormal.X = (float) Math.Round(pNormal.X, 2);
  2160. pNormal.Y = (float) Math.Round(pNormal.Y, 2);
  2161. pNormal.Z = (float) Math.Round(pNormal.Z, 2);
  2162. pNormal.Normalize();
  2163. collisionPoint.X = (float) Math.Round(collisionPoint.X, 1);
  2164. collisionPoint.Y = (float) Math.Round(collisionPoint.Y, 1);
  2165. collisionPoint.Z = (float) Math.Round(collisionPoint.Z, 1);
  2166. Vector4 plane = new(pNormal.X, pNormal.Y, pNormal.Z,collisionPoint.Dot(pNormal));
  2167. UpdateCameraCollisionPlane(plane);
  2168. }
  2169. }
  2170. else if(CameraConstraintActive)
  2171. {
  2172. Vector4 plane = new(0.9f, 0.0f, 0.361f, -9000f); // not right...
  2173. UpdateCameraCollisionPlane(plane);
  2174. CameraConstraintActive = false;
  2175. }
  2176. m_doingCamRayCast = false;
  2177. }
  2178. /// <summary>
  2179. /// This is the event handler for client movement. If a client is moving, this event is triggering.
  2180. /// </summary>
  2181. public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
  2182. {
  2183. //m_log.DebugFormat(
  2184. // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
  2185. // Scene.Name, remoteClient.Name, (ACFlags)agentData.ControlFlags);
  2186. if (IsChildAgent || IsInTransit)
  2187. {
  2188. //m_log.DebugFormat("DEBUG: HandleAgentUpdate: child agent in {0}", Scene.Name);
  2189. return;
  2190. }
  2191. #region Sanity Checking
  2192. // This is irritating. Really.
  2193. if (!AbsolutePosition.IsFinite())
  2194. {
  2195. bool isphysical = PhysicsActor != null;
  2196. if(isphysical)
  2197. RemoveFromPhysicalScene();
  2198. m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
  2199. m_pos = m_LastFinitePos;
  2200. if (!m_pos.IsFinite())
  2201. {
  2202. m_pos.X = 127f;
  2203. m_pos.Y = 127f;
  2204. m_pos.Z = 127f;
  2205. m_log.Error("[AVATAR]: NonFinite Avatar on lastFiniteposition also. Reset Position. Mantis this please. Error #9999903");
  2206. }
  2207. if(isphysical)
  2208. AddToPhysicalScene(false);
  2209. }
  2210. else
  2211. {
  2212. m_LastFinitePos = m_pos;
  2213. }
  2214. #endregion Sanity Checking
  2215. #region Inputs
  2216. // The Agent's Draw distance setting
  2217. // When we get to the point of re-computing neighbors everytime this
  2218. // changes, then start using the agent's drawdistance rather than the
  2219. // region's draw distance.
  2220. DrawDistance = agentData.Far;
  2221. ACFlags allFlags = (ACFlags)agentData.ControlFlags;
  2222. bool newHideTitle = (agentData.Flags & (byte)AgentUpdateFlags.HideTitle) != 0;
  2223. if(HideTitle != newHideTitle)
  2224. {
  2225. HideTitle = newHideTitle;
  2226. SendAvatarDataToAllAgents();
  2227. }
  2228. MuteCollisions = (agentData.Flags & (byte)AgentUpdateFlags.MuteCollisions) != 0;
  2229. // FIXME: This does not work as intended because the viewer only sends the lbutton down when the button
  2230. // is first pressed, not whilst it is held down. If this is required in the future then need to look
  2231. // for an AGENT_CONTROL_LBUTTON_UP event and make sure to handle cases where an initial DOWN is not
  2232. // received (e.g. on holding LMB down on the avatar in a viewer).
  2233. m_leftButtonDown = (allFlags & ACFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
  2234. m_mouseLook = (allFlags & ACFlags.AGENT_CONTROL_MOUSELOOK) != 0;
  2235. m_headrotation = agentData.HeadRotation;
  2236. //byte oldState = State;
  2237. State = agentData.State;
  2238. #endregion Inputs
  2239. //if (oldState != State)
  2240. // SendAgentTerseUpdate(this);
  2241. if ((allFlags & ACFlags.AGENT_CONTROL_STAND_UP) != 0)
  2242. StandUp();
  2243. if ((allFlags & ACFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
  2244. HandleAgentSitOnGround();
  2245. ACFlags flags = RemoveIgnoredControls(allFlags, IgnoredControls);
  2246. m_AgentControlFlags = flags;
  2247. // Raycast from the avatar's head to the camera to see if there's anything blocking the view
  2248. // this exclude checks may not be complete
  2249. if (agentData.NeedsCameraCollision)
  2250. checkCameraCollision();
  2251. // This will be the case if the agent is sitting on the groudn or on an object.
  2252. PhysicsActor actor = m_physActor;
  2253. if (actor == null)
  2254. {
  2255. SendControlsToScripts((uint)allFlags);
  2256. return;
  2257. }
  2258. if (AllowMovement)
  2259. {
  2260. Rotation = agentData.BodyRotation;
  2261. //m_log.DebugFormat("[SCENE PRESENCE]: Initial body rotation {0} for {1}", agentData.BodyRotation, Name);
  2262. bool update_movementflag = false;
  2263. bool DCFlagKeyPressed = false;
  2264. bool mvToTarget = m_movingToTarget;
  2265. if (agentData.UseClientAgentPosition)
  2266. {
  2267. m_movingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).LengthSquared() > 0.04f;
  2268. m_moveToPositionTarget = agentData.ClientAgentPosition;
  2269. m_moveToSpeed = -1f;
  2270. }
  2271. Vector3 agent_control_v3 = Vector3.Zero;
  2272. float agent_velocity = AgentControlNormalVel;
  2273. uint oldflags = MovementFlags & (CONTROL_FLAG_NUDGE_MASK | CONTROL_FLAG_NORM_MASK);
  2274. MovementFlags = (uint)flags & (CONTROL_FLAG_NUDGE_MASK | CONTROL_FLAG_NORM_MASK);
  2275. if (MovementFlags != 0)
  2276. {
  2277. DCFlagKeyPressed = true;
  2278. mvToTarget = false;
  2279. //update_movementflag |= (MovementFlags ^ oldflags) != 0;
  2280. update_movementflag = true;
  2281. if (!m_setAlwaysRun && (flags & (ACFlags.AGENT_CONTROL_FAST_AT | ACFlags.AGENT_CONTROL_FAST_UP)) == 0)
  2282. agent_velocity = AgentControlMidVel;
  2283. if ((MovementFlags & CONTROL_FLAG_NUDGE_MASK) != 0)
  2284. MovementFlags |= (MovementFlags >> 19);
  2285. for (int i = 0, mask = 1; i < 6; ++i, mask <<= 1)
  2286. {
  2287. if((MovementFlags & mask) != 0)
  2288. agent_control_v3 += Dir_Vectors[i];
  2289. }
  2290. }
  2291. else
  2292. {
  2293. if (oldflags != 0)
  2294. update_movementflag = true;
  2295. }
  2296. bool newFlying;
  2297. if (ForceFly)
  2298. newFlying = true;
  2299. else if (FlyDisabled)
  2300. newFlying = false;
  2301. else if (mvToTarget)
  2302. newFlying = actor.Flying;
  2303. else
  2304. newFlying = ((flags & ACFlags.AGENT_CONTROL_FLY) != 0);
  2305. if (actor.Flying != newFlying)
  2306. {
  2307. actor.Flying = newFlying;
  2308. update_movementflag = true;
  2309. }
  2310. // Detect AGENT_CONTROL_STOP state changes
  2311. if (AgentControlStopActive != ((flags & ACFlags.AGENT_CONTROL_STOP) != 0))
  2312. {
  2313. AgentControlStopActive = !AgentControlStopActive;
  2314. update_movementflag = true;
  2315. }
  2316. if (m_movingToTarget)
  2317. {
  2318. // If the user has pressed a key then we want to cancel any move to target.
  2319. if (DCFlagKeyPressed)
  2320. {
  2321. ResetMoveToTarget();
  2322. update_movementflag = true;
  2323. }
  2324. else
  2325. {
  2326. // The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
  2327. // certain position. It's only check for tolerance on returning to that position is 0.2
  2328. // rather than 1, at which point it removes its force target.
  2329. if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2f : 0.5f, ref agent_control_v3))
  2330. update_movementflag = true;
  2331. }
  2332. }
  2333. // Only do this if we're flying
  2334. if (Flying && !ForceFly)
  2335. {
  2336. //m_log.Debug("[CONTROL]: " +flags);
  2337. // Applies a satisfying roll effect to the avatar when flying.
  2338. const ACFlags flagsLeft = ACFlags.AGENT_CONTROL_TURN_LEFT | ACFlags.AGENT_CONTROL_YAW_POS;
  2339. const ACFlags flagsRight = ACFlags.AGENT_CONTROL_TURN_RIGHT | ACFlags.AGENT_CONTROL_YAW_NEG;
  2340. if ((flags & flagsLeft) == flagsLeft)
  2341. {
  2342. ApplyFlyingRoll(
  2343. FLY_ROLL_RADIANS_PER_UPDATE,
  2344. (flags & ACFlags.AGENT_CONTROL_UP_POS) != 0,
  2345. (flags & ACFlags.AGENT_CONTROL_UP_NEG) != 0);
  2346. }
  2347. else if ((flags & flagsRight) == flagsRight)
  2348. {
  2349. ApplyFlyingRoll(
  2350. -FLY_ROLL_RADIANS_PER_UPDATE,
  2351. (flags & ACFlags.AGENT_CONTROL_UP_POS) != 0,
  2352. (flags & ACFlags.AGENT_CONTROL_UP_NEG) != 0);
  2353. }
  2354. else
  2355. {
  2356. if (m_AngularVelocity.Z != 0)
  2357. m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
  2358. }
  2359. }
  2360. else if (IsColliding && agent_control_v3.Z < 0f)
  2361. agent_control_v3.Z = 0;
  2362. //m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name);
  2363. // If the agent update does move the avatar, then calculate the force ready for the velocity update,
  2364. // which occurs later in the main scene loop
  2365. // We also need to update if the user rotates their avatar whilst it is slow walking/running (if they
  2366. // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update
  2367. // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the
  2368. // avatar location in place).
  2369. if (update_movementflag)
  2370. {
  2371. if (AgentControlStopActive)
  2372. {
  2373. //if (MovementFlag == 0 && Animator.Falling)
  2374. if (MovementFlags == 0 && Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling)
  2375. {
  2376. AddNewMovement(agent_control_v3, AgentControlStopSlowVel, true);
  2377. }
  2378. else
  2379. AddNewMovement(agent_control_v3, AgentControlStopSlowVel);
  2380. }
  2381. else
  2382. {
  2383. if(m_movingToTarget ||
  2384. (Animator.currentControlState != ScenePresenceAnimator.motionControlStates.flying &&
  2385. Animator.currentControlState != ScenePresenceAnimator.motionControlStates.onsurface)
  2386. )
  2387. AddNewMovement(agent_control_v3, agent_velocity);
  2388. else
  2389. {
  2390. if (MovementFlags != 0)
  2391. AddNewMovement(agent_control_v3, agent_velocity);
  2392. else
  2393. m_delayedStop = Util.GetTimeStampMS() + 250.0;
  2394. }
  2395. }
  2396. }
  2397. else if((flags & ACFlags.AGENT_CONTROL_FINISH_ANIM) != 0)
  2398. Animator.UpdateMovementAnimations();
  2399. SendControlsToScripts((uint)allFlags);
  2400. }
  2401. }
  2402. private void HandleAgentFOV(IClientAPI remoteClient, float _fov)
  2403. {
  2404. m_FOV = _fov;
  2405. }
  2406. /// <summary>
  2407. /// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering.
  2408. /// </summary>
  2409. private void HandleAgentCamerasUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
  2410. {
  2411. //m_log.DebugFormat(
  2412. // "[SCENE PRESENCE]: In {0} received agent camera update from {1}, flags {2}",
  2413. // Scene.RegionInfo.RegionName, remoteClient.Name, (ACFlags)agentData.ControlFlags);
  2414. if (IsChildAgent || IsInTransit)
  2415. return;
  2416. // Camera location in world. We'll need to raytrace
  2417. // from this location from time to time.
  2418. CameraPosition = agentData.CameraCenter;
  2419. CameraAtAxis = agentData.CameraAtAxis;
  2420. CameraAtAxis.Normalize();
  2421. CameraLeftAxis = agentData.CameraLeftAxis;
  2422. CameraLeftAxis.Normalize();
  2423. CameraUpAxis = agentData.CameraUpAxis;
  2424. CameraUpAxis.Normalize();
  2425. CameraRotation = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
  2426. DrawDistance = agentData.Far;
  2427. if (agentData.NeedsCameraCollision)
  2428. checkCameraCollision();
  2429. TriggerScenePresenceUpdated();
  2430. }
  2431. /// <summary>
  2432. /// Calculate an update to move the presence to the set target.
  2433. /// </summary>
  2434. /// <remarks>
  2435. /// This doesn't actually perform the movement. Instead, it adds its vector to agent_control_v3.
  2436. /// </remarks>
  2437. /// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
  2438. /// <returns>True if movement has been updated in some way. False otherwise.</returns>
  2439. public bool HandleMoveToTargetUpdate(float tolerance, ref Vector3 agent_control_v3)
  2440. {
  2441. //m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
  2442. bool updated = false;
  2443. Vector3 LocalVectorToTarget3D = m_moveToPositionTarget - AbsolutePosition;
  2444. //m_log.DebugFormat(
  2445. // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
  2446. // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
  2447. float distanceToTarget;
  2448. //if(Flying && !LandAtTarget)
  2449. // distanceToTarget = LocalVectorToTarget3D.LengthSquared();
  2450. //else
  2451. distanceToTarget = (LocalVectorToTarget3D.X * LocalVectorToTarget3D.X) + (LocalVectorToTarget3D.Y * LocalVectorToTarget3D.Y);
  2452. // m_log.DebugFormat(
  2453. // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
  2454. // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
  2455. // Check the error term of the current position in relation to the target position
  2456. if (distanceToTarget <= tolerance * tolerance)
  2457. {
  2458. // We are close enough to the target
  2459. Velocity = Vector3.Zero;
  2460. if (Flying)
  2461. {
  2462. if (LandAtTarget)
  2463. {
  2464. Flying = false;
  2465. // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot
  2466. // the target if flying.
  2467. // We really need to be more subtle (slow the avatar as it approaches the target) or at
  2468. // least be able to set collision status once, rather than 5 times to give it enough
  2469. // weighting so that that PhysicsActor thinks it really is colliding.
  2470. for (int i = 0; i < 5; i++)
  2471. IsColliding = true;
  2472. }
  2473. }
  2474. else
  2475. m_moveToPositionTarget.Z = AbsolutePosition.Z;
  2476. AbsolutePosition = m_moveToPositionTarget;
  2477. ResetMoveToTarget();
  2478. return false;
  2479. }
  2480. if(Flying && !LandAtTarget)
  2481. distanceToTarget = LocalVectorToTarget3D.LengthSquared();
  2482. if (m_moveToSpeed > 0 &&
  2483. distanceToTarget <= m_moveToSpeed * m_moveToSpeed * Scene.FrameTime * Scene.FrameTime)
  2484. m_moveToSpeed = MathF.Sqrt(distanceToTarget) / Scene.FrameTime;
  2485. try
  2486. {
  2487. // move avatar in 3D towards target, in avatar coordinate frame.
  2488. // This movement vector gets added to the velocity through AddNewMovement().
  2489. // Theoretically we might need a more complex PID approach here if other
  2490. // unknown forces are acting on the avatar and we need to adaptively respond
  2491. // to such forces, but the following simple approach seems to works fine.
  2492. float angle = 0.5f * MathF.Atan2(LocalVectorToTarget3D.Y, LocalVectorToTarget3D.X);
  2493. Quaternion rot = new(0,0, MathF.Sin(angle),MathF.Cos(angle));
  2494. Rotation = rot;
  2495. LocalVectorToTarget3D *= Quaternion.Inverse(rot); // change to avatar coords
  2496. if(!Flying)
  2497. LocalVectorToTarget3D.Z = 0;
  2498. LocalVectorToTarget3D.Normalize();
  2499. // update avatar movement flags. the avatar coordinate system is as follows:
  2500. //
  2501. // +X (forward)
  2502. //
  2503. // ^
  2504. // |
  2505. // |
  2506. // |
  2507. // |
  2508. // (left) +Y <--------o--------> -Y
  2509. // avatar
  2510. // |
  2511. // |
  2512. // |
  2513. // |
  2514. // v
  2515. // -X
  2516. //
  2517. // based on the above avatar coordinate system, classify the movement into
  2518. // one of left/right/back/forward.
  2519. uint tmpAgentControlFlags = 0;
  2520. if (LocalVectorToTarget3D.X < 0) //MoveBack
  2521. tmpAgentControlFlags = (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
  2522. else if (LocalVectorToTarget3D.X > 0) //Move Forward
  2523. tmpAgentControlFlags = (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
  2524. if (LocalVectorToTarget3D.Y > 0) //MoveLeft
  2525. tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
  2526. else if (LocalVectorToTarget3D.Y < 0) //MoveRight
  2527. tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
  2528. updated = LocalVectorToTarget3D.Z != 0;
  2529. updated |= tmpAgentControlFlags != 0;
  2530. //m_log.DebugFormat(
  2531. // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
  2532. // LocalVectorToTarget3D, agent_control_v3, Name);
  2533. const uint noMovFlagsMask = (uint)(~CONTROL_FLAG_NORM_MASK);
  2534. MovementFlags &= noMovFlagsMask;
  2535. MovementFlags |= tmpAgentControlFlags;
  2536. m_AgentControlFlags &= unchecked((ACFlags)noMovFlagsMask);
  2537. m_AgentControlFlags |= (ACFlags)tmpAgentControlFlags;
  2538. if (updated)
  2539. agent_control_v3 = LocalVectorToTarget3D;
  2540. }
  2541. catch (Exception e)
  2542. {
  2543. //Avoid system crash, can be slower but...
  2544. m_log.DebugFormat("Crash! {0}", e.ToString());
  2545. }
  2546. return updated;
  2547. // AddNewMovement(agent_control_v3);
  2548. }
  2549. public void MoveToTargetHandle(Vector3 pos, bool noFly, bool landAtTarget)
  2550. {
  2551. MoveToTarget(pos, noFly, landAtTarget, false);
  2552. }
  2553. /// <summary>
  2554. /// Move to the given target over time.
  2555. /// </summary>
  2556. /// <param name="pos"></param>
  2557. /// <param name="noFly">
  2558. /// If true, then don't allow the avatar to fly to the target, even if it's up in the air.
  2559. /// This is to allow movement to targets that are known to be on an elevated platform with a continuous path
  2560. /// from start to finish.
  2561. /// </param>
  2562. /// <param name="landAtTarget">
  2563. /// If true and the avatar starts flying during the move then land at the target.
  2564. /// </param>
  2565. public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget, bool running, float tau = -1f)
  2566. {
  2567. m_delayedStop = -1;
  2568. if (IsSitting)
  2569. StandUp();
  2570. //m_log.DebugFormat(
  2571. // "[SCENE PRESENCE]: Avatar {0} received request to move to position {1} in {2}",
  2572. // Name, pos, m_scene.RegionInfo.RegionName);
  2573. // Allow move to another sub-region within a megaregion
  2574. Vector2 regionSize;
  2575. regionSize = new Vector2(m_scene.RegionInfo.RegionSizeX, m_scene.RegionInfo.RegionSizeY);
  2576. if (pos.X < 0.5f)
  2577. pos.X = 0.5f;
  2578. else if (pos.X > regionSize.X - 0.5f)
  2579. pos.X = regionSize.X - 0.5f;
  2580. if (pos.Y < 0.5f)
  2581. pos.Y = 0.5f;
  2582. else if (pos.Y > regionSize.Y - 0.5f)
  2583. pos.Y = regionSize.Y - 0.5f;
  2584. float terrainHeight;
  2585. terrainHeight = m_scene.GetGroundHeight(pos.X, pos.Y);
  2586. // dont try to land underground
  2587. terrainHeight += Appearance.AvatarHeight * 0.5f + 0.2f;
  2588. if(terrainHeight > pos.Z)
  2589. pos.Z = terrainHeight;
  2590. //m_log.DebugFormat(
  2591. // "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}",
  2592. // Name, pos, terrainHeight, m_scene.RegionInfo.RegionName);
  2593. bool shouldfly = true;
  2594. if(IsNPC)
  2595. {
  2596. if (!Flying)
  2597. shouldfly = !noFly && (pos.Z > terrainHeight + Appearance.AvatarHeight);
  2598. LandAtTarget = landAtTarget && shouldfly;
  2599. }
  2600. else
  2601. {
  2602. // we have no control on viewer fly state
  2603. shouldfly = Flying || (pos.Z > terrainHeight + Appearance.AvatarHeight);
  2604. LandAtTarget = false;
  2605. }
  2606. // m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0},[1}", localVectorToTarget3D.X,localVectorToTarget3D.Y);
  2607. if(tau > 0)
  2608. {
  2609. if(tau < Scene.FrameTime)
  2610. tau = Scene.FrameTime;
  2611. Vector3 localVectorToTarget3D = pos - AbsolutePosition;
  2612. if (!shouldfly)
  2613. localVectorToTarget3D.Z = 0;
  2614. m_moveToSpeed = localVectorToTarget3D.Length() / tau;
  2615. if(m_moveToSpeed < 0.5f) //to tune
  2616. m_moveToSpeed = 0.5f;
  2617. else if(m_moveToSpeed > 50f)
  2618. m_moveToSpeed = 50f;
  2619. }
  2620. else
  2621. m_moveToSpeed = AgentControlNormalVel * m_speedModifier;
  2622. SetAlwaysRun = running;
  2623. Flying = shouldfly;
  2624. m_moveToPositionTarget = pos;
  2625. m_movingToTarget = true;
  2626. Vector3 control = Vector3.Zero;
  2627. if(HandleMoveToTargetUpdate(0.5f, ref control))
  2628. AddNewMovement(control, AgentControlNormalVel);
  2629. }
  2630. /// <summary>
  2631. /// Reset the move to target.
  2632. /// </summary>
  2633. public void ResetMoveToTarget()
  2634. {
  2635. //m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
  2636. m_movingToTarget = false;
  2637. m_moveToSpeed = -1f;
  2638. //MoveToPositionTarget = Vector3.Zero;
  2639. //lock(m_forceToApplyLock)
  2640. // m_forceToApplyValid = false; // cancel possible last action
  2641. // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
  2642. // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
  2643. // However, the line is here rather than in the NPC module since it also appears necessary to stop a
  2644. // viewer that uses "go here" from juddering on all subsequent avatar movements.
  2645. AgentControlFlags = (uint)ACFlags.NONE;
  2646. if(IsNPC)
  2647. Animator.UpdateMovementAnimations();
  2648. }
  2649. /// <summary>
  2650. /// Perform the logic necessary to stand the avatar up. This method also executes
  2651. /// the stand animation.
  2652. /// </summary>
  2653. public void StandUp(bool addPhys = true)
  2654. {
  2655. //m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
  2656. bool satOnObject = IsSatOnObject;
  2657. SceneObjectPart part = ParentPart;
  2658. SitGround = false;
  2659. if (satOnObject)
  2660. {
  2661. PrevSitOffset = m_pos; // Save sit offset
  2662. UnRegisterSeatControls(part.ParentGroup.UUID);
  2663. TaskInventoryDictionary taskIDict = part.TaskInventory;
  2664. if (taskIDict != null)
  2665. {
  2666. lock (taskIDict)
  2667. {
  2668. foreach (UUID taskID in taskIDict.Keys)
  2669. {
  2670. UnRegisterControlEventsToScript(LocalId, taskID);
  2671. taskIDict[taskID].PermsMask &= ~(
  2672. 2048 | //PERMISSION_CONTROL_CAMERA
  2673. 4); // PERMISSION_TAKE_CONTROLS
  2674. }
  2675. }
  2676. }
  2677. ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
  2678. ParentID = 0;
  2679. ParentPart = null;
  2680. Quaternion standRotation = part.ParentGroup.RootPart.RotationOffset;
  2681. Vector3 sitWorldPosition = part.ParentGroup.AbsolutePosition + m_pos * standRotation;
  2682. standRotation *= m_bodyRot;
  2683. m_bodyRot = standRotation;
  2684. Quaternion standRotationZ;
  2685. Vector3 adjustmentForSitPose = part.StandOffset;
  2686. if (adjustmentForSitPose.X == 0 &&
  2687. adjustmentForSitPose.Y == 0 &&
  2688. adjustmentForSitPose.Z == 0)
  2689. {
  2690. standRotationZ = new Quaternion(0, 0, standRotation.Z, standRotation.W);
  2691. float t = standRotationZ.W * standRotationZ.W + standRotationZ.Z * standRotationZ.Z;
  2692. if (t > 0)
  2693. {
  2694. t = 1.0f / (float)Math.Sqrt(t);
  2695. standRotationZ.W *= t;
  2696. standRotationZ.Z *= t;
  2697. }
  2698. else
  2699. {
  2700. standRotationZ.W = 1.0f;
  2701. standRotationZ.Z = 0f;
  2702. }
  2703. adjustmentForSitPose = new Vector3(0.65f, 0, m_sitAvatarHeight * 0.5f + .1f) * standRotationZ;
  2704. }
  2705. else
  2706. {
  2707. sitWorldPosition = part.GetWorldPosition();
  2708. standRotation = part.GetWorldRotation();
  2709. standRotationZ = new Quaternion(0, 0, standRotation.Z, standRotation.W);
  2710. float t = standRotationZ.W * standRotationZ.W + standRotationZ.Z * standRotationZ.Z;
  2711. if (t > 0)
  2712. {
  2713. t = 1.0f / (float)Math.Sqrt(t);
  2714. standRotationZ.W *= t;
  2715. standRotationZ.Z *= t;
  2716. }
  2717. else
  2718. {
  2719. standRotationZ.W = 1.0f;
  2720. standRotationZ.Z = 0f;
  2721. }
  2722. adjustmentForSitPose *= standRotationZ;
  2723. if (Appearance != null && Appearance.AvatarHeight > 0)
  2724. adjustmentForSitPose.Z += 0.5f * Appearance.AvatarHeight + .1f;
  2725. else
  2726. adjustmentForSitPose.Z += .9f;
  2727. }
  2728. m_pos = sitWorldPosition + adjustmentForSitPose;
  2729. }
  2730. if (addPhys && PhysicsActor == null)
  2731. AddToPhysicalScene(false);
  2732. if (satOnObject)
  2733. {
  2734. m_requestedSitTargetID = 0;
  2735. part.RemoveSittingAvatar(this);
  2736. part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
  2737. SendAvatarDataToAllAgents();
  2738. m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on
  2739. }
  2740. // reset to default sitAnimation
  2741. sitAnimation = "SIT";
  2742. Animator.SetMovementAnimations("STAND");
  2743. TriggerScenePresenceUpdated();
  2744. }
  2745. private SceneObjectPart FindNextAvailableSitTarget(UUID targetID)
  2746. {
  2747. SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID);
  2748. if (targetPart == null)
  2749. return null;
  2750. // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used.
  2751. if (targetPart.IsSitTargetSet && targetPart.SitTargetAvatar.IsZero() && targetPart.SitActiveRange >= 0)
  2752. return targetPart;
  2753. // If the primitive the player clicked on has no sit target, and one or more other linked objects
  2754. // have sit targets that are not full, the sit target of the object with the lowest link number will be used.
  2755. SceneObjectPart[] partArray = targetPart.ParentGroup.Parts;
  2756. if (partArray.Length < 2)
  2757. return targetPart;
  2758. SceneObjectPart lastPart = null;
  2759. //look for prims with explicit sit targets that are available
  2760. foreach (SceneObjectPart part in partArray)
  2761. {
  2762. if (part.IsSitTargetSet && part.SitTargetAvatar.IsZero() && part.SitActiveRange >= 0)
  2763. {
  2764. if(lastPart == null)
  2765. {
  2766. if (part.LinkNum < 2)
  2767. return part;
  2768. lastPart = part;
  2769. }
  2770. else
  2771. {
  2772. if(lastPart.LinkNum > part.LinkNum)
  2773. lastPart = part;
  2774. }
  2775. }
  2776. }
  2777. // no explicit sit target found - use original target
  2778. return lastPart ?? targetPart;
  2779. }
  2780. private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion sitOrientation)
  2781. {
  2782. SceneObjectPart part = FindNextAvailableSitTarget(targetID);
  2783. if (part == null)
  2784. return;
  2785. float range = part.SitActiveRange;
  2786. if (range < 0)
  2787. return;
  2788. Vector3 pos = part.AbsolutePosition + offset;
  2789. if (range > 1e-5f)
  2790. {
  2791. if (Vector3.DistanceSquared(AbsolutePosition, pos) > range * range)
  2792. return;
  2793. }
  2794. if (PhysicsActor != null)
  2795. m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
  2796. if (part.IsSitTargetSet && part.SitTargetAvatar.IsZero())
  2797. {
  2798. offset = part.SitTargetPosition;
  2799. sitOrientation = part.SitTargetOrientation;
  2800. }
  2801. else
  2802. {
  2803. if (PhysicsSit(part,offset)) // physics engine
  2804. return;
  2805. if (Vector3.DistanceSquared(AbsolutePosition, pos) > 100f)
  2806. return;
  2807. AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
  2808. }
  2809. if (PhysicsActor != null)
  2810. RemoveFromPhysicalScene();
  2811. if (m_movingToTarget)
  2812. ResetMoveToTarget();
  2813. Velocity = Vector3.Zero;
  2814. m_AngularVelocity = Vector3.Zero;
  2815. part.AddSittingAvatar(this);
  2816. Vector3 cameraAtOffset = part.GetCameraAtOffset();
  2817. Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
  2818. bool forceMouselook = part.GetForceMouselook();
  2819. if (!part.IsRoot)
  2820. {
  2821. sitOrientation = part.RotationOffset * sitOrientation;
  2822. offset *= part.RotationOffset;
  2823. offset += part.OffsetPosition;
  2824. if (cameraAtOffset.IsZero() && cameraEyeOffset.IsZero())
  2825. {
  2826. cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset();
  2827. cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset();
  2828. }
  2829. else
  2830. {
  2831. cameraAtOffset *= part.RotationOffset;
  2832. cameraAtOffset += part.OffsetPosition;
  2833. cameraEyeOffset *= part.RotationOffset;
  2834. cameraEyeOffset += part.OffsetPosition;
  2835. }
  2836. }
  2837. sitOrientation = part.ParentGroup.RootPart.RotationOffset * sitOrientation;
  2838. ControllingClient.SendSitResponse(
  2839. part.ParentGroup.UUID, offset, sitOrientation,
  2840. true, cameraAtOffset, cameraEyeOffset, forceMouselook);
  2841. m_requestedSitTargetID = part.LocalId;
  2842. HandleAgentSit(ControllingClient, UUID);
  2843. // Moved here to avoid a race with default sit anim
  2844. // The script event needs to be raised after the default sit anim is set.
  2845. //part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
  2846. //m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on
  2847. }
  2848. public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset)
  2849. {
  2850. if (IsChildAgent)
  2851. return;
  2852. if (ParentID != 0)
  2853. {
  2854. if (targetID.Equals(ParentPart.UUID))
  2855. return; // already sitting here, ignore
  2856. StandUp();
  2857. }
  2858. else if (SitGround)
  2859. StandUp();
  2860. SendSitResponse(targetID, offset, Quaternion.Identity);
  2861. }
  2862. // returns false if does not suport so older sit can be tried
  2863. public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
  2864. {
  2865. if (part == null || part.ParentGroup.IsAttachment)
  2866. return true;
  2867. if ( m_scene.PhysicsScene == null)
  2868. return false;
  2869. if (part.PhysActor == null)
  2870. {
  2871. // none physics shape
  2872. if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
  2873. ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
  2874. else
  2875. { // non physical phantom TODO
  2876. //ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
  2877. return false;
  2878. }
  2879. return true;
  2880. }
  2881. m_requestedSitTargetID = part.LocalId;
  2882. if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
  2883. {
  2884. return true;
  2885. }
  2886. m_requestedSitTargetID = 0;
  2887. return false;
  2888. }
  2889. private bool CanEnterLandPosition(Vector3 testPos)
  2890. {
  2891. ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
  2892. if (land == null || land.LandData.Name == "NO_LAND")
  2893. return true;
  2894. return land.CanBeOnThisLand(UUID,testPos.Z);
  2895. }
  2896. // status
  2897. // < 0 ignore
  2898. // 0 bad sit spot
  2899. public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
  2900. {
  2901. if (status < 0)
  2902. return;
  2903. if (status == 0)
  2904. {
  2905. ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
  2906. return;
  2907. }
  2908. SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
  2909. if (part == null)
  2910. return;
  2911. Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
  2912. if(!CanEnterLandPosition(targetPos))
  2913. {
  2914. ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
  2915. return;
  2916. }
  2917. RemoveFromPhysicalScene();
  2918. if (m_movingToTarget)
  2919. ResetMoveToTarget();
  2920. Velocity = Vector3.Zero;
  2921. m_AngularVelocity = Vector3.Zero;
  2922. m_requestedSitTargetID = 0;
  2923. part.AddSittingAvatar(this);
  2924. ParentPart = part;
  2925. ParentID = part.LocalId;
  2926. Vector3 cameraAtOffset = part.GetCameraAtOffset();
  2927. Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
  2928. if (!part.IsRoot)
  2929. {
  2930. Orientation = part.RotationOffset * Orientation;
  2931. offset *= part.RotationOffset;
  2932. offset += part.OffsetPosition;
  2933. if (cameraAtOffset.IsZero() && cameraEyeOffset.IsZero())
  2934. {
  2935. cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset();
  2936. cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset();
  2937. }
  2938. else
  2939. {
  2940. cameraAtOffset *= part.RotationOffset;
  2941. cameraAtOffset += part.OffsetPosition;
  2942. cameraEyeOffset *= part.RotationOffset;
  2943. cameraEyeOffset += part.OffsetPosition;
  2944. }
  2945. }
  2946. m_bodyRot = Orientation;
  2947. m_pos = offset;
  2948. Orientation = part.ParentGroup.RootPart.RotationOffset * Orientation;
  2949. ControllingClient.SendSitResponse(
  2950. part.ParentGroup.UUID, offset, Orientation, true, cameraAtOffset, cameraEyeOffset, part.GetForceMouselook());
  2951. SendAvatarDataToAllAgents();
  2952. if (status == 3)
  2953. sitAnimation = "SIT_GROUND";
  2954. else
  2955. sitAnimation = "SIT";
  2956. Animator.SetMovementAnimations("SIT");
  2957. part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
  2958. m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on
  2959. }
  2960. public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
  2961. {
  2962. if (IsChildAgent)
  2963. return;
  2964. if(IsSitting)
  2965. return;
  2966. SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID);
  2967. m_requestedSitTargetID = 0;
  2968. if (part != null)
  2969. {
  2970. if (part.ParentGroup.IsAttachment)
  2971. {
  2972. m_log.WarnFormat(
  2973. "[SCENE PRESENCE]: Avatar {0} tried to sit on part {1} from object {2} in {3} but this is an attachment for avatar id {4}",
  2974. Name, part.Name, part.ParentGroup.Name, Scene.Name, part.ParentGroup.AttachedAvatar);
  2975. return;
  2976. }
  2977. RemoveFromPhysicalScene();
  2978. if (part.SitTargetAvatar.Equals(UUID))
  2979. {
  2980. Vector3 sitTargetPos = part.SitTargetPosition;
  2981. Quaternion sitTargetOrient = part.SitTargetOrientation;
  2982. //m_log.DebugFormat(
  2983. // "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}",
  2984. // Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId);
  2985. float x, y, z, m;
  2986. Vector3 sitOffset;
  2987. Quaternion r = sitTargetOrient;
  2988. Vector3 newPos;
  2989. Quaternion newRot;
  2990. if (LegacySitOffsets)
  2991. {
  2992. float m1, m2;
  2993. m1 = r.X * r.X + r.Y * r.Y;
  2994. m2 = r.Z * r.Z + r.W * r.W;
  2995. // Rotate the vector <0, 0, 1>
  2996. x = 2 * (r.X * r.Z + r.Y * r.W);
  2997. y = 2 * (-r.X * r.W + r.Y * r.Z);
  2998. z = m2 - m1;
  2999. // Set m to be the square of the norm of r.
  3000. m = m1 + m2;
  3001. // This constant is emperically determined to be what is used in SL.
  3002. // See also http://opensimulator.org/mantis/view.php?id=7096
  3003. float offset = 0.05f;
  3004. // Normally m will be ~ 1, but if someone passed a handcrafted quaternion
  3005. // to llSitTarget with values so small that squaring them is rounded off
  3006. // to zero, then m could be zero. The result of this floating point
  3007. // round off error (causing us to skip this impossible normalization)
  3008. // is only 5 cm.
  3009. if (m > 0.000001f)
  3010. {
  3011. offset /= m;
  3012. }
  3013. Vector3 up = new (x, y, z);
  3014. sitOffset = up * offset;
  3015. newPos = sitTargetPos - sitOffset + SIT_TARGET_ADJUSTMENT;
  3016. }
  3017. else
  3018. {
  3019. m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
  3020. if (MathF.Abs(1.0f - m) > 0.000001f)
  3021. {
  3022. if(m != 0f)
  3023. {
  3024. m = 1.0f / MathF.Sqrt(m);
  3025. r.X *= m;
  3026. r.Y *= m;
  3027. r.Z *= m;
  3028. r.W *= m;
  3029. }
  3030. else
  3031. {
  3032. r.X = 0.0f;
  3033. r.Y = 0.0f;
  3034. r.Z = 0.0f;
  3035. r.W = 1.0f;
  3036. }
  3037. }
  3038. x = 2 * (r.X * r.Z + r.Y * r.W);
  3039. y = 2 * (-r.X * r.W + r.Y * r.Z);
  3040. z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
  3041. Vector3 up = new(x, y, z);
  3042. sitOffset = up * Appearance.AvatarHeight * 0.02638f;
  3043. newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
  3044. }
  3045. if (part.IsRoot)
  3046. {
  3047. newRot = sitTargetOrient;
  3048. }
  3049. else
  3050. {
  3051. newPos *= part.RotationOffset;
  3052. newRot = part.RotationOffset * sitTargetOrient;
  3053. }
  3054. newPos += part.OffsetPosition;
  3055. m_pos = newPos;
  3056. Rotation = newRot;
  3057. //ParentPosition = part.AbsolutePosition;
  3058. }
  3059. else
  3060. {
  3061. // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is
  3062. // being sat upon.
  3063. m_pos -= part.GroupPosition;
  3064. }
  3065. part.AddSittingAvatar(this);
  3066. ParentPart = part;
  3067. ParentID = part.LocalId;
  3068. m_AngularVelocity = Vector3.Zero;
  3069. Velocity = Vector3.Zero;
  3070. SendAvatarDataToAllAgents();
  3071. if (String.IsNullOrEmpty(part.SitAnimation))
  3072. sitAnimation = "SIT";
  3073. else
  3074. sitAnimation = part.SitAnimation;
  3075. Animator.SetMovementAnimations("SIT");
  3076. //TriggerScenePresenceUpdated();
  3077. part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
  3078. m_scene.EventManager.TriggerParcelPrimCountTainted(); // update select/ sat on
  3079. }
  3080. }
  3081. public void HandleAgentSitOnGround()
  3082. {
  3083. if (IsChildAgent)
  3084. return;
  3085. sitAnimation = "SIT_GROUND_CONSTRAINED";
  3086. SitGround = true;
  3087. RemoveFromPhysicalScene();
  3088. m_AngularVelocity = Vector3.Zero;
  3089. Velocity = Vector3.Zero;
  3090. Animator.SetMovementAnimations("SITGROUND");
  3091. TriggerScenePresenceUpdated();
  3092. }
  3093. /// <summary>
  3094. /// Event handler for the 'Always run' setting on the client
  3095. /// Tells the physics plugin to increase speed of movement.
  3096. /// </summary>
  3097. public void HandleSetAlwaysRun(IClientAPI remoteClient, bool pSetAlwaysRun)
  3098. {
  3099. SetAlwaysRun = pSetAlwaysRun;
  3100. }
  3101. public void HandleStartAnim(IClientAPI remoteClient, UUID animID)
  3102. {
  3103. Animator.AddAnimation(animID, UUID.Zero);
  3104. TriggerScenePresenceUpdated();
  3105. }
  3106. public void HandleStopAnim(IClientAPI remoteClient, UUID animID)
  3107. {
  3108. Animator.RemoveAnimation(animID, false);
  3109. TriggerScenePresenceUpdated();
  3110. }
  3111. public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack)
  3112. {
  3113. Animator.avnChangeAnim(animID, addRemove, sendPack);
  3114. }
  3115. // old api hook, to remove
  3116. public void AddNewMovement(Vector3 vec)
  3117. {
  3118. AddNewMovement(vec, AgentControlNormalVel);
  3119. }
  3120. /// <summary>
  3121. /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
  3122. /// </summary>
  3123. /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
  3124. /// <param name="thisAddSpeedModifier">
  3125. /// Optional additional speed modifier for this particular add. Default is 1</param>
  3126. public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier, bool breaking = false)
  3127. {
  3128. // m_log.DebugFormat(
  3129. // "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}",
  3130. // vec, Rotation, thisAddSpeedModifier, Name);
  3131. m_delayedStop = -1;
  3132. // rotate from avatar coord space to world
  3133. Quaternion rot = Rotation;
  3134. if (!Flying && !IsNPC)
  3135. {
  3136. // force rotation to be around Z only, if not flying
  3137. // needed for mouselook
  3138. rot.X = 0;
  3139. rot.Y = 0;
  3140. }
  3141. Vector3 direc = vec * rot;
  3142. direc.Normalize();
  3143. if ((vec.Z == 0f) && !Flying)
  3144. direc.Z = 0f; // Prevent camera WASD up.
  3145. bool notmvtrgt = !m_movingToTarget || m_moveToSpeed <= 0;
  3146. // odd rescalings
  3147. if(notmvtrgt)
  3148. direc *= SpeedModifier * thisAddSpeedModifier;
  3149. else
  3150. direc *= m_moveToSpeed;
  3151. //m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name);
  3152. if (Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling
  3153. && (PhysicsActor == null || !PhysicsActor.PIDHoverActive))
  3154. {
  3155. if (breaking)
  3156. direc.Z = -9999f; //hack to tell physics to stop on Z
  3157. //else
  3158. //direc = Vector3.Zero;
  3159. }
  3160. else if (Flying)
  3161. {
  3162. if (notmvtrgt)
  3163. {
  3164. if (IsColliding && direc.Z < 0)
  3165. // landing situation, prevent avatar moving or it may fail to land
  3166. // animator will handle this condition and do the land
  3167. direc = Vector3.Zero;
  3168. else
  3169. direc *= 4.0f;
  3170. }
  3171. }
  3172. else if (IsColliding)
  3173. {
  3174. if (((AgentControlFlags & (uint)ACFlags.AGENT_CONTROL_UP_POS) != 0) && notmvtrgt) // reinforce jumps
  3175. {
  3176. direc.Z = 0;
  3177. }
  3178. else if (direc.Z < 0) // on a surface moving down (pg down) only changes animation
  3179. direc.Z = 0;
  3180. }
  3181. TargetVelocity = direc;
  3182. Animator.UpdateMovementAnimations();
  3183. }
  3184. #endregion
  3185. #region Overridden Methods
  3186. const float ROTATION_TOLERANCE = 0.01f;
  3187. const float VELOCITY_TOLERANCE = 0.1f;
  3188. const float LOWVELOCITYSQ = 0.1f;
  3189. const float POSITION_LARGETOLERANCE = 5f;
  3190. const float POSITION_SMALLTOLERANCE = 0.05f;
  3191. public override void Update()
  3192. {
  3193. if (IsDeleted)
  3194. return;
  3195. if (NeedInitialData > 0)
  3196. {
  3197. SendInitialData();
  3198. return;
  3199. }
  3200. if (IsChildAgent || IsInTransit)
  3201. return;
  3202. CheckForBorderCrossing();
  3203. if (m_movingToTarget)
  3204. {
  3205. m_delayedStop = -1;
  3206. Vector3 control = Vector3.Zero;
  3207. if(HandleMoveToTargetUpdate(0.5f, ref control))
  3208. AddNewMovement(control, AgentControlNormalVel);
  3209. }
  3210. else if(m_delayedStop > 0)
  3211. {
  3212. if(IsSatOnObject)
  3213. m_delayedStop = -1;
  3214. else if(Util.GetTimeStampMS() > m_delayedStop)
  3215. {
  3216. m_delayedStop = -1;
  3217. AddNewMovement(Vector3.Zero, 0);
  3218. }
  3219. }
  3220. if (Appearance.AvatarSize.NotEqual(m_lastSize))
  3221. SendAvatarDataToAllAgents();
  3222. // Send terse position update if not sitting and position, velocity, or rotation
  3223. // has changed significantly from last sent update
  3224. if (!IsSatOnObject)
  3225. {
  3226. if (State != m_lastState ||
  3227. Math.Abs(m_bodyRot.X - m_lastRotation.X) > ROTATION_TOLERANCE ||
  3228. Math.Abs(m_bodyRot.Y - m_lastRotation.Y) > ROTATION_TOLERANCE ||
  3229. Math.Abs(m_bodyRot.Z - m_lastRotation.Z) > ROTATION_TOLERANCE ||
  3230. Math.Abs(CollisionPlane.X - m_lastCollisionPlane.X) > POSITION_SMALLTOLERANCE ||
  3231. Math.Abs(CollisionPlane.Y - m_lastCollisionPlane.Y) > POSITION_SMALLTOLERANCE ||
  3232. Math.Abs(CollisionPlane.W - m_lastCollisionPlane.W) > POSITION_SMALLTOLERANCE)
  3233. {
  3234. SendTerseUpdateToAllClients();
  3235. }
  3236. else
  3237. {
  3238. Vector3 vel = Velocity;
  3239. if(!vel.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
  3240. (vel.IsZero() && !m_lastVelocity.IsZero()))
  3241. {
  3242. SendTerseUpdateToAllClients();
  3243. }
  3244. else
  3245. {
  3246. Vector3 dpos = m_pos - m_lastPosition;
  3247. if(!dpos.ApproxZero(POSITION_LARGETOLERANCE) ||
  3248. ((!dpos.ApproxZero(POSITION_SMALLTOLERANCE)) && vel.LengthSquared() < LOWVELOCITYSQ))
  3249. {
  3250. SendTerseUpdateToAllClients();
  3251. }
  3252. }
  3253. }
  3254. }
  3255. CheckForSignificantMovement();
  3256. }
  3257. #endregion
  3258. #region Update Client(s)
  3259. public void SendUpdateToAgent(ScenePresence p)
  3260. {
  3261. IClientAPI remoteClient = p.ControllingClient;
  3262. if (remoteClient.IsActive)
  3263. {
  3264. //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
  3265. remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
  3266. m_scene.StatsReporter.AddAgentUpdates(1);
  3267. }
  3268. }
  3269. public void SendFullUpdateToClient(IClientAPI remoteClient)
  3270. {
  3271. if (remoteClient.IsActive)
  3272. {
  3273. //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
  3274. remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate);
  3275. m_scene.StatsReporter.AddAgentUpdates(1);
  3276. }
  3277. }
  3278. // this is diferente from SendTerseUpdateToClient
  3279. // this sends bypassing entities updates
  3280. public void SendAgentTerseUpdate(ISceneEntity p)
  3281. {
  3282. ControllingClient.SendAgentTerseUpdate(p);
  3283. }
  3284. /// <summary>
  3285. /// Sends a location update to the client connected to this scenePresence
  3286. /// via entity updates
  3287. /// </summary>
  3288. /// <param name="remoteClient"></param>
  3289. public void SendTerseUpdateToClient(IClientAPI remoteClient)
  3290. {
  3291. // If the client is inactive, it's getting its updates from another
  3292. // server.
  3293. if (remoteClient.IsActive)
  3294. {
  3295. //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
  3296. remoteClient.SendEntityUpdate(
  3297. this,
  3298. PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
  3299. | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
  3300. m_scene.StatsReporter.AddAgentUpdates(1);
  3301. }
  3302. }
  3303. public void SendTerseUpdateToAgent(ScenePresence p)
  3304. {
  3305. IClientAPI remoteClient = p.ControllingClient;
  3306. if (!remoteClient.IsActive)
  3307. return;
  3308. if (ParcelHideThisAvatar && p.currentParcelUUID.NotEqual(currentParcelUUID )&& !p.IsViewerUIGod)
  3309. return;
  3310. //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
  3311. remoteClient.SendEntityUpdate(
  3312. this,
  3313. PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
  3314. | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
  3315. m_scene.StatsReporter.AddAgentUpdates(1);
  3316. }
  3317. public void SendTerseUpdateToAgentNF(ScenePresence p)
  3318. {
  3319. IClientAPI remoteClient = p.ControllingClient;
  3320. if (remoteClient.IsActive)
  3321. {
  3322. //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity);
  3323. remoteClient.SendEntityUpdate(this,
  3324. PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity
  3325. | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
  3326. m_scene.StatsReporter.AddAgentUpdates(1);
  3327. }
  3328. }
  3329. /// <summary>
  3330. /// Send a location/velocity/accelleration update to all agents in scene
  3331. /// </summary>
  3332. public void SendTerseUpdateToAllClients()
  3333. {
  3334. m_lastState = State;
  3335. m_lastPosition = m_pos;
  3336. m_lastRotation = m_bodyRot;
  3337. m_lastVelocity = Velocity;
  3338. m_lastCollisionPlane = CollisionPlane;
  3339. m_scene.ForEachScenePresence(SendTerseUpdateToAgent);
  3340. // Update the "last" values
  3341. TriggerScenePresenceUpdated();
  3342. }
  3343. public void SetSendCoarseLocationMethod(SendCoarseLocationsMethod d)
  3344. {
  3345. m_sendCoarseLocationsMethod = d;
  3346. }
  3347. public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
  3348. {
  3349. m_sendCoarseLocationsMethod?.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs);
  3350. }
  3351. public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
  3352. {
  3353. ControllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations);
  3354. }
  3355. public void RegionHandShakeReply (IClientAPI client)
  3356. {
  3357. if(IsNPC)
  3358. return;
  3359. lock (m_completeMovementLock)
  3360. {
  3361. if(m_gotRegionHandShake)
  3362. return;
  3363. m_gotRegionHandShake = true;
  3364. NeedInitialData = 2;
  3365. }
  3366. }
  3367. private void SendInitialData()
  3368. {
  3369. //wait for region handshake
  3370. if (NeedInitialData < 2)
  3371. return;
  3372. uint flags = ControllingClient.GetViewerCaps();
  3373. if ((flags & (uint)ViewerFlags.SentSeeds) == 0) // wait for seeds sending
  3374. return;
  3375. // give some extra time to make sure viewers did process seeds
  3376. if (++NeedInitialData < 6) // needs fix if update rate changes on heartbeat
  3377. return;
  3378. /*
  3379. if(!GotAttachmentsData)
  3380. {
  3381. if(++NeedInitialData == 300) // 30s in current heartbeat
  3382. m_log.WarnFormat("[ScenePresence({0}] slow attachment assets transfer for {1}", Scene.Name, Name);
  3383. }
  3384. else if((m_teleportFlags & TeleportFlags.ViaHGLogin) != 0)
  3385. m_log.WarnFormat("[ScenePresence({0}] got hg attachment assets transfer for {1}, cntr = {2}", Scene.Name, Name, NeedInitialData);
  3386. */
  3387. NeedInitialData = -1;
  3388. bool selfappearance = (flags & 4) != 0;
  3389. // this should enqueued on the client processing job to save threads
  3390. Util.FireAndForget(delegate
  3391. {
  3392. if(!IsChildAgent)
  3393. {
  3394. // close v1 sender region obsolete
  3395. if (!string.IsNullOrEmpty(m_callbackURI))
  3396. {
  3397. m_log.DebugFormat(
  3398. "[SCENE PRESENCE({0})]: Releasing {1} {2} with old callback to {3}",
  3399. Scene.RegionInfo.RegionName, Name, UUID, m_callbackURI);
  3400. UUID originID;
  3401. lock (m_originRegionIDAccessLock)
  3402. originID = m_originRegionID;
  3403. Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
  3404. m_callbackURI = null;
  3405. }
  3406. // v0.7 close HG sender region
  3407. else if (!string.IsNullOrEmpty(m_newCallbackURI))
  3408. {
  3409. m_log.DebugFormat(
  3410. "[SCENE PRESENCE({0})]: Releasing {1} {2} with callback to {3}",
  3411. Scene.RegionInfo.RegionName, Name, UUID, m_newCallbackURI);
  3412. UUID originID;
  3413. lock (m_originRegionIDAccessLock)
  3414. originID = m_originRegionID;
  3415. Scene.SimulationService.ReleaseAgent(originID, UUID, m_newCallbackURI);
  3416. m_newCallbackURI = null;
  3417. }
  3418. IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
  3419. m_agentTransfer?.CloseOldChildAgents(this);
  3420. }
  3421. uint flags = ControllingClient.GetViewerCaps();
  3422. if ((flags & (uint)(ViewerFlags.TPBR | ViewerFlags.SentTPBR)) == (uint)ViewerFlags.TPBR)
  3423. ControllingClient.SendRegionHandshake();
  3424. m_log.DebugFormat("[SCENE PRESENCE({0})]: SendInitialData for {1}", m_scene.RegionInfo.RegionName, UUID);
  3425. if (m_teleportFlags <= 0)
  3426. {
  3427. m_scene.SendLayerData(ControllingClient);
  3428. ILandChannel landch = m_scene.LandChannel;
  3429. landch?.sendClientInitialLandInfo(ControllingClient, true);
  3430. }
  3431. m_log.DebugFormat("[SCENE PRESENCE({0})]: SendInitialData at parcel {1}", m_scene.RegionInfo.RegionName, currentParcelUUID);
  3432. SendOtherAgentsAvatarFullToMe();
  3433. if (m_scene.ObjectsCullingByDistance)
  3434. {
  3435. m_reprioritizationBusy = true;
  3436. m_reprioritizationLastPosition = AbsolutePosition;
  3437. m_reprioritizationLastDrawDistance = DrawDistance;
  3438. ControllingClient.ReprioritizeUpdates();
  3439. m_reprioritizationLastTime = Util.EnvironmentTickCount();
  3440. m_reprioritizationBusy = false;
  3441. }
  3442. else
  3443. {
  3444. //bool cacheCulling = (flags & 1) != 0;
  3445. bool cacheEmpty = (flags & 2) != 0;
  3446. EntityBase[] entities = Scene.Entities.GetEntities();
  3447. if(cacheEmpty)
  3448. {
  3449. foreach (EntityBase e in entities)
  3450. {
  3451. if (e is SceneObjectGroup sog && !sog.IsAttachment)
  3452. sog.SendFullAnimUpdateToClient(ControllingClient);
  3453. }
  3454. }
  3455. else
  3456. {
  3457. foreach (EntityBase e in entities)
  3458. {
  3459. if (e is SceneObjectGroup grp && !grp.IsAttachment)
  3460. {
  3461. if(grp.IsViewerCachable)
  3462. grp.SendUpdateProbes(ControllingClient);
  3463. else
  3464. grp.SendFullAnimUpdateToClient(ControllingClient);
  3465. }
  3466. }
  3467. }
  3468. m_reprioritizationLastPosition = AbsolutePosition;
  3469. m_reprioritizationLastDrawDistance = DrawDistance;
  3470. m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it
  3471. m_reprioritizationBusy = false;
  3472. }
  3473. if (!IsChildAgent)
  3474. {
  3475. // Create child agents in neighbouring regions
  3476. IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
  3477. m_agentTransfer?.EnableChildAgents(this);
  3478. m_lastChildUpdatesTime = Util.EnvironmentTickCount() + 10000;
  3479. m_lastChildAgentUpdatePosition = AbsolutePosition;
  3480. m_lastChildAgentCheckPosition = m_lastChildAgentUpdatePosition;
  3481. m_lastChildAgentUpdateDrawDistance = DrawDistance;
  3482. m_lastRegionsDrawDistance = RegionViewDistance;
  3483. m_lastChildAgentUpdateGodLevel = GodController.ViwerUIGodLevel;
  3484. m_childUpdatesBusy = false; // allow them
  3485. }
  3486. });
  3487. }
  3488. /// <summary>
  3489. /// Send avatar full data appearance and animations for all other root agents to this agent, this agent
  3490. /// can be either a child or root
  3491. /// </summary>
  3492. public void SendOtherAgentsAvatarFullToMe()
  3493. {
  3494. int count = 0;
  3495. m_scene.ForEachRootScenePresence(delegate(ScenePresence p)
  3496. {
  3497. // only send information about other root agents
  3498. if (p.UUID.Equals(UUID))
  3499. return;
  3500. // get the avatar, then a kill if can't see it
  3501. p.SendInitialAvatarDataToAgent(this);
  3502. if (p.ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !IsViewerUIGod)
  3503. return;
  3504. p.SendAppearanceToAgentNF(this);
  3505. p.SendAnimPackToAgentNF(this);
  3506. p.SendAttachmentsToAgentNF(this);
  3507. count++;
  3508. });
  3509. m_scene.StatsReporter.AddAgentUpdates(count);
  3510. }
  3511. /// <summary>
  3512. /// Send this agent's avatar data to all other root and child agents in the scene
  3513. /// This agent must be root. This avatar will receive its own update.
  3514. /// </summary>
  3515. public void SendAvatarDataToAllAgents()
  3516. {
  3517. //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAllAgents: {0} ({1})", Name, UUID);
  3518. // only send update from root agents to other clients; children are only "listening posts"
  3519. if (IsChildAgent)
  3520. return;
  3521. m_lastSize = Appearance.AvatarSize;
  3522. int count = 0;
  3523. m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
  3524. {
  3525. SendAvatarDataToAgent(scenePresence);
  3526. count++;
  3527. });
  3528. m_scene.StatsReporter.AddAgentUpdates(count);
  3529. }
  3530. // sends avatar object to all clients so they cross it into region
  3531. // then sends kills to hide
  3532. public void SendInitialAvatarDataToAllAgents(List<ScenePresence> presences)
  3533. {
  3534. m_lastSize = Appearance.AvatarSize;
  3535. int count = 0;
  3536. SceneObjectPart sitroot = null;
  3537. if (ParentID != 0 && ParentPart != null) // we need to send the sitting root prim
  3538. {
  3539. sitroot = ParentPart.ParentGroup.RootPart;
  3540. }
  3541. foreach (ScenePresence p in presences)
  3542. {
  3543. if(p.IsDeleted || p.IsNPC)
  3544. continue;
  3545. if (sitroot != null) // we need to send the sitting root prim
  3546. {
  3547. p.ControllingClient.SendEntityFullUpdateImmediate(ParentPart.ParentGroup.RootPart);
  3548. }
  3549. p.ControllingClient.SendEntityFullUpdateImmediate(this);
  3550. if (p != this && ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  3551. // either just kill the object
  3552. // p.ControllingClient.SendKillObject(new List<uint> {LocalId});
  3553. // or also attachments viewer may still know about
  3554. SendKillTo(p);
  3555. count++;
  3556. }
  3557. m_scene.StatsReporter.AddAgentUpdates(count);
  3558. }
  3559. public void SendInitialAvatarDataToAgent(ScenePresence p)
  3560. {
  3561. if(ParentID != 0 && ParentPart != null) // we need to send the sitting root prim
  3562. {
  3563. p.ControllingClient.SendEntityFullUpdateImmediate(ParentPart.ParentGroup.RootPart);
  3564. }
  3565. p.ControllingClient.SendEntityFullUpdateImmediate(this);
  3566. if (p != this && ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  3567. // either just kill the object
  3568. // p.ControllingClient.SendKillObject(new List<uint> {LocalId});
  3569. // or also attachments viewer may still know about
  3570. SendKillTo(p);
  3571. }
  3572. /// <summary>
  3573. /// Send avatar data to an agent.
  3574. /// </summary>
  3575. /// <param name="avatar"></param>
  3576. public void SendAvatarDataToAgent(ScenePresence avatar)
  3577. {
  3578. //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID);
  3579. if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && !avatar.IsViewerUIGod)
  3580. return;
  3581. avatar.ControllingClient.SendEntityFullUpdateImmediate(this);
  3582. }
  3583. public void SendAvatarDataToAgentNF(ScenePresence avatar)
  3584. {
  3585. avatar.ControllingClient.SendEntityFullUpdateImmediate(this);
  3586. }
  3587. /// <summary>
  3588. /// Send this agent's appearance to all other root and child agents in the scene
  3589. /// This agent must be root.
  3590. /// </summary>
  3591. public void SendAppearanceToAllOtherAgents()
  3592. {
  3593. //m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} {1}", Name, UUID);
  3594. // only send update from root agents to other clients; children are only "listening posts"
  3595. if (IsChildAgent)
  3596. return;
  3597. int count = 0;
  3598. m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
  3599. {
  3600. if(scenePresence.IsNPC)
  3601. return;
  3602. // only send information to other root agents
  3603. if (scenePresence.m_localId == m_localId)
  3604. return;
  3605. SendAppearanceToAgent(scenePresence);
  3606. count++;
  3607. });
  3608. m_scene.StatsReporter.AddAgentUpdates(count);
  3609. }
  3610. public void SendAppearanceToAgent(ScenePresence avatar)
  3611. {
  3612. // m_log.DebugFormat(
  3613. // "[SCENE PRESENCE]: Sending appearance data from {0} {1} to {2} {3}", Name, m_uuid, avatar.Name, avatar.UUID);
  3614. if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && !avatar.IsViewerUIGod)
  3615. return;
  3616. SendAppearanceToAgentNF(avatar);
  3617. }
  3618. public void SendAppearanceToAgentNF(ScenePresence avatar)
  3619. {
  3620. avatar.ControllingClient.SendAppearance(UUID, Appearance.VisualParams, Appearance.Texture.GetBakesBytes(), Appearance.AvatarPreferencesHoverZ);
  3621. }
  3622. public void SendAnimPackToAgent(ScenePresence p)
  3623. {
  3624. if (IsChildAgent || Animator == null)
  3625. return;
  3626. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  3627. return;
  3628. Animator.SendAnimPackToClient(p.ControllingClient);
  3629. }
  3630. public void SendAnimPackToAgent(ScenePresence p, UUID[] animations, int[] seqs, UUID[] objectIDs)
  3631. {
  3632. if (IsChildAgent)
  3633. return;
  3634. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  3635. return;
  3636. p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
  3637. }
  3638. public void SendAnimPackToAgentNF(ScenePresence p)
  3639. {
  3640. if (IsChildAgent || Animator == null)
  3641. return;
  3642. Animator.SendAnimPackToClient(p.ControllingClient);
  3643. }
  3644. public void SendAnimPackToAgentNF(ScenePresence p, UUID[] animations, int[] seqs, UUID[] objectIDs)
  3645. {
  3646. p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
  3647. }
  3648. public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
  3649. {
  3650. if (IsChildAgent)
  3651. return;
  3652. m_scene.ForEachScenePresence(delegate (ScenePresence p)
  3653. {
  3654. if (p.IsNPC)
  3655. return;
  3656. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  3657. return;
  3658. p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
  3659. });
  3660. }
  3661. public void SendAnimPackToOthers(UUID[] animations, int[] seqs, UUID[] objectIDs)
  3662. {
  3663. if (IsChildAgent)
  3664. return;
  3665. m_scene.ForEachScenePresence(delegate (ScenePresence p)
  3666. {
  3667. if (p.IsNPC)
  3668. return;
  3669. if (p.LocalId == LocalId)
  3670. return;
  3671. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  3672. return;
  3673. p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs);
  3674. });
  3675. }
  3676. #endregion
  3677. #region Significant Movement Method
  3678. private void checkRePrioritization()
  3679. {
  3680. if(IsDeleted || !ControllingClient.IsActive)
  3681. return;
  3682. if(m_reprioritizationBusy)
  3683. return;
  3684. float limit = Scene.ReprioritizationDistance;
  3685. bool byDrawdistance = Scene.ObjectsCullingByDistance;
  3686. if(byDrawdistance)
  3687. {
  3688. float minregionSize = Scene.RegionInfo.RegionSizeX;
  3689. if(minregionSize > Scene.RegionInfo.RegionSizeY)
  3690. minregionSize = Scene.RegionInfo.RegionSizeY;
  3691. minregionSize *= 0.5f;
  3692. if(DrawDistance > minregionSize && m_reprioritizationLastDrawDistance > minregionSize)
  3693. byDrawdistance = false;
  3694. else
  3695. byDrawdistance = (Math.Abs(DrawDistance - m_reprioritizationLastDrawDistance) > 0.5f * limit);
  3696. }
  3697. int tdiff = Util.EnvironmentTickCountSubtract(m_reprioritizationLastTime);
  3698. if(!byDrawdistance && tdiff < Scene.ReprioritizationInterval)
  3699. return;
  3700. // priority uses avatar position
  3701. Vector3 pos = AbsolutePosition;
  3702. Vector3 diff = pos - m_reprioritizationLastPosition;
  3703. limit *= limit;
  3704. if (!byDrawdistance && diff.LengthSquared() < limit)
  3705. return;
  3706. m_reprioritizationBusy = true;
  3707. m_reprioritizationLastPosition = pos;
  3708. m_reprioritizationLastDrawDistance = DrawDistance;
  3709. Util.FireAndForget(
  3710. o =>
  3711. {
  3712. ControllingClient.ReprioritizeUpdates();
  3713. m_reprioritizationLastTime = Util.EnvironmentTickCount();
  3714. m_reprioritizationBusy = false;
  3715. }, null, "ScenePresence.Reprioritization");
  3716. }
  3717. /// <summary>
  3718. /// This checks for a significant movement and sends a coarselocationchange update
  3719. /// </summary>
  3720. protected void CheckForSignificantMovement()
  3721. {
  3722. Vector3 pos = AbsolutePosition;
  3723. Vector3 diff = pos - posLastMove;
  3724. if (diff.LengthSquared() > MOVEMENT)
  3725. {
  3726. posLastMove = pos;
  3727. m_scene.EventManager.TriggerOnClientMovement(this);
  3728. }
  3729. diff = pos - posLastSignificantMove;
  3730. if (diff.LengthSquared() > SIGNIFICANT_MOVEMENT)
  3731. {
  3732. posLastSignificantMove = pos;
  3733. m_scene.EventManager.TriggerSignificantClientMovement(this);
  3734. }
  3735. if(IsNPC)
  3736. return;
  3737. // updates priority recalc
  3738. checkRePrioritization();
  3739. if(m_childUpdatesBusy || RegionViewDistance == 0)
  3740. return;
  3741. int tdiff = Util.EnvironmentTickCountSubtract(m_lastChildUpdatesTime);
  3742. if (tdiff < CHILDUPDATES_TIME)
  3743. return;
  3744. bool viewchanged = Math.Abs(RegionViewDistance - m_lastRegionsDrawDistance) > 32.0f;
  3745. IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
  3746. float dx = pos.X - m_lastChildAgentCheckPosition.X;
  3747. float dy = pos.Y - m_lastChildAgentCheckPosition.Y;
  3748. if ((m_agentTransfer != null) && (viewchanged || ((dx * dx + dy * dy) > CHILDAGENTSCHECK_MOVEMENT)))
  3749. {
  3750. m_childUpdatesBusy = true;
  3751. m_lastChildAgentCheckPosition = pos;
  3752. m_lastChildAgentUpdatePosition = pos;
  3753. m_lastChildAgentUpdateGodLevel = GodController.ViwerUIGodLevel;
  3754. m_lastChildAgentUpdateDrawDistance = DrawDistance;
  3755. m_lastRegionsDrawDistance = RegionViewDistance;
  3756. // m_lastChildAgentUpdateCamPosition = CameraPosition;
  3757. Util.FireAndForget(
  3758. o =>
  3759. {
  3760. m_agentTransfer.EnableChildAgents(this);
  3761. m_lastChildUpdatesTime = Util.EnvironmentTickCount();
  3762. m_childUpdatesBusy = false;
  3763. }, null, "ScenePresence.CheckChildAgents");
  3764. }
  3765. else
  3766. {
  3767. //possible KnownRegionHandles always contains current region and this check is not needed
  3768. int minhandles = KnownRegionHandles.Contains(RegionHandle) ? 1 : 0;
  3769. if(KnownRegionHandles.Count > minhandles)
  3770. {
  3771. bool doUpdate = false;
  3772. if (m_lastChildAgentUpdateGodLevel != GodController.ViwerUIGodLevel)
  3773. doUpdate = true;
  3774. if (Math.Abs(DrawDistance - m_lastChildAgentUpdateDrawDistance) > 32.0f)
  3775. doUpdate = true;
  3776. if(!doUpdate)
  3777. {
  3778. diff = pos - m_lastChildAgentUpdatePosition;
  3779. if (diff.LengthSquared() > CHILDUPDATES_MOVEMENT)
  3780. doUpdate = true;
  3781. }
  3782. if (doUpdate)
  3783. {
  3784. m_childUpdatesBusy = true;
  3785. m_lastChildAgentUpdatePosition = pos;
  3786. m_lastChildAgentUpdateGodLevel = GodController.ViwerUIGodLevel;
  3787. m_lastChildAgentUpdateDrawDistance = DrawDistance;
  3788. // m_lastChildAgentUpdateCamPosition = CameraPosition;
  3789. AgentPosition agentpos = new()
  3790. {
  3791. AgentID = UUID,
  3792. SessionID = ControllingClient.SessionId,
  3793. Size = Appearance.AvatarSize,
  3794. Center = CameraPosition,
  3795. Far = DrawDistance,
  3796. Position = AbsolutePosition,
  3797. Velocity = Velocity,
  3798. RegionHandle = RegionHandle,
  3799. GodData = GodController.State(),
  3800. Throttles = ControllingClient.GetThrottlesPacked(1)
  3801. };
  3802. // Let's get this out of the update loop
  3803. Util.FireAndForget(
  3804. o =>
  3805. {
  3806. m_scene.SendOutChildAgentUpdates(agentpos, this);
  3807. m_lastChildUpdatesTime = Util.EnvironmentTickCount();
  3808. m_childUpdatesBusy = false;
  3809. }, null, "ScenePresence.SendOutChildAgentUpdates");
  3810. }
  3811. }
  3812. }
  3813. }
  3814. #endregion
  3815. #region Border Crossing Methods
  3816. /// <summary>
  3817. /// Starts the process of moving an avatar into another region if they are crossing the border.
  3818. /// </summary>
  3819. /// <remarks>
  3820. /// Also removes the avatar from the physical scene if transit has started.
  3821. /// </remarks>
  3822. protected void CheckForBorderCrossing()
  3823. {
  3824. // Check that we we are not a child
  3825. if (IsChildAgent || IsInTransit)
  3826. return;
  3827. // If we don't have a PhysActor, we can't cross anyway
  3828. // Also don't do this while sat, sitting avatars cross with the
  3829. // object they sit on. ParentUUID denoted a pending sit, don't
  3830. // interfere with it.
  3831. if (ParentID != 0 || PhysicsActor == null || ParentUUID.IsNotZero())
  3832. return;
  3833. Vector3 pos2 = AbsolutePosition;
  3834. Vector3 vel = Velocity;
  3835. RegionInfo rinfo = m_scene.RegionInfo;
  3836. float timeStep = m_scene.FrameTime;
  3837. float t = pos2.X + vel.X * timeStep;
  3838. if (t >= 0 && t < rinfo.RegionSizeX)
  3839. {
  3840. t = pos2.Y + vel.Y * timeStep;
  3841. if (t >= 0 && t < rinfo.RegionSizeY)
  3842. return;
  3843. }
  3844. //m_log.DebugFormat(
  3845. // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}",
  3846. // pos2, Name, Scene.Name);
  3847. if (!CrossToNewRegion() && m_requestedSitTargetID == 0)
  3848. {
  3849. // we don't have entity transfer module
  3850. Vector3 pos = AbsolutePosition;
  3851. vel = Velocity;
  3852. float px = pos.X;
  3853. if (px < 0)
  3854. pos.X += vel.X * 2;
  3855. else if (px > rinfo.RegionSizeX)
  3856. pos.X -= vel.X * 2;
  3857. float py = pos.Y;
  3858. if (py < 0)
  3859. pos.Y += vel.Y * 2;
  3860. else if (py > rinfo.RegionSizeY)
  3861. pos.Y -= vel.Y * 2;
  3862. Velocity = Vector3.Zero;
  3863. m_AngularVelocity = Vector3.Zero;
  3864. AbsolutePosition = pos;
  3865. }
  3866. }
  3867. public void CrossToNewRegionFail()
  3868. {
  3869. if (m_requestedSitTargetID == 0)
  3870. {
  3871. bool isFlying = Flying;
  3872. RemoveFromPhysicalScene();
  3873. Vector3 pos = AbsolutePosition;
  3874. Vector3 vel = Velocity;
  3875. float px = pos.X;
  3876. if (px < 0)
  3877. pos.X += vel.X * 2;
  3878. else if (px > m_scene.RegionInfo.RegionSizeX)
  3879. pos.X -= vel.X * 2;
  3880. float py = pos.Y;
  3881. if (py < 0)
  3882. pos.Y += vel.Y * 2;
  3883. else if (py > m_scene.RegionInfo.RegionSizeY)
  3884. pos.Y -= vel.Y * 2;
  3885. Velocity = Vector3.Zero;
  3886. m_AngularVelocity = Vector3.Zero;
  3887. AbsolutePosition = pos;
  3888. AddToPhysicalScene(isFlying);
  3889. }
  3890. }
  3891. /// <summary>
  3892. /// Moves the agent outside the region bounds
  3893. /// Tells neighbor region that we're crossing to it
  3894. /// If the neighbor accepts, remove the agent's viewable avatar from this scene
  3895. /// set them to a child agent.
  3896. /// </summary>
  3897. protected bool CrossToNewRegion()
  3898. {
  3899. try
  3900. {
  3901. return m_scene.CrossAgentToNewRegion(this, Flying);
  3902. }
  3903. catch
  3904. {
  3905. // result = m_scene.CrossAgentToNewRegion(this, false);
  3906. return false;
  3907. }
  3908. }
  3909. /// <summary>
  3910. /// Computes which child agents to close when the scene presence moves to another region.
  3911. /// Removes those regions from m_knownRegions.
  3912. /// </summary>
  3913. /// <param name="newRegionHandle">The new region's handle</param>
  3914. /// <param name="newRegionSizeX">The new region's size x</param>
  3915. /// <param name="newRegionSizeY">The new region's size y</param>
  3916. /// <returns></returns>
  3917. public List<ulong> GetChildAgentsToClose(ulong newRegionHandle, int newRegionSizeX, int newRegionSizeY)
  3918. {
  3919. ulong curRegionHandle = m_scene.RegionInfo.RegionHandle;
  3920. List<ulong> byebyeRegions = new();
  3921. if(newRegionHandle == curRegionHandle) //??
  3922. return byebyeRegions;
  3923. List<ulong> knownRegions = KnownRegionHandles;
  3924. m_log.DebugFormat(
  3925. "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}",
  3926. knownRegions.Count, Scene.RegionInfo.RegionName);
  3927. Util.RegionHandleToRegionLoc(newRegionHandle, out uint newRegionX, out uint newRegionY);
  3928. foreach (ulong handle in knownRegions)
  3929. {
  3930. if(newRegionY == 0) // HG
  3931. byebyeRegions.Add(handle);
  3932. else if(handle == curRegionHandle)
  3933. {
  3934. continue;
  3935. /*
  3936. RegionInfo curreg = m_scene.RegionInfo;
  3937. if (Util.IsOutsideView(255, curreg.RegionLocX, newRegionX, curreg.RegionLocY, newRegionY,
  3938. (int)curreg.RegionSizeX, (int)curreg.RegionSizeX, newRegionSizeX, newRegionSizeY))
  3939. {
  3940. byebyeRegions.Add(handle);
  3941. }
  3942. */
  3943. }
  3944. else
  3945. {
  3946. Util.RegionHandleToRegionLoc(handle, out uint x, out uint y);
  3947. if (m_knownChildRegionsSizeInfo.TryGetValue(handle, out spRegionSizeInfo regInfo))
  3948. {
  3949. // if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY,
  3950. // for now need to close all but first order bc RegionViewDistance it the target value not ours
  3951. if (Util.IsOutsideView(255, x, newRegionX, y, newRegionY,
  3952. regInfo.sizeX, regInfo.sizeY, newRegionSizeX, newRegionSizeY))
  3953. {
  3954. byebyeRegions.Add(handle);
  3955. }
  3956. }
  3957. else
  3958. {
  3959. // if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY,
  3960. if (Util.IsOutsideView(255, x, newRegionX, y, newRegionY,
  3961. (int)Constants.RegionSize, (int)Constants.RegionSize, newRegionSizeX, newRegionSizeY))
  3962. {
  3963. byebyeRegions.Add(handle);
  3964. }
  3965. }
  3966. }
  3967. }
  3968. return byebyeRegions;
  3969. }
  3970. public void CloseChildAgents(List<ulong> byebyeRegions)
  3971. {
  3972. byebyeRegions.Remove(Scene.RegionInfo.RegionHandle);
  3973. if (byebyeRegions.Count > 0)
  3974. {
  3975. m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
  3976. AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID);
  3977. string auth = string.Empty;
  3978. if (acd != null)
  3979. auth = acd.SessionID.ToString();
  3980. m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
  3981. }
  3982. foreach (ulong handle in byebyeRegions)
  3983. {
  3984. RemoveNeighbourRegion(handle);
  3985. Scene.CapsModule.DropChildSeed(UUID, handle);
  3986. }
  3987. }
  3988. public void closeAllChildAgents()
  3989. {
  3990. List<ulong> byebyeRegions = new();
  3991. List<ulong> knownRegions = KnownRegionHandles;
  3992. foreach (ulong handle in knownRegions)
  3993. {
  3994. if (handle != Scene.RegionInfo.RegionHandle)
  3995. {
  3996. byebyeRegions.Add(handle);
  3997. RemoveNeighbourRegion(handle);
  3998. Scene.CapsModule.DropChildSeed(UUID, handle);
  3999. }
  4000. }
  4001. if (byebyeRegions.Count > 0)
  4002. {
  4003. m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
  4004. AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID);
  4005. string auth = string.Empty;
  4006. if (acd != null)
  4007. auth = acd.SessionID.ToString();
  4008. m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
  4009. }
  4010. }
  4011. #endregion
  4012. /// <summary>
  4013. /// handle god level requests.
  4014. /// </summary>
  4015. public void GrantGodlikePowers(UUID token, bool godStatus)
  4016. {
  4017. if (IsNPC)
  4018. return;
  4019. bool wasgod = IsViewerUIGod;
  4020. GodController.RequestGodMode(godStatus);
  4021. if (wasgod != IsViewerUIGod)
  4022. parcelGodCheck(m_currentParcelUUID);
  4023. }
  4024. #region Child Agent Updates
  4025. public void UpdateChildAgent(AgentData cAgentData)
  4026. {
  4027. // m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
  4028. if (!IsChildAgent)
  4029. return;
  4030. CopyFrom(cAgentData);
  4031. m_updateAgentReceivedAfterTransferEvent.Set();
  4032. }
  4033. private static Vector3 marker = new(-1f, -1f, -1f);
  4034. /// <summary>
  4035. /// This updates important decision making data about a child agent
  4036. /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
  4037. /// </summary>
  4038. public void UpdateChildAgent(AgentPosition cAgentData)
  4039. {
  4040. if (!IsChildAgent)
  4041. return;
  4042. GodController.SetState(cAgentData.GodData);
  4043. RegionHandle = cAgentData.RegionHandle;
  4044. uint rRegionX = (uint)(RegionHandle >> 40);
  4045. uint rRegionY = (((uint)RegionHandle) >> 8);
  4046. uint tRegionX = m_scene.RegionInfo.RegionLocX;
  4047. uint tRegionY = m_scene.RegionInfo.RegionLocY;
  4048. //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY);
  4049. int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize;
  4050. int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize;
  4051. Vector3 offset = new(shiftx, shifty, 0f);
  4052. m_pos = cAgentData.Position + offset;
  4053. CameraPosition = cAgentData.Center + offset;
  4054. DrawDistance = cAgentData.Far;
  4055. if (cAgentData.ChildrenCapSeeds is not null && cAgentData.ChildrenCapSeeds.Count > 0)
  4056. {
  4057. Scene.CapsModule?.SetChildrenSeed(UUID, cAgentData.ChildrenCapSeeds);
  4058. KnownRegions = cAgentData.ChildrenCapSeeds;
  4059. }
  4060. if ((cAgentData.Throttles is not null) && cAgentData.Throttles.Length > 0)
  4061. {
  4062. // some scaling factor
  4063. float x = m_pos.X;
  4064. if (x > m_scene.RegionInfo.RegionSizeX)
  4065. x -= m_scene.RegionInfo.RegionSizeX;
  4066. float y = m_pos.Y;
  4067. if (y > m_scene.RegionInfo.RegionSizeY)
  4068. y -= m_scene.RegionInfo.RegionSizeY;
  4069. x = x * x + y * y;
  4070. float factor = 1.0f - x * 0.3f / Constants.RegionSize / Constants.RegionSize;
  4071. if (factor < 0.2f)
  4072. factor = 0.2f;
  4073. ControllingClient.SetChildAgentThrottle(cAgentData.Throttles,factor);
  4074. }
  4075. //cAgentData.AVHeight;
  4076. //m_velocity = cAgentData.Velocity;
  4077. checkRePrioritization();
  4078. }
  4079. public void CopyTo(AgentData cAgent, bool isCrossUpdate)
  4080. {
  4081. cAgent.CallbackURI = m_callbackURI;
  4082. cAgent.NewCallbackURI = m_newCallbackURI;
  4083. cAgent.AgentID = UUID;
  4084. cAgent.RegionID = Scene.RegionInfo.RegionID;
  4085. cAgent.SessionID = ControllingClient.SessionId;
  4086. cAgent.Position = AbsolutePosition;
  4087. cAgent.Velocity = m_velocity;
  4088. cAgent.Center = CameraPosition;
  4089. cAgent.AtAxis = CameraAtAxis;
  4090. cAgent.LeftAxis = CameraLeftAxis;
  4091. cAgent.UpAxis = CameraUpAxis;
  4092. cAgent.Far = DrawDistance;
  4093. cAgent.GodData = GodController.State();
  4094. // Throttles
  4095. cAgent.Throttles = ControllingClient.GetThrottlesPacked(1);
  4096. cAgent.HeadRotation = m_headrotation;
  4097. cAgent.BodyRotation = Rotation;
  4098. cAgent.ControlFlags = (uint)m_AgentControlFlags;
  4099. cAgent.AlwaysRun = SetAlwaysRun;
  4100. // make clear we want the all thing
  4101. cAgent.Appearance = new AvatarAppearance(Appearance,true,true);
  4102. cAgent.ParentPart = ParentUUID;
  4103. cAgent.SitOffset = PrevSitOffset;
  4104. lock (scriptedcontrols)
  4105. {
  4106. ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
  4107. int i = 0;
  4108. foreach (ScriptControllers c in scriptedcontrols.Values)
  4109. {
  4110. controls[i++] = new ControllerData(c.objectID, c.itemID, (uint)c.ignoreControls, (uint)c.eventControls);
  4111. }
  4112. cAgent.Controllers = controls;
  4113. }
  4114. // Animations
  4115. try
  4116. {
  4117. cAgent.Anims = Animator.Animations.ToArray();
  4118. }
  4119. catch { }
  4120. cAgent.DefaultAnim = Animator.Animations.DefaultAnimation;
  4121. cAgent.AnimState = Animator.Animations.ImplicitDefaultAnimation;
  4122. cAgent.MovementAnimationOverRides = Overrides.CloneAOPairs();
  4123. cAgent.MotionState = (byte)Animator.currentControlState;
  4124. Scene.AttachmentsModule?.CopyAttachments(this, cAgent);
  4125. if(isCrossUpdate)
  4126. {
  4127. cAgent.CrossingFlags = m_crossingFlags;
  4128. cAgent.CrossingFlags |= 1;
  4129. cAgent.CrossExtraFlags = 0;
  4130. if((LastCommands & ScriptControlled.CONTROL_LBUTTON) != 0)
  4131. cAgent.CrossExtraFlags |= 1;
  4132. if((LastCommands & ScriptControlled.CONTROL_ML_LBUTTON) != 0)
  4133. cAgent.CrossExtraFlags |= 2;
  4134. }
  4135. else
  4136. cAgent.CrossingFlags = 0;
  4137. if(isCrossUpdate)
  4138. {
  4139. //cAgent.agentCOF = COF;
  4140. cAgent.ActiveGroupID = ControllingClient.ActiveGroupId;
  4141. cAgent.ActiveGroupName = ControllingClient.ActiveGroupName;
  4142. if(Grouptitle == null)
  4143. cAgent.ActiveGroupTitle = String.Empty;
  4144. else
  4145. cAgent.ActiveGroupTitle = Grouptitle;
  4146. }
  4147. IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
  4148. if (friendsModule != null)
  4149. {
  4150. cAgent.CachedFriendsOnline = friendsModule.GetCachedFriendsOnline(UUID);
  4151. }
  4152. }
  4153. private void CopyFrom(AgentData cAgent)
  4154. {
  4155. m_callbackURI = cAgent.CallbackURI;
  4156. m_newCallbackURI = cAgent.NewCallbackURI;
  4157. //m_log.DebugFormat(
  4158. // "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
  4159. // Name, m_scene.RegionInfo.RegionName, m_callbackURI);
  4160. GodController.SetState(cAgent.GodData);
  4161. m_pos = cAgent.Position;
  4162. m_velocity = cAgent.Velocity;
  4163. CameraPosition = cAgent.Center;
  4164. CameraAtAxis = cAgent.AtAxis;
  4165. CameraLeftAxis = cAgent.LeftAxis;
  4166. CameraUpAxis = cAgent.UpAxis;
  4167. Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis);
  4168. CameraRotation = camRot;
  4169. ParentUUID = cAgent.ParentPart;
  4170. PrevSitOffset = cAgent.SitOffset;
  4171. // When we get to the point of re-computing neighbors everytime this
  4172. // changes, then start using the agent's drawdistance rather than the
  4173. // region's draw distance.
  4174. DrawDistance = cAgent.Far;
  4175. //DrawDistance = Scene.DefaultDrawDistance;
  4176. if (cAgent.ChildrenCapSeeds != null && cAgent.ChildrenCapSeeds.Count > 0)
  4177. {
  4178. Scene.CapsModule?.SetChildrenSeed(UUID, cAgent.ChildrenCapSeeds);
  4179. KnownRegions = cAgent.ChildrenCapSeeds;
  4180. }
  4181. if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
  4182. ControllingClient.SetChildAgentThrottle(cAgent.Throttles, 1.0f);
  4183. m_headrotation = cAgent.HeadRotation;
  4184. Rotation = cAgent.BodyRotation;
  4185. m_AgentControlFlags = (ACFlags)cAgent.ControlFlags;
  4186. SetAlwaysRun = cAgent.AlwaysRun;
  4187. Appearance = new AvatarAppearance(cAgent.Appearance, true, true);
  4188. /*
  4189. bool isFlying = ((m_AgentControlFlags & ACFlags.AGENT_CONTROL_FLY) != 0);
  4190. if (PhysicsActor != null)
  4191. {
  4192. RemoveFromPhysicalScene();
  4193. AddToPhysicalScene(isFlying);
  4194. }
  4195. */
  4196. Scene.AttachmentsModule?.CopyAttachments(cAgent, this);
  4197. try
  4198. {
  4199. lock (scriptedcontrols)
  4200. {
  4201. if (cAgent.Controllers != null)
  4202. {
  4203. scriptedcontrols.Clear();
  4204. IgnoredControls = ScriptControlled.CONTROL_ZERO;
  4205. foreach (ControllerData c in cAgent.Controllers)
  4206. {
  4207. ScriptControllers sc = new()
  4208. {
  4209. objectID = c.ObjectID,
  4210. itemID = c.ItemID,
  4211. ignoreControls = (ScriptControlled)c.IgnoreControls,
  4212. eventControls = (ScriptControlled)c.EventControls
  4213. };
  4214. scriptedcontrols[sc.itemID] = sc;
  4215. IgnoredControls |= sc.ignoreControls; // this is not correct, aparently only last applied should count
  4216. }
  4217. }
  4218. }
  4219. }
  4220. catch { }
  4221. // we are losing animator somewhere
  4222. if (Animator == null)
  4223. Animator = new ScenePresenceAnimator(this);
  4224. else
  4225. Animator.ResetAnimations();
  4226. Overrides.CopyAOPairsFrom(cAgent.MovementAnimationOverRides);
  4227. int nanim = ControllingClient.NextAnimationSequenceNumber;
  4228. // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object?
  4229. if (cAgent.DefaultAnim != null)
  4230. {
  4231. if (cAgent.DefaultAnim.SequenceNum > nanim)
  4232. nanim = cAgent.DefaultAnim.SequenceNum;
  4233. Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
  4234. }
  4235. if (cAgent.AnimState != null)
  4236. {
  4237. if (cAgent.AnimState.SequenceNum > nanim)
  4238. nanim = cAgent.AnimState.SequenceNum;
  4239. Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
  4240. }
  4241. if (cAgent.Anims != null)
  4242. {
  4243. int canim = Animator.Animations.FromArray(cAgent.Anims);
  4244. if(canim > nanim)
  4245. nanim = canim;
  4246. }
  4247. ControllingClient.NextAnimationSequenceNumber = ++nanim;
  4248. if (cAgent.MotionState != 0)
  4249. Animator.currentControlState = (ScenePresenceAnimator.motionControlStates) cAgent.MotionState;
  4250. m_crossingFlags = cAgent.CrossingFlags;
  4251. m_gotCrossUpdate = (m_crossingFlags != 0);
  4252. if(m_gotCrossUpdate)
  4253. {
  4254. LastCommands &= ~(ScriptControlled.CONTROL_LBUTTON | ScriptControlled.CONTROL_ML_LBUTTON);
  4255. if((cAgent.CrossExtraFlags & 1) != 0)
  4256. LastCommands |= ScriptControlled.CONTROL_LBUTTON;
  4257. if((cAgent.CrossExtraFlags & 2) != 0)
  4258. LastCommands |= ScriptControlled.CONTROL_ML_LBUTTON;
  4259. MouseDown = (cAgent.CrossExtraFlags & 3) != 0;
  4260. }
  4261. m_haveGroupInformation = false;
  4262. // using this as protocol detection don't want to mess with the numbers for now
  4263. if(cAgent.ActiveGroupTitle != null)
  4264. {
  4265. m_haveGroupInformation = true;
  4266. //COF = cAgent.agentCOF;
  4267. if(ControllingClient.IsGroupMember(cAgent.ActiveGroupID))
  4268. {
  4269. ControllingClient.ActiveGroupId = cAgent.ActiveGroupID;
  4270. ControllingClient.ActiveGroupName = cAgent.ActiveGroupName;
  4271. Grouptitle = cAgent.ActiveGroupTitle;
  4272. ControllingClient.ActiveGroupPowers =
  4273. ControllingClient.GetGroupPowers(cAgent.ActiveGroupID);
  4274. }
  4275. else
  4276. {
  4277. // we got a unknown active group so get what groups thinks about us
  4278. IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
  4279. gm?.SendAgentGroupDataUpdate(ControllingClient);
  4280. }
  4281. }
  4282. lock (m_originRegionIDAccessLock)
  4283. m_originRegionID = cAgent.RegionID;
  4284. if (cAgent.CachedFriendsOnline != null)
  4285. {
  4286. IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
  4287. friendsModule?.CacheFriendsOnline(UUID, cAgent.CachedFriendsOnline, true);
  4288. }
  4289. }
  4290. public bool CopyAgent(out IAgentData agent)
  4291. {
  4292. agent = new CompleteAgentData();
  4293. CopyTo((AgentData)agent, false);
  4294. return true;
  4295. }
  4296. #endregion Child Agent Updates
  4297. /// <summary>
  4298. /// Handles part of the PID controller function for moving an avatar.
  4299. /// </summary>
  4300. public void UpdateMovement()
  4301. {
  4302. /*
  4303. if (IsInTransit)
  4304. return;
  4305. lock(m_forceToApplyLock)
  4306. {
  4307. if (m_forceToApplyValid)
  4308. {
  4309. Velocity = m_forceToApply;
  4310. m_forceToApplyValid = false;
  4311. TriggerScenePresenceUpdated();
  4312. }
  4313. }
  4314. */
  4315. }
  4316. /// <summary>
  4317. /// Adds a physical representation of the avatar to the Physics plugin
  4318. /// </summary>
  4319. public void AddToPhysicalScene(bool isFlying)
  4320. {
  4321. // m_log.DebugFormat(
  4322. // "[SCENE PRESENCE]: Adding physics actor for {0}, ifFlying = {1} in {2}",
  4323. // Name, isFlying, Scene.RegionInfo.RegionName);
  4324. if (PhysicsActor != null)
  4325. {
  4326. m_log.ErrorFormat(
  4327. "[SCENE PRESENCE]: Adding physics actor for {0} to {1} but this scene presence already has a physics actor",
  4328. Name, Scene.RegionInfo.RegionName);
  4329. }
  4330. if (Appearance.AvatarHeight == 0)
  4331. //Appearance.SetHeight();
  4332. Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
  4333. //lock(m_forceToApplyLock)
  4334. // m_forceToApplyValid = false;
  4335. PhysicsScene scene = m_scene.PhysicsScene;
  4336. Vector3 pVec = AbsolutePosition;
  4337. PhysicsActor pa = scene.AddAvatar(
  4338. LocalId, Firstname + "." + Lastname, pVec,
  4339. Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
  4340. pa.Orientation = m_bodyRot;
  4341. //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
  4342. pa.OnCollisionUpdate += PhysicsCollisionUpdate;
  4343. pa.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong
  4344. pa.SubscribeEvents(100);
  4345. pa.LocalID = LocalId;
  4346. pa.SetAlwaysRun = m_setAlwaysRun;
  4347. PhysicsActor = pa;
  4348. }
  4349. private void OutOfBoundsCall(Vector3 pos)
  4350. {
  4351. ControllingClient?.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
  4352. }
  4353. /// <summary>
  4354. /// Event called by the physics plugin to tell the avatar about a collision.
  4355. /// </summary>
  4356. /// <remarks>
  4357. /// This function is called continuously, even when there are no collisions. If the avatar is walking on the
  4358. /// ground or a prim then there will be collision information between the avatar and the surface.
  4359. ///
  4360. /// FIXME: However, we can't safely avoid calling this yet where there are no collisions without analyzing whether
  4361. /// any part of this method is relying on an every-frame call.
  4362. /// </remarks>
  4363. /// <param name="e"></param>
  4364. public void PhysicsCollisionUpdate(EventArgs e)
  4365. {
  4366. if (IsChildAgent)
  4367. return;
  4368. if(IsInTransit)
  4369. return;
  4370. CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
  4371. Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
  4372. if (coldata.Count == 0)
  4373. CollisionPlane = Vector4.UnitW;
  4374. else
  4375. {
  4376. ContactPoint lowest;
  4377. lowest.SurfaceNormal = Vector3.Zero;
  4378. lowest.Position = Vector3.Zero;
  4379. float maxZ= float.MaxValue;
  4380. foreach (ContactPoint contact in coldata.Values)
  4381. {
  4382. if (contact.CharacterFeet && contact.Position.Z < maxZ)
  4383. {
  4384. lowest = contact;
  4385. maxZ = lowest.Position.Z;
  4386. }
  4387. }
  4388. if (maxZ != float.MaxValue)
  4389. {
  4390. lowest.SurfaceNormal = -lowest.SurfaceNormal;
  4391. CollisionPlane = new Vector4(lowest.SurfaceNormal, lowest.Position.Dot(lowest.SurfaceNormal));
  4392. }
  4393. else
  4394. CollisionPlane = Vector4.UnitW;
  4395. }
  4396. RaiseCollisionScriptEvents(coldata);
  4397. // Gods do not take damage and Invulnerable is set depending on parcel/region flags
  4398. if (Invulnerable || IsViewerUIGod)
  4399. return;
  4400. // The following may be better in the ICombatModule
  4401. // probably tweaking of the values for ground and normal prim collisions will be needed
  4402. float startHealth = Health;
  4403. if(coldata.Count > 0)
  4404. {
  4405. uint killerObj = 0;
  4406. SceneObjectPart part;
  4407. float rvel; // relative velocity, negative on approch
  4408. foreach (uint localid in coldata.Keys)
  4409. {
  4410. if (localid == 0)
  4411. {
  4412. // 0 is the ground
  4413. rvel = coldata[0].RelativeSpeed;
  4414. if(rvel < -5.0f)
  4415. Health -= 0.01f * rvel * rvel;
  4416. }
  4417. else
  4418. {
  4419. part = Scene.GetSceneObjectPart(localid);
  4420. if(part != null && !part.ParentGroup.IsVolumeDetect)
  4421. {
  4422. if (part.ParentGroup.Damage > 0.0f)
  4423. {
  4424. // Something with damage...
  4425. Health -= part.ParentGroup.Damage;
  4426. part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
  4427. }
  4428. else
  4429. {
  4430. // An ordinary prim
  4431. rvel = coldata[localid].RelativeSpeed;
  4432. if(rvel < -5.0f)
  4433. {
  4434. Health -= 0.005f * rvel * rvel;
  4435. }
  4436. }
  4437. }
  4438. else
  4439. {
  4440. }
  4441. }
  4442. if (Health <= 0.0f)
  4443. {
  4444. if (localid != 0)
  4445. killerObj = localid;
  4446. }
  4447. }
  4448. if (Health <= 0)
  4449. {
  4450. ControllingClient.SendHealth(Health);
  4451. m_scene.EventManager.TriggerAvatarKill(killerObj, this);
  4452. return;
  4453. }
  4454. }
  4455. if(Math.Abs(Health - startHealth) > 1.0)
  4456. ControllingClient.SendHealth(Health);
  4457. }
  4458. public void setHealthWithUpdate(float health)
  4459. {
  4460. Health = health;
  4461. ControllingClient.SendHealth(Health);
  4462. }
  4463. public void AddAttachment(SceneObjectGroup gobj)
  4464. {
  4465. lock (m_attachments)
  4466. {
  4467. // This may be true when the attachment comes back
  4468. // from serialization after login. Clear it.
  4469. gobj.IsDeleted = false;
  4470. m_attachments.Add(gobj);
  4471. }
  4472. IBakedTextureModule bakedModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
  4473. bakedModule?.UpdateMeshAvatar(m_uuid);
  4474. }
  4475. public int GetAttachmentsCount()
  4476. {
  4477. return m_attachments.Count;
  4478. }
  4479. /// <summary>
  4480. /// Get all the presence's attachments.
  4481. /// </summary>
  4482. /// <returns>A copy of the list which contains the attachments.</returns>
  4483. public List<SceneObjectGroup> GetAttachments()
  4484. {
  4485. lock (m_attachments)
  4486. return new List<SceneObjectGroup>(m_attachments);
  4487. }
  4488. /// <summary>
  4489. /// Get the scene objects attached to the given point.
  4490. /// </summary>
  4491. /// <param name="attachmentPoint"></param>
  4492. /// <returns>Returns an empty list if there were no attachments at the point.</returns>
  4493. public List<SceneObjectGroup> GetAttachments(uint attachmentPoint)
  4494. {
  4495. List<SceneObjectGroup> attachments = new();
  4496. if (attachmentPoint >= 0)
  4497. {
  4498. lock (m_attachments)
  4499. {
  4500. foreach (SceneObjectGroup so in m_attachments)
  4501. {
  4502. if (attachmentPoint == so.AttachmentPoint)
  4503. attachments.Add(so);
  4504. }
  4505. }
  4506. }
  4507. return attachments;
  4508. }
  4509. public bool HasAttachments()
  4510. {
  4511. lock (m_attachments)
  4512. return m_attachments.Count > 0;
  4513. }
  4514. /// <summary>
  4515. /// Returns the total count of scripts in all parts inventories.
  4516. /// </summary>
  4517. public int ScriptCount()
  4518. {
  4519. int count = 0;
  4520. lock (m_attachments)
  4521. {
  4522. foreach (SceneObjectGroup gobj in m_attachments)
  4523. {
  4524. if (gobj != null)
  4525. {
  4526. count += gobj.ScriptCount();
  4527. }
  4528. }
  4529. }
  4530. return count;
  4531. }
  4532. /// <summary>
  4533. /// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
  4534. /// </summary>
  4535. public float ScriptExecutionTime()
  4536. {
  4537. float time = 0.0f;
  4538. lock (m_attachments)
  4539. {
  4540. foreach (SceneObjectGroup gobj in m_attachments)
  4541. {
  4542. if (gobj != null)
  4543. {
  4544. time += gobj.ScriptExecutionTime();
  4545. }
  4546. }
  4547. }
  4548. return time;
  4549. }
  4550. /// <summary>
  4551. /// Returns the total count of running scripts in all parts.
  4552. /// </summary>
  4553. public int RunningScriptCount()
  4554. {
  4555. int count = 0;
  4556. lock (m_attachments)
  4557. {
  4558. foreach (SceneObjectGroup gobj in m_attachments)
  4559. {
  4560. if (gobj != null)
  4561. {
  4562. count += gobj.RunningScriptCount();
  4563. }
  4564. }
  4565. }
  4566. return count;
  4567. }
  4568. public bool HasScriptedAttachments()
  4569. {
  4570. lock (m_attachments)
  4571. {
  4572. foreach (SceneObjectGroup gobj in m_attachments)
  4573. {
  4574. if (gobj != null)
  4575. {
  4576. if (gobj.RootPart.Inventory.ContainsScripts())
  4577. return true;
  4578. }
  4579. }
  4580. }
  4581. return false;
  4582. }
  4583. public void RemoveAttachment(SceneObjectGroup gobj)
  4584. {
  4585. lock (m_attachments)
  4586. m_attachments.Remove(gobj);
  4587. }
  4588. /// <summary>
  4589. /// Clear all attachments
  4590. /// </summary>
  4591. public void ClearAttachments()
  4592. {
  4593. lock (m_attachments)
  4594. m_attachments.Clear();
  4595. }
  4596. /// <summary>
  4597. /// This is currently just being done for information.
  4598. /// </summary>
  4599. public bool ValidateAttachments()
  4600. {
  4601. bool validated = true;
  4602. lock (m_attachments)
  4603. {
  4604. // Validate
  4605. foreach (SceneObjectGroup gobj in m_attachments)
  4606. {
  4607. if (gobj == null)
  4608. {
  4609. m_log.WarnFormat(
  4610. "[SCENE PRESENCE]: Failed to validate an attachment for {0} since it was null. Continuing", Name);
  4611. validated = false;
  4612. }
  4613. else if (gobj.IsDeleted)
  4614. {
  4615. m_log.WarnFormat(
  4616. "[SCENE PRESENCE]: Failed to validate attachment {0} {1} for {2} since it had been deleted. Continuing",
  4617. gobj.Name, gobj.UUID, Name);
  4618. validated = false;
  4619. }
  4620. }
  4621. }
  4622. return validated;
  4623. }
  4624. /*
  4625. public void SendAttachmentsToAllAgents()
  4626. {
  4627. lock (m_attachments)
  4628. {
  4629. foreach (SceneObjectGroup sog in m_attachments)
  4630. {
  4631. m_scene.ForEachScenePresence(delegate(ScenePresence p)
  4632. {
  4633. if (p != this && sog.HasPrivateAttachmentPoint)
  4634. return;
  4635. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  4636. return;
  4637. SendTerseUpdateToAgentNF(p);
  4638. SendAttachmentFullUpdateToAgentNF(sog, p);
  4639. });
  4640. }
  4641. }
  4642. }
  4643. */
  4644. // send attachments to a client without filters except for huds
  4645. // for now they are checked in several places down the line...
  4646. public void SendAttachmentsToAgentNF(ScenePresence p)
  4647. {
  4648. SendTerseUpdateToAgentNF(p);
  4649. //SendAvatarDataToAgentNF(this);
  4650. lock (m_attachments)
  4651. {
  4652. foreach (SceneObjectGroup sog in m_attachments)
  4653. {
  4654. SendAttachmentFullUpdateToAgentNF(sog, p);
  4655. }
  4656. }
  4657. }
  4658. public void SendAttachmentFullUpdateToAgentNF(SceneObjectGroup sog, ScenePresence p)
  4659. {
  4660. if (p != this && sog.HasPrivateAttachmentPoint)
  4661. return;
  4662. SceneObjectPart[] parts = sog.Parts;
  4663. SceneObjectPart rootpart = sog.RootPart;
  4664. PrimUpdateFlags update = PrimUpdateFlags.FullUpdate;
  4665. if (rootpart.Shape.MeshFlagEntry)
  4666. update = PrimUpdateFlags.FullUpdatewithAnim;
  4667. p.ControllingClient.SendEntityUpdate(rootpart, update);
  4668. for (int i = 0; i < parts.Length; i++)
  4669. {
  4670. SceneObjectPart part = parts[i];
  4671. if (part == rootpart)
  4672. continue;
  4673. p.ControllingClient.SendEntityUpdate(part, update);
  4674. }
  4675. }
  4676. public void SendAttachmentScheduleUpdate(SceneObjectGroup sog)
  4677. {
  4678. if (IsChildAgent || IsInTransit || IsDeleted)
  4679. return;
  4680. SceneObjectPart[] origparts = sog.Parts;
  4681. SceneObjectPart[] parts = new SceneObjectPart[origparts.Length];
  4682. PrimUpdateFlags[] flags = new PrimUpdateFlags[origparts.Length];
  4683. SceneObjectPart rootpart = sog.RootPart;
  4684. PrimUpdateFlags cur = sog.RootPart.GetAndClearUpdateFlag();
  4685. bool noanim = !rootpart.Shape.MeshFlagEntry;
  4686. int nparts = 0;
  4687. if (noanim || rootpart.Animations == null)
  4688. cur &= ~PrimUpdateFlags.Animations;
  4689. if (cur != PrimUpdateFlags.None)
  4690. {
  4691. flags[nparts] = cur;
  4692. parts[nparts] = rootpart;
  4693. ++nparts;
  4694. }
  4695. for (int i = 0; i < origparts.Length; i++)
  4696. {
  4697. if (origparts[i] == rootpart)
  4698. continue;
  4699. cur = origparts[i].GetAndClearUpdateFlag();
  4700. if (noanim || origparts[i].Animations == null)
  4701. cur &= ~PrimUpdateFlags.Animations;
  4702. if (cur == PrimUpdateFlags.None)
  4703. continue;
  4704. flags[nparts] = cur;
  4705. parts[nparts] = origparts[i];
  4706. ++nparts;
  4707. }
  4708. if (nparts == 0 || IsChildAgent || IsInTransit || IsDeleted)
  4709. return;
  4710. for (int i = 0; i < nparts; i++)
  4711. ControllingClient.SendEntityUpdate(parts[i], flags[i]);
  4712. if (sog.HasPrivateAttachmentPoint)
  4713. return;
  4714. List<ScenePresence> allPresences = m_scene.GetScenePresences();
  4715. foreach (ScenePresence p in allPresences)
  4716. {
  4717. if (p == this || p.IsDeleted)
  4718. continue;
  4719. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  4720. continue;
  4721. for (int i = 0; i < nparts; i++)
  4722. p.ControllingClient.SendEntityUpdate(parts[i], flags[i]);
  4723. }
  4724. }
  4725. public void SendAttachmentUpdate(SceneObjectGroup sog, PrimUpdateFlags update)
  4726. {
  4727. if (IsChildAgent || IsInTransit)
  4728. return;
  4729. SceneObjectPart[] origparts = sog.Parts;
  4730. SceneObjectPart[] parts = new SceneObjectPart[origparts.Length];
  4731. PrimUpdateFlags[] flags = new PrimUpdateFlags[origparts.Length];
  4732. SceneObjectPart rootpart = sog.RootPart;
  4733. bool noanim = !rootpart.Shape.MeshFlagEntry;
  4734. int nparts = 0;
  4735. PrimUpdateFlags cur = update;
  4736. if (noanim || rootpart.Animations == null)
  4737. cur &= ~PrimUpdateFlags.Animations;
  4738. if (cur != PrimUpdateFlags.None)
  4739. {
  4740. flags[nparts] = cur;
  4741. parts[nparts] = rootpart;
  4742. ++nparts;
  4743. }
  4744. for (int i = 0; i < origparts.Length; i++)
  4745. {
  4746. if (origparts[i] == rootpart)
  4747. continue;
  4748. cur = update;
  4749. if (noanim || origparts[i].Animations == null)
  4750. cur &= ~PrimUpdateFlags.Animations;
  4751. if (cur == PrimUpdateFlags.None)
  4752. continue;
  4753. flags[nparts] = cur;
  4754. parts[nparts] = origparts[i];
  4755. ++nparts;
  4756. }
  4757. if (nparts == 0)
  4758. return;
  4759. for(int i = 0; i < nparts; i++)
  4760. ControllingClient.SendEntityUpdate(parts[i], flags[i]);
  4761. if (sog.HasPrivateAttachmentPoint)
  4762. return;
  4763. List<ScenePresence> allPresences = m_scene.GetScenePresences();
  4764. foreach (ScenePresence p in allPresences)
  4765. {
  4766. if (p == this)
  4767. continue;
  4768. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  4769. continue;
  4770. p.ControllingClient.SendEntityUpdate(rootpart, update);
  4771. for (int i = 0; i < nparts; i++)
  4772. p.ControllingClient.SendEntityUpdate(parts[i], flags[i]);
  4773. }
  4774. }
  4775. public void SendAttachmentUpdate(SceneObjectPart part, PrimUpdateFlags update)
  4776. {
  4777. if (IsChildAgent || IsInTransit)
  4778. return;
  4779. if ((update & PrimUpdateFlags.Animations) != 0 && part.Animations == null)
  4780. {
  4781. update &= ~PrimUpdateFlags.Animations;
  4782. if (update == PrimUpdateFlags.None)
  4783. return;
  4784. }
  4785. ControllingClient.SendEntityUpdate(part, update);
  4786. if (part.ParentGroup.HasPrivateAttachmentPoint)
  4787. return;
  4788. List<ScenePresence> allPresences = m_scene.GetScenePresences();
  4789. foreach (ScenePresence p in allPresences)
  4790. {
  4791. if (p == this)
  4792. continue;
  4793. if (ParcelHideThisAvatar && currentParcelUUID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  4794. continue;
  4795. p.ControllingClient.SendEntityUpdate(part, update);
  4796. }
  4797. }
  4798. public void SendScriptChangedEventToAttachments(Changed val)
  4799. {
  4800. lock (m_attachments)
  4801. {
  4802. foreach (SceneObjectGroup grp in m_attachments)
  4803. {
  4804. if ((grp.ScriptEvents & scriptEvents.changed) != 0)
  4805. {
  4806. foreach(SceneObjectPart sop in grp.Parts)
  4807. {
  4808. sop.TriggerScriptChangedEvent(val);
  4809. }
  4810. }
  4811. }
  4812. }
  4813. }
  4814. /// <summary>
  4815. /// Gets the mass.
  4816. /// </summary>
  4817. /// <returns>
  4818. /// The mass.
  4819. /// </returns>
  4820. public float GetMass()
  4821. {
  4822. PhysicsActor pa = PhysicsActor;
  4823. if (pa != null)
  4824. return pa.Mass;
  4825. else
  4826. return 0;
  4827. }
  4828. internal void Jump(float impulseZ)
  4829. {
  4830. PhysicsActor?.AvatarJump(impulseZ);
  4831. }
  4832. internal void PushForce(Vector3 impulse)
  4833. {
  4834. PhysicsActor?.AddForce(impulse, true);
  4835. }
  4836. private CameraData CameraDataCache;
  4837. CameraData physActor_OnPhysicsRequestingCameraData()
  4838. {
  4839. CameraDataCache ??= new CameraData();
  4840. CameraDataCache.MouseLook = m_mouseLook;
  4841. CameraDataCache.CameraRotation = CameraRotation;
  4842. CameraDataCache.CameraAtAxis = CameraAtAxis;
  4843. return CameraDataCache;
  4844. }
  4845. public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID)
  4846. {
  4847. SceneObjectPart part = m_scene.GetSceneObjectPart(Obj_localID);
  4848. if (part == null)
  4849. return;
  4850. ControllingClient.SendTakeControls(controls, false, false);
  4851. ControllingClient.SendTakeControls(controls, true, false);
  4852. ScriptControllers obj = new()
  4853. {
  4854. ignoreControls = ScriptControlled.CONTROL_ZERO,
  4855. eventControls = ScriptControlled.CONTROL_ZERO,
  4856. objectID = part.ParentGroup.UUID,
  4857. itemID = Script_item_UUID
  4858. };
  4859. if (pass_on == 0 && accept == 0)
  4860. {
  4861. IgnoredControls |= (ScriptControlled)controls;
  4862. obj.ignoreControls = (ScriptControlled)controls;
  4863. }
  4864. if (pass_on == 0 && accept == 1)
  4865. {
  4866. IgnoredControls |= (ScriptControlled)controls;
  4867. obj.ignoreControls = (ScriptControlled)controls;
  4868. obj.eventControls = (ScriptControlled)controls;
  4869. }
  4870. if (pass_on == 1 && accept == 1)
  4871. {
  4872. IgnoredControls = ScriptControlled.CONTROL_ZERO;
  4873. obj.eventControls = (ScriptControlled)controls;
  4874. obj.ignoreControls = ScriptControlled.CONTROL_ZERO;
  4875. }
  4876. lock (scriptedcontrols)
  4877. {
  4878. if (pass_on == 1 && accept == 0)
  4879. {
  4880. IgnoredControls &= ~(ScriptControlled)controls;
  4881. if (scriptedcontrols.ContainsKey(Script_item_UUID))
  4882. RemoveScriptFromControlNotifications(Script_item_UUID, part);
  4883. }
  4884. else
  4885. {
  4886. AddScriptToControlNotifications(Script_item_UUID, part, ref obj);
  4887. }
  4888. }
  4889. ControllingClient.SendTakeControls(controls, pass_on == 1, true);
  4890. }
  4891. private void AddScriptToControlNotifications(OpenMetaverse.UUID Script_item_UUID, SceneObjectPart part, ref ScriptControllers obj)
  4892. {
  4893. scriptedcontrols[Script_item_UUID] = obj;
  4894. PhysicsActor physActor = part.ParentGroup.RootPart.PhysActor;
  4895. if (physActor != null)
  4896. {
  4897. physActor.OnPhysicsRequestingCameraData -= physActor_OnPhysicsRequestingCameraData;
  4898. physActor.OnPhysicsRequestingCameraData += physActor_OnPhysicsRequestingCameraData;
  4899. }
  4900. }
  4901. private void RemoveScriptFromControlNotifications(OpenMetaverse.UUID Script_item_UUID, SceneObjectPart part)
  4902. {
  4903. scriptedcontrols.Remove(Script_item_UUID);
  4904. if (part != null)
  4905. {
  4906. PhysicsActor physActor = part.ParentGroup.RootPart.PhysActor;
  4907. if (physActor != null)
  4908. {
  4909. physActor.OnPhysicsRequestingCameraData -= physActor_OnPhysicsRequestingCameraData;
  4910. }
  4911. }
  4912. }
  4913. public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID)
  4914. {
  4915. lock (scriptedcontrols)
  4916. {
  4917. foreach (ScriptControllers c in scriptedcontrols.Values)
  4918. {
  4919. SceneObjectGroup sog = m_scene.GetSceneObjectGroup(c.objectID);
  4920. if(sog != null && !sog.IsDeleted && sog.RootPart.PhysActor != null)
  4921. sog.RootPart.PhysActor.OnPhysicsRequestingCameraData -= physActor_OnPhysicsRequestingCameraData;
  4922. }
  4923. IgnoredControls = ScriptControlled.CONTROL_ZERO;
  4924. scriptedcontrols.Clear();
  4925. }
  4926. ControllingClient.SendTakeControls(int.MaxValue, false, false);
  4927. }
  4928. public void HandleRevokePermissions(UUID objectID, uint permissions )
  4929. {
  4930. // still skeleton code
  4931. if((permissions & (16 | 0x8000 )) == 0) //PERMISSION_TRIGGER_ANIMATION | PERMISSION_OVERRIDE_ANIMATIONS
  4932. return;
  4933. if(objectID.Equals(m_scene.RegionInfo.RegionID)) // for all objects
  4934. {
  4935. List<SceneObjectGroup> sogs = m_scene.GetSceneObjectGroups();
  4936. for(int i = 0; i < sogs.Count; ++i)
  4937. sogs[i].RemoveScriptsPermissions(this, (int)permissions);
  4938. }
  4939. else
  4940. {
  4941. SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
  4942. part?.Inventory.RemoveScriptsPermissions(this, (int)permissions);
  4943. }
  4944. }
  4945. public void ClearControls()
  4946. {
  4947. IgnoredControls = ScriptControlled.CONTROL_ZERO;
  4948. lock (scriptedcontrols)
  4949. {
  4950. scriptedcontrols.Clear();
  4951. }
  4952. }
  4953. public void UnRegisterSeatControls(UUID obj)
  4954. {
  4955. List<UUID> takers = new();
  4956. foreach (ScriptControllers c in scriptedcontrols.Values)
  4957. {
  4958. if (c.objectID.Equals(obj))
  4959. takers.Add(c.itemID);
  4960. }
  4961. foreach (UUID t in takers)
  4962. {
  4963. UnRegisterControlEventsToScript(0, t);
  4964. }
  4965. }
  4966. public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID)
  4967. {
  4968. SceneObjectPart part = m_scene.GetSceneObjectPart(Obj_localID);
  4969. lock (scriptedcontrols)
  4970. {
  4971. if (scriptedcontrols.TryGetValue(Script_item_UUID, out ScriptControllers takecontrols))
  4972. {
  4973. ScriptControlled sctc = takecontrols.eventControls;
  4974. ControllingClient.SendTakeControls((int)sctc, false, false);
  4975. ControllingClient.SendTakeControls((int)sctc, true, false);
  4976. RemoveScriptFromControlNotifications(Script_item_UUID, part);
  4977. IgnoredControls = ScriptControlled.CONTROL_ZERO;
  4978. foreach (ScriptControllers scData in scriptedcontrols.Values)
  4979. {
  4980. IgnoredControls |= scData.ignoreControls;
  4981. }
  4982. }
  4983. }
  4984. }
  4985. private void SendControlsToScripts(uint flags)
  4986. {
  4987. // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script
  4988. // (e.g., a walking script) checks which animation is active it will be the correct animation.
  4989. lock (scriptedcontrols)
  4990. {
  4991. if (scriptedcontrols.Count <= 0)
  4992. return;
  4993. ScriptControlled allflags;
  4994. if (flags != 0)
  4995. {
  4996. if ((flags & ((uint)ACFlags.AGENT_CONTROL_LBUTTON_UP | unchecked((uint)ACFlags.AGENT_CONTROL_ML_LBUTTON_UP))) != 0)
  4997. {
  4998. allflags = ScriptControlled.CONTROL_ZERO;
  4999. }
  5000. else // recover last state of mouse
  5001. allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
  5002. allflags |= (ScriptControlled)((flags & CONTROL_FLAG_NUDGE_MASK) >> 19);
  5003. allflags |= (ScriptControlled)(flags & CONTROL_FLAG_NORM_MASK);
  5004. if ((flags & (uint)ACFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
  5005. allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
  5006. if ((flags & (uint)ACFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
  5007. allflags |= ScriptControlled.CONTROL_LBUTTON;
  5008. if ((flags & (uint)ACFlags.AGENT_CONTROL_YAW_NEG) != 0)
  5009. {
  5010. allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
  5011. }
  5012. if ((flags & (uint)ACFlags.AGENT_CONTROL_YAW_POS) != 0)
  5013. {
  5014. allflags |= ScriptControlled.CONTROL_ROT_LEFT;
  5015. }
  5016. }
  5017. else // recover last state of mouse
  5018. allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
  5019. // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
  5020. if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
  5021. {
  5022. foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
  5023. {
  5024. ScriptControlled eventcnt = kvp.Value.eventControls;
  5025. ScriptControlled localHeld = allflags & eventcnt; // the flags interesting for us
  5026. ScriptControlled localLast = LastCommands & eventcnt; // the activated controls in the last cycle
  5027. ScriptControlled localChange = localHeld ^ localLast; // the changed bits
  5028. if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
  5029. {
  5030. // only send if still pressed or just changed
  5031. m_scene.EventManager.TriggerControlEvent(kvp.Key, UUID, (uint)localHeld, (uint)localChange);
  5032. }
  5033. }
  5034. }
  5035. LastCommands = allflags;
  5036. MouseDown = (allflags & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON)) != 0;
  5037. }
  5038. }
  5039. internal static ACFlags RemoveIgnoredControls(ACFlags flags, ScriptControlled ignored)
  5040. {
  5041. if(flags == ACFlags.NONE)
  5042. return flags;
  5043. if (ignored == ScriptControlled.CONTROL_ZERO)
  5044. return flags;
  5045. ignored &= (ScriptControlled)CONTROL_FLAG_NORM_MASK;
  5046. ignored |= (ScriptControlled)((uint)ignored << 19);
  5047. flags &= ~(ACFlags)ignored;
  5048. if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0)
  5049. flags &= ~(ACFlags.AGENT_CONTROL_YAW_NEG);
  5050. if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0)
  5051. flags &= ~(ACFlags.AGENT_CONTROL_YAW_POS);
  5052. if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0)
  5053. flags &= ~(ACFlags.AGENT_CONTROL_ML_LBUTTON_DOWN);
  5054. if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0)
  5055. flags &= ~(ACFlags.AGENT_CONTROL_LBUTTON_UP | ACFlags.AGENT_CONTROL_LBUTTON_DOWN);
  5056. return flags;
  5057. }
  5058. // returns true it local teleport allowed and sets the destiny position into pos
  5059. public bool CheckLocalTPLandingPoint(ref Vector3 pos)
  5060. {
  5061. // Never constrain lures
  5062. if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
  5063. return true;
  5064. if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
  5065. return true;
  5066. // do not constrain gods and estate managers
  5067. if(m_scene.Permissions.IsGod(m_uuid) ||
  5068. m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid))
  5069. return true;
  5070. // will teleport to a telehub spawn point or landpoint if that results in getting closer to target
  5071. // if not the local teleport fails.
  5072. float currDistanceSQ = Vector3.DistanceSquared(AbsolutePosition, pos);
  5073. // first check telehub
  5074. UUID TelehubObjectID = m_scene.RegionInfo.RegionSettings.TelehubObject;
  5075. if ( !TelehubObjectID.IsZero())
  5076. {
  5077. SceneObjectGroup telehubSOG = m_scene.GetSceneObjectGroup(TelehubObjectID);
  5078. if(telehubSOG != null)
  5079. {
  5080. Vector3 spawnPos;
  5081. float spawnDistSQ;
  5082. SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray();
  5083. if(spawnPoints.Length == 0)
  5084. {
  5085. spawnPos = new Vector3(128.0f, 128.0f, pos.Z);
  5086. spawnDistSQ = Vector3.DistanceSquared(spawnPos, pos);
  5087. }
  5088. else
  5089. {
  5090. Vector3 hubPos = telehubSOG.AbsolutePosition;
  5091. Quaternion hubRot = telehubSOG.GroupRotation;
  5092. spawnPos = spawnPoints[0].GetLocation(hubPos, hubRot);
  5093. spawnDistSQ = Vector3.DistanceSquared(spawnPos, pos);
  5094. float testDistSQ;
  5095. Vector3 testSpawnPos;
  5096. for(int i = 1; i< spawnPoints.Length; i++)
  5097. {
  5098. testSpawnPos = spawnPoints[i].GetLocation(hubPos, hubRot);
  5099. testDistSQ = Vector3.DistanceSquared(testSpawnPos, pos);
  5100. if(testDistSQ < spawnDistSQ)
  5101. {
  5102. spawnPos = testSpawnPos;
  5103. spawnDistSQ = testDistSQ;
  5104. }
  5105. }
  5106. }
  5107. if (currDistanceSQ < spawnDistSQ)
  5108. {
  5109. // we are already close
  5110. ControllingClient.SendAlertMessage("Can't teleport closer to destination");
  5111. return false;
  5112. }
  5113. else
  5114. {
  5115. pos = spawnPos;
  5116. return true;
  5117. }
  5118. }
  5119. }
  5120. ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
  5121. if (land.LandData.LandingType != (byte)LandingType.LandingPoint
  5122. || land.LandData.OwnerID.Equals(m_uuid))
  5123. return true;
  5124. Vector3 landLocation = land.LandData.UserLocation;
  5125. if(landLocation.IsZero())
  5126. return true;
  5127. if (currDistanceSQ < Vector3.DistanceSquared(landLocation, pos))
  5128. {
  5129. ControllingClient.SendAlertMessage("Can't teleport closer to destination");
  5130. return false;
  5131. }
  5132. pos = land.LandData.UserLocation;
  5133. return true;
  5134. }
  5135. const TeleportFlags TeleHubTPFlags = TeleportFlags.ViaLogin
  5136. | TeleportFlags.ViaHGLogin | TeleportFlags.ViaLocation;
  5137. private bool CheckAndAdjustTelehub(SceneObjectGroup telehub, ref Vector3 pos, ref bool positionChanged)
  5138. {
  5139. // forcing telehubs on any tp that reachs this
  5140. if ((m_teleportFlags & TeleHubTPFlags) != 0 ||
  5141. (!m_scene.TelehubAllowLandmarks && ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )))
  5142. {
  5143. ILandObject land;
  5144. Vector3 teleHubPosition = telehub.AbsolutePosition;
  5145. SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray();
  5146. if(spawnPoints.Length == 0)
  5147. {
  5148. land = m_scene.LandChannel.GetLandObject(teleHubPosition.X,teleHubPosition.Y);
  5149. if(land != null)
  5150. {
  5151. pos = teleHubPosition;
  5152. if(land.IsEitherBannedOrRestricted(UUID))
  5153. return false;
  5154. positionChanged = true;
  5155. return true;
  5156. }
  5157. else
  5158. return false;
  5159. }
  5160. int index;
  5161. int tries;
  5162. bool selected = false;
  5163. bool validhub;
  5164. Vector3 spawnPosition;
  5165. Quaternion teleHubRotation = telehub.GroupRotation;
  5166. switch(m_scene.SpawnPointRouting)
  5167. {
  5168. case "random":
  5169. tries = spawnPoints.Length;
  5170. if(tries < 3) // no much sense in random with a few points when there same can have bans
  5171. goto case "sequence";
  5172. do
  5173. {
  5174. index = Random.Shared.Next(spawnPoints.Length - 1);
  5175. spawnPosition = spawnPoints[index].GetLocation(teleHubPosition, teleHubRotation);
  5176. land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
  5177. if(land != null && !land.IsEitherBannedOrRestricted(UUID))
  5178. selected = true;
  5179. } while(selected == false && --tries > 0 );
  5180. if(tries <= 0)
  5181. goto case "sequence";
  5182. pos = spawnPosition;
  5183. return true;
  5184. case "sequence":
  5185. tries = spawnPoints.Length;
  5186. selected = false;
  5187. validhub = false;
  5188. do
  5189. {
  5190. index = m_scene.SpawnPoint();
  5191. spawnPosition = spawnPoints[index].GetLocation(teleHubPosition, teleHubRotation);
  5192. land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
  5193. if(land != null)
  5194. {
  5195. validhub = true;
  5196. if(land.IsEitherBannedOrRestricted(UUID))
  5197. selected = false;
  5198. else
  5199. selected = true;
  5200. }
  5201. } while(selected == false && --tries > 0);
  5202. if(!validhub)
  5203. return false;
  5204. pos = spawnPosition;
  5205. if(!selected)
  5206. return false;
  5207. positionChanged = true;
  5208. return true;
  5209. default:
  5210. case "closest":
  5211. float distancesq = float.MaxValue;
  5212. int closest = -1;
  5213. validhub = false;
  5214. for(int i = 0; i < spawnPoints.Length; i++)
  5215. {
  5216. spawnPosition = spawnPoints[i].GetLocation(teleHubPosition, teleHubRotation);
  5217. Vector3 offset = spawnPosition - pos;
  5218. float dsq = offset.LengthSquared();
  5219. land = m_scene.LandChannel.GetLandObject(spawnPosition.X,spawnPosition.Y);
  5220. if(land == null)
  5221. continue;
  5222. validhub = true;
  5223. if(land.IsEitherBannedOrRestricted(UUID))
  5224. continue;
  5225. if(dsq >= distancesq)
  5226. continue;
  5227. distancesq = dsq;
  5228. closest = i;
  5229. }
  5230. if(!validhub)
  5231. return false;
  5232. if(closest < 0)
  5233. {
  5234. pos = spawnPoints[0].GetLocation(teleHubPosition, teleHubRotation);
  5235. positionChanged = true;
  5236. return false;
  5237. }
  5238. pos = spawnPoints[closest].GetLocation(teleHubPosition, teleHubRotation);
  5239. positionChanged = true;
  5240. return true;
  5241. }
  5242. }
  5243. return false;
  5244. }
  5245. const TeleportFlags adicionalLandPointFlags = TeleportFlags.ViaLandmark |
  5246. TeleportFlags.ViaLocation | TeleportFlags.ViaHGLogin;
  5247. // Modify landing point based on possible banning, telehubs or parcel restrictions.
  5248. // This is the behavior in OpenSim for a very long time, different from SL
  5249. private bool CheckAndAdjustLandingPoint_OS(ref Vector3 pos, ref Vector3 lookat, ref bool positionChanged)
  5250. {
  5251. // Honor bans
  5252. if (!m_scene.TestLandRestrictions(UUID, out string _, ref pos.X, ref pos.Y))
  5253. return false;
  5254. SceneObjectGroup telehub;
  5255. if (!m_scene.RegionInfo.RegionSettings.TelehubObject.IsZero() && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) is not null)
  5256. {
  5257. if (!m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
  5258. {
  5259. CheckAndAdjustTelehub(telehub, ref pos, ref positionChanged);
  5260. return true;
  5261. }
  5262. }
  5263. ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
  5264. if (land != null)
  5265. {
  5266. if (Scene.DebugTeleporting)
  5267. TeleportFlagsDebug();
  5268. // If we come in via login, landmark or map, we want to
  5269. // honor landing points. If we come in via Lure, we want
  5270. // to ignore them.
  5271. if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
  5272. (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
  5273. (m_teleportFlags & adicionalLandPointFlags) != 0)
  5274. {
  5275. // Don't restrict gods, estate managers, or land owners to
  5276. // the TP point. This behaviour mimics agni.
  5277. if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
  5278. !land.LandData.UserLocation.IsZero() &&
  5279. !IsViewerUIGod &&
  5280. ((land.LandData.OwnerID != m_uuid &&
  5281. !m_scene.Permissions.IsGod(m_uuid) &&
  5282. !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
  5283. (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
  5284. (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
  5285. {
  5286. pos = land.LandData.UserLocation;
  5287. positionChanged = true;
  5288. }
  5289. }
  5290. }
  5291. return true;
  5292. }
  5293. // Modify landing point based on telehubs or parcel restrictions.
  5294. // This is a behavior coming from AVN, somewhat mimicking SL
  5295. private bool CheckAndAdjustLandingPoint_SL(ref Vector3 pos, ref Vector3 lookat, ref bool positionChanged)
  5296. {
  5297. // dont mess with gods
  5298. if(IsGod)
  5299. return true;
  5300. // respect region owner and managers
  5301. //if(m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid))
  5302. // return true;
  5303. if (!m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
  5304. {
  5305. SceneObjectGroup telehub;
  5306. if (!m_scene.RegionInfo.RegionSettings.TelehubObject.IsZero() && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) is not null)
  5307. {
  5308. if(CheckAndAdjustTelehub(telehub, ref pos, ref positionChanged))
  5309. return true;
  5310. }
  5311. }
  5312. // Honor bans, actually we don't honour them
  5313. if (!m_scene.TestLandRestrictions(UUID, out string _, ref pos.X, ref pos.Y))
  5314. return false;
  5315. ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
  5316. if (land is not null)
  5317. {
  5318. if (Scene.DebugTeleporting)
  5319. TeleportFlagsDebug();
  5320. // If we come in via login, landmark or map, we want to
  5321. // honor landing points. If we come in via Lure, we want
  5322. // to ignore them.
  5323. if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
  5324. (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)
  5325. || (m_teleportFlags & adicionalLandPointFlags) != 0)
  5326. {
  5327. if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
  5328. !land.LandData.UserLocation.IsZero() )
  5329. // &&
  5330. // land.LandData.OwnerID != m_uuid )
  5331. {
  5332. pos = land.LandData.UserLocation;
  5333. if(!land.LandData.UserLookAt.IsZero())
  5334. lookat = land.LandData.UserLookAt;
  5335. positionChanged = true;
  5336. }
  5337. }
  5338. }
  5339. return true;
  5340. }
  5341. [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
  5342. private DetectedObject CreateDetObject(SceneObjectPart obj)
  5343. {
  5344. return new DetectedObject()
  5345. {
  5346. keyUUID = obj.UUID,
  5347. nameStr = obj.Name,
  5348. ownerUUID = obj.OwnerID,
  5349. posVector = obj.AbsolutePosition,
  5350. rotQuat = obj.GetWorldRotation(),
  5351. velVector = obj.Velocity,
  5352. colliderType = 0,
  5353. groupUUID = obj.GroupID,
  5354. linkNumber = 0
  5355. };
  5356. }
  5357. [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
  5358. private DetectedObject CreateDetObject(ScenePresence av)
  5359. {
  5360. DetectedObject detobj = new()
  5361. {
  5362. keyUUID = av.UUID,
  5363. nameStr = av.ControllingClient.Name,
  5364. ownerUUID = av.UUID,
  5365. posVector = av.AbsolutePosition,
  5366. rotQuat = av.Rotation,
  5367. velVector = av.Velocity,
  5368. colliderType = av.IsNPC ? 0x20 : 0x1, // OpenSim\Region\ScriptEngine\Shared\Helpers.cs
  5369. groupUUID = av.ControllingClient.ActiveGroupId,
  5370. linkNumber = 0
  5371. };
  5372. if (av.IsSatOnObject)
  5373. detobj.colliderType |= 0x4; //passive
  5374. else if (!detobj.velVector.IsZero())
  5375. detobj.colliderType |= 0x2; //active
  5376. return detobj;
  5377. }
  5378. [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
  5379. private DetectedObject CreateDetObjectForGround()
  5380. {
  5381. DetectedObject detobj = new()
  5382. {
  5383. keyUUID = UUID.Zero,
  5384. nameStr = "",
  5385. ownerUUID = UUID.Zero,
  5386. posVector = AbsolutePosition,
  5387. rotQuat = Quaternion.Identity,
  5388. velVector = Vector3.Zero,
  5389. colliderType = 0,
  5390. groupUUID = UUID.Zero,
  5391. linkNumber = 0
  5392. };
  5393. return detobj;
  5394. }
  5395. private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
  5396. {
  5397. ColliderArgs colliderArgs = new();
  5398. List<DetectedObject> colliding = new();
  5399. foreach (uint localId in colliders)
  5400. {
  5401. if (localId == 0)
  5402. continue;
  5403. SceneObjectPart obj = m_scene.GetSceneObjectPart(localId);
  5404. if (obj != null)
  5405. {
  5406. if (!dest.CollisionFilteredOut(obj.UUID, obj.Name))
  5407. colliding.Add(CreateDetObject(obj));
  5408. }
  5409. else
  5410. {
  5411. ScenePresence av = m_scene.GetScenePresence(localId);
  5412. if (av != null && (!av.IsChildAgent))
  5413. {
  5414. if (!dest.CollisionFilteredOut(av.UUID, av.Name))
  5415. colliding.Add(CreateDetObject(av));
  5416. }
  5417. }
  5418. }
  5419. colliderArgs.Colliders = colliding;
  5420. return colliderArgs;
  5421. }
  5422. private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
  5423. [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
  5424. private void SendCollisionEvent(SceneObjectGroup dest, scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
  5425. {
  5426. if (colliders.Count > 0)
  5427. {
  5428. if ((dest.RootPart.ScriptEvents & ev) != 0)
  5429. {
  5430. ColliderArgs CollidingMessage = CreateColliderArgs(dest.RootPart, colliders);
  5431. if (CollidingMessage.Colliders.Count > 0)
  5432. notify(dest.RootPart.LocalId, CollidingMessage);
  5433. }
  5434. }
  5435. }
  5436. [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
  5437. private void SendLandCollisionEvent(SceneObjectGroup dest, scriptEvents ev, ScriptCollidingNotification notify)
  5438. {
  5439. if ((dest.RootPart.ScriptEvents & ev) != 0)
  5440. {
  5441. ColliderArgs LandCollidingMessage = new();
  5442. List<DetectedObject> colliding = new(){CreateDetObjectForGround()};
  5443. LandCollidingMessage.Colliders = colliding;
  5444. notify(dest.RootPart.LocalId, LandCollidingMessage);
  5445. }
  5446. }
  5447. private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata)
  5448. {
  5449. int nattachments = m_attachments.Count;
  5450. if (!ParcelAllowThisAvatarSounds && nattachments == 0)
  5451. return;
  5452. try
  5453. {
  5454. List<SceneObjectGroup> attachements;
  5455. int numberCollisions = coldata.Count;
  5456. if (numberCollisions == 0)
  5457. {
  5458. if (m_lastColliders.Count == 0 && !m_lastLandCollide)
  5459. return; // nothing to do
  5460. if(m_attachments.Count > 0)
  5461. {
  5462. attachements = GetAttachments();
  5463. for (int j = 0; j < attachements.Count; ++j)
  5464. {
  5465. SceneObjectGroup att = attachements[j];
  5466. scriptEvents attev = att.RootPart.ScriptEvents;
  5467. if (m_lastLandCollide && (attev & scriptEvents.land_collision_end) != 0)
  5468. SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
  5469. if ((attev & scriptEvents.collision_end) != 0)
  5470. SendCollisionEvent(att, scriptEvents.collision_end, m_lastColliders, m_scene.EventManager.TriggerScriptCollidingEnd);
  5471. }
  5472. }
  5473. m_lastLandCollide = false;
  5474. m_lastColliders.Clear();
  5475. return;
  5476. }
  5477. bool thisHitLand = false;
  5478. bool startLand = false;
  5479. List<uint> thisHitColliders = new(numberCollisions);
  5480. List<uint> endedColliders = new(m_lastColliders.Count);
  5481. List<uint> startedColliders = new(numberCollisions);
  5482. if(ParcelAllowThisAvatarSounds)
  5483. {
  5484. List<CollisionForSoundInfo> soundinfolist = new();
  5485. CollisionForSoundInfo soundinfo;
  5486. ContactPoint curcontact;
  5487. foreach (uint id in coldata.Keys)
  5488. {
  5489. if(id == 0)
  5490. {
  5491. thisHitLand = true;
  5492. startLand = !m_lastLandCollide;
  5493. if (startLand)
  5494. {
  5495. startLand = true;
  5496. curcontact = coldata[id];
  5497. if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
  5498. {
  5499. soundinfo = new CollisionForSoundInfo()
  5500. {
  5501. colliderID = id,
  5502. position = curcontact.Position,
  5503. relativeVel = curcontact.RelativeSpeed
  5504. };
  5505. soundinfolist.Add(soundinfo);
  5506. }
  5507. }
  5508. }
  5509. else
  5510. {
  5511. thisHitColliders.Add(id);
  5512. if (!m_lastColliders.Contains(id))
  5513. {
  5514. startedColliders.Add(id);
  5515. curcontact = coldata[id];
  5516. if (Math.Abs(curcontact.RelativeSpeed) > 0.2)
  5517. {
  5518. soundinfo = new CollisionForSoundInfo()
  5519. {
  5520. colliderID = id,
  5521. position = curcontact.Position,
  5522. relativeVel = curcontact.RelativeSpeed
  5523. };
  5524. soundinfolist.Add(soundinfo);
  5525. }
  5526. }
  5527. }
  5528. }
  5529. if (soundinfolist.Count > 0)
  5530. CollisionSounds.AvatarCollisionSound(this, soundinfolist);
  5531. }
  5532. else
  5533. {
  5534. foreach (uint id in coldata.Keys)
  5535. {
  5536. if (id == 0)
  5537. {
  5538. thisHitLand = true;
  5539. startLand = !m_lastLandCollide;
  5540. }
  5541. else
  5542. {
  5543. thisHitColliders.Add(id);
  5544. if (!m_lastColliders.Contains(id))
  5545. startedColliders.Add(id);
  5546. }
  5547. }
  5548. }
  5549. // calculate things that ended colliding
  5550. foreach (uint localID in m_lastColliders)
  5551. {
  5552. if (!thisHitColliders.Contains(localID))
  5553. {
  5554. endedColliders.Add(localID);
  5555. }
  5556. }
  5557. attachements = GetAttachments();
  5558. for (int i = 0; i < attachements.Count; ++i)
  5559. {
  5560. SceneObjectGroup att = attachements[i];
  5561. scriptEvents attev = att.RootPart.ScriptEvents;
  5562. if ((attev & scriptEvents.anyobjcollision) != 0)
  5563. {
  5564. SendCollisionEvent(att, scriptEvents.collision_start, startedColliders, m_scene.EventManager.TriggerScriptCollidingStart);
  5565. SendCollisionEvent(att, scriptEvents.collision , m_lastColliders , m_scene.EventManager.TriggerScriptColliding);
  5566. SendCollisionEvent(att, scriptEvents.collision_end , endedColliders , m_scene.EventManager.TriggerScriptCollidingEnd);
  5567. }
  5568. if ((attev & scriptEvents.anylandcollision) != 0)
  5569. {
  5570. if (thisHitLand)
  5571. {
  5572. if (startLand)
  5573. SendLandCollisionEvent(att, scriptEvents.land_collision_start, m_scene.EventManager.TriggerScriptLandCollidingStart);
  5574. SendLandCollisionEvent(att, scriptEvents.land_collision, m_scene.EventManager.TriggerScriptLandColliding);
  5575. }
  5576. else if (m_lastLandCollide)
  5577. SendLandCollisionEvent(att, scriptEvents.land_collision_end, m_scene.EventManager.TriggerScriptLandCollidingEnd);
  5578. }
  5579. }
  5580. m_lastLandCollide = thisHitLand;
  5581. m_lastColliders = thisHitColliders;
  5582. }
  5583. catch { }
  5584. }
  5585. private void TeleportFlagsDebug() {
  5586. // Some temporary debugging help to show all the TeleportFlags we have...
  5587. bool HG = false;
  5588. if((m_teleportFlags & TeleportFlags.ViaHGLogin) == TeleportFlags.ViaHGLogin)
  5589. HG = true;
  5590. m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
  5591. uint i;
  5592. for (int x = 0; x <= 30 ; x++)
  5593. {
  5594. i = 1u << x;
  5595. if((m_teleportFlags & (TeleportFlags)i) != 0)
  5596. {
  5597. if (HG == false)
  5598. m_log.InfoFormat("[SCENE PRESENCE]: Teleport Flags include {0}", ((TeleportFlags) i).ToString());
  5599. else
  5600. m_log.InfoFormat("[SCENE PRESENCE]: HG Teleport Flags include {0}", ((TeleportFlags)i).ToString());
  5601. }
  5602. }
  5603. m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
  5604. }
  5605. private void parcelGodCheck(UUID currentParcelID)
  5606. {
  5607. List<ScenePresence> allpresences = m_scene.GetScenePresences();
  5608. foreach (ScenePresence p in allpresences)
  5609. {
  5610. if (p.IsDeleted || p.IsChildAgent || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
  5611. continue;
  5612. if (p.ParcelHideThisAvatar && p.currentParcelUUID != currentParcelID)
  5613. {
  5614. if (IsViewerUIGod)
  5615. p.SendViewTo(this);
  5616. else
  5617. p.SendKillTo(this);
  5618. }
  5619. }
  5620. }
  5621. private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID,
  5622. bool currentParcelHide, bool previusParcelHide, bool oldhide, bool check)
  5623. {
  5624. List<ScenePresence> killsToSendto = new();
  5625. List<ScenePresence> killsToSendme = new();
  5626. List<ScenePresence> viewsToSendto = new();
  5627. List<ScenePresence> viewsToSendme = new();
  5628. List<ScenePresence> allpresences;
  5629. if (IsInTransit || IsChildAgent)
  5630. return;
  5631. if (check)
  5632. {
  5633. // check is relative to current parcel only
  5634. if (oldhide == currentParcelHide)
  5635. return;
  5636. allpresences = m_scene.GetScenePresences();
  5637. if (oldhide)
  5638. { // where private
  5639. foreach (ScenePresence p in allpresences)
  5640. {
  5641. if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
  5642. continue;
  5643. // those on not on parcel see me
  5644. if (currentParcelID.NotEqual(p.currentParcelUUID))
  5645. {
  5646. viewsToSendto.Add(p); // they see me
  5647. }
  5648. }
  5649. } // where private end
  5650. else
  5651. { // where public
  5652. foreach (ScenePresence p in allpresences)
  5653. {
  5654. if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
  5655. continue;
  5656. // those not on parcel dont see me
  5657. if (currentParcelID.NotEqual(p.currentParcelUUID) && !p.IsViewerUIGod)
  5658. {
  5659. killsToSendto.Add(p); // they dont see me
  5660. }
  5661. }
  5662. } // where public end
  5663. }
  5664. else
  5665. {
  5666. if (currentParcelHide)
  5667. {
  5668. // now on a private parcel
  5669. allpresences = m_scene.GetScenePresences();
  5670. if (previusParcelHide && !previusParcelID.IsZero())
  5671. {
  5672. foreach (ScenePresence p in allpresences)
  5673. {
  5674. if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
  5675. continue;
  5676. // only those on previous parcel need receive kills
  5677. if (previusParcelID.Equals(p.currentParcelUUID))
  5678. {
  5679. if(!p.IsViewerUIGod)
  5680. killsToSendto.Add(p); // they dont see me
  5681. if(!IsViewerUIGod)
  5682. killsToSendme.Add(p); // i dont see them
  5683. }
  5684. // only those on new parcel need see
  5685. if (currentParcelID.Equals(p.currentParcelUUID))
  5686. {
  5687. viewsToSendto.Add(p); // they see me
  5688. viewsToSendme.Add(p); // i see them
  5689. }
  5690. }
  5691. }
  5692. else
  5693. {
  5694. //was on a public area
  5695. allpresences = m_scene.GetScenePresences();
  5696. foreach (ScenePresence p in allpresences)
  5697. {
  5698. if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
  5699. continue;
  5700. // those not on new parcel dont see me
  5701. if (!p.IsViewerUIGod && currentParcelID.NotEqual(p.currentParcelUUID))
  5702. {
  5703. killsToSendto.Add(p); // they dont see me
  5704. }
  5705. else
  5706. {
  5707. viewsToSendme.Add(p); // i see those on it
  5708. }
  5709. }
  5710. }
  5711. } // now on a private parcel end
  5712. else
  5713. {
  5714. // now on public parcel
  5715. if (previusParcelHide && !previusParcelID.IsZero())
  5716. {
  5717. // was on private area
  5718. allpresences = m_scene.GetScenePresences();
  5719. foreach (ScenePresence p in allpresences)
  5720. {
  5721. if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive)
  5722. continue;
  5723. // only those old parcel need kills
  5724. if (!IsViewerUIGod && previusParcelID.Equals(p.currentParcelUUID))
  5725. {
  5726. killsToSendme.Add(p); // i dont see them
  5727. }
  5728. else
  5729. {
  5730. viewsToSendto.Add(p); // they see me
  5731. }
  5732. }
  5733. }
  5734. else
  5735. return; // was on a public area also
  5736. } // now on public parcel end
  5737. }
  5738. // send the things
  5739. if (killsToSendto.Count > 0)
  5740. {
  5741. foreach (ScenePresence p in killsToSendto)
  5742. {
  5743. // m_log.Debug("[AVATAR]: killTo: " + Lastname + " " + p.Lastname);
  5744. SendKillTo(p);
  5745. }
  5746. }
  5747. if (killsToSendme.Count > 0)
  5748. {
  5749. foreach (ScenePresence p in killsToSendme)
  5750. {
  5751. // m_log.Debug("[AVATAR]: killToMe: " + Lastname + " " + p.Lastname);
  5752. p.SendKillTo(this);
  5753. }
  5754. }
  5755. if (viewsToSendto.Count > 0)
  5756. {
  5757. foreach (ScenePresence p in viewsToSendto)
  5758. {
  5759. SendViewTo(p);
  5760. }
  5761. }
  5762. if (viewsToSendme.Count > 0 )
  5763. {
  5764. foreach (ScenePresence p in viewsToSendme)
  5765. {
  5766. if (p.IsChildAgent)
  5767. continue;
  5768. // m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname);
  5769. p.SendViewTo(this);
  5770. }
  5771. }
  5772. }
  5773. public void HasMovedAway(bool nearRegion)
  5774. {
  5775. if (nearRegion)
  5776. {
  5777. Scene.AttachmentsModule?.DeleteAttachmentsFromScene(this, true);
  5778. if (!ParcelHideThisAvatar || IsViewerUIGod)
  5779. return;
  5780. List<ScenePresence> allpresences = m_scene.GetScenePresences();
  5781. foreach (ScenePresence p in allpresences)
  5782. {
  5783. if (p.IsDeleted || p == this || p.IsChildAgent || p.ControllingClient == null || !p.ControllingClient.IsActive)
  5784. continue;
  5785. if (p.currentParcelUUID.Equals(m_currentParcelUUID))
  5786. {
  5787. p.SendKillTo(this);
  5788. }
  5789. }
  5790. }
  5791. else
  5792. {
  5793. lock (m_completeMovementLock)
  5794. {
  5795. GodController.HasMovedAway();
  5796. NeedInitialData = -1;
  5797. m_gotRegionHandShake = false;
  5798. }
  5799. List<ScenePresence> allpresences = m_scene.GetScenePresences();
  5800. foreach (ScenePresence p in allpresences)
  5801. {
  5802. if (p == this)
  5803. continue;
  5804. SendKillTo(p);
  5805. if (!p.IsChildAgent)
  5806. p.SendKillTo(this);
  5807. }
  5808. Scene.AttachmentsModule?.DeleteAttachmentsFromScene(this, true);
  5809. }
  5810. }
  5811. // kill with attachs root kills
  5812. public void SendKillTo(ScenePresence p)
  5813. {
  5814. List<uint> ids = new(m_attachments.Count + 1);
  5815. foreach (SceneObjectGroup sog in m_attachments)
  5816. {
  5817. ids.Add(sog.RootPart.LocalId);
  5818. }
  5819. ids.Add(LocalId);
  5820. p.ControllingClient.SendKillObject(ids);
  5821. }
  5822. /*
  5823. // kill with hack
  5824. public void SendKillTo(ScenePresence p)
  5825. {
  5826. foreach (SceneObjectGroup sog in m_attachments)
  5827. p.ControllingClient.SendPartFullUpdate(sog.RootPart, LocalId + 1);
  5828. p.ControllingClient.SendKillObject(new List<uint> { LocalId });
  5829. }
  5830. */
  5831. public void SendViewTo(ScenePresence p)
  5832. {
  5833. SendAvatarDataToAgentNF(p);
  5834. SendAppearanceToAgent(p);
  5835. Animator?.SendAnimPackToClient(p.ControllingClient);
  5836. SendAttachmentsToAgentNF(p);
  5837. }
  5838. public void SetAnimationOverride(string animState, UUID animID)
  5839. {
  5840. Overrides.SetOverride(animState, animID);
  5841. //Animator.SendAnimPack();
  5842. Animator.ForceUpdateMovementAnimations();
  5843. }
  5844. public UUID GetAnimationOverride(string animState)
  5845. {
  5846. return Overrides.GetOverriddenAnimation(animState);
  5847. }
  5848. public bool TryGetAnimationOverride(string animState, out UUID animID)
  5849. {
  5850. return Overrides.TryGetOverriddenAnimation(animState, out animID);
  5851. }
  5852. }
  5853. }