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