Scene.cc 202 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _SCENE_H_
  23. #include "Scene.h"
  24. #endif
  25. #ifndef _DGL_H_
  26. #include "graphics/dgl.h"
  27. #endif
  28. #ifndef _CONSOLETYPES_H_
  29. #include "console/consoleTypes.h"
  30. #endif
  31. #ifndef _BITSTREAM_H_
  32. #include "io/bitStream.h"
  33. #endif
  34. #ifndef _SCENE_OBJECT_H_
  35. #include "2d/sceneobject/SceneObject.h"
  36. #endif
  37. #ifndef _CONTACT_FILTER_H_
  38. #include "ContactFilter.h"
  39. #endif
  40. #ifndef _SCENE_RENDER_OBJECT_H_
  41. #include "2d/SceneRenderObject.h"
  42. #endif
  43. #ifndef _SCENE_CONTROLLER_H_
  44. #include "2d/controllers/core/SceneController.h"
  45. #endif
  46. #ifndef _PARTICLE_SYSTEM_H_
  47. #include "2d/core/ParticleSystem.h"
  48. #endif
  49. // Script bindings.
  50. #include "Scene_ScriptBinding.h"
  51. // Debug Profiling.
  52. #include "debug/profiler.h"
  53. //------------------------------------------------------------------------------
  54. SimObjectPtr<Scene> Scene::LoadingScene = NULL;
  55. //------------------------------------------------------------------------------
  56. static ContactFilter mContactFilter;
  57. // Scene counter.
  58. static U32 sSceneCount = 0;
  59. static U32 sSceneMasterIndex = 0;
  60. // Joint custom node names.
  61. static StringTableEntry jointCustomNodeName = StringTable->insert( "Joints" );
  62. static StringTableEntry jointCollideConnectedName = StringTable->insert( "CollideConnected" );
  63. static StringTableEntry jointLocalAnchorAName = StringTable->insert( "LocalAnchorA" );
  64. static StringTableEntry jointLocalAnchorBName = StringTable->insert( "LocalAnchorB" );
  65. static StringTableEntry jointDistanceNodeName = StringTable->insert( "Distance" );
  66. static StringTableEntry jointDistanceLengthName = StringTable->insert( "Length" );
  67. static StringTableEntry jointDistanceFrequencyName = StringTable->insert( "Frequency" );
  68. static StringTableEntry jointDistanceDampingRatioName = StringTable->insert( "DampingRatio" );
  69. static StringTableEntry jointRopeNodeName = StringTable->insert( "Rope" );
  70. static StringTableEntry jointRopeMaxLengthName = StringTable->insert( "MaxLength" );
  71. static StringTableEntry jointRevoluteNodeName = StringTable->insert( "Revolute" );
  72. static StringTableEntry jointRevoluteLimitLowerAngleName = StringTable->insert( "LowerAngle" );
  73. static StringTableEntry jointRevoluteLimitUpperAngleName = StringTable->insert( "UpperAngle" );
  74. static StringTableEntry jointRevoluteMotorSpeedName = StringTable->insert( "MotorSpeed" );
  75. static StringTableEntry jointRevoluteMotorMaxTorqueName = StringTable->insert( "MaxTorque" );
  76. static StringTableEntry jointWeldNodeName = StringTable->insert( "Weld" );
  77. static StringTableEntry jointWeldFrequencyName = jointDistanceFrequencyName;
  78. static StringTableEntry jointWeldDampingRatioName = jointDistanceDampingRatioName;
  79. static StringTableEntry jointWheelNodeName = StringTable->insert( "Wheel" );
  80. static StringTableEntry jointWheelWorldAxisName = StringTable->insert( "WorldAxis" );
  81. static StringTableEntry jointWheelMotorSpeedName = StringTable->insert( "MotorSpeed" );
  82. static StringTableEntry jointWheelMotorMaxTorqueName = jointRevoluteMotorMaxTorqueName;
  83. static StringTableEntry jointWheelFrequencyName = jointDistanceFrequencyName;
  84. static StringTableEntry jointWheelDampingRatioName = jointDistanceDampingRatioName;
  85. static StringTableEntry jointFrictionNodeName = StringTable->insert( "Friction" );
  86. static StringTableEntry jointFrictionMaxForceName = StringTable->insert( "MaxForce" );
  87. static StringTableEntry jointFrictionMaxTorqueName = jointRevoluteMotorMaxTorqueName;
  88. static StringTableEntry jointPrismaticNodeName = StringTable->insert( "Prismatic" );
  89. static StringTableEntry jointPrismaticWorldAxisName = jointWheelWorldAxisName;
  90. static StringTableEntry jointPrismaticLimitLowerTransName = StringTable->insert( "LowerTranslation" );
  91. static StringTableEntry jointPrismaticLimitUpperTransName = StringTable->insert( "UpperTranslation" );
  92. static StringTableEntry jointPrismaticMotorSpeedName = jointRevoluteMotorSpeedName;
  93. static StringTableEntry jointPrismaticMotorMaxForceName = jointFrictionMaxForceName;
  94. static StringTableEntry jointPulleyNodeName = StringTable->insert( "Pulley" );
  95. static StringTableEntry jointPulleyGroundAnchorAName = StringTable->insert( "GroundAnchorA" );
  96. static StringTableEntry jointPulleyGroundAnchorBName = StringTable->insert( "GroundAnchorB" );
  97. static StringTableEntry jointPulleyLengthAName = StringTable->insert( "LengthA" );
  98. static StringTableEntry jointPulleyLengthBName = StringTable->insert( "LengthB" );
  99. static StringTableEntry jointPulleyRatioName = StringTable->insert( "Ratio" );
  100. static StringTableEntry jointTargetNodeName = StringTable->insert( "Target" );
  101. static StringTableEntry jointTargetWorldTargetName = StringTable->insert( "WorldTarget" );
  102. static StringTableEntry jointTargetMaxForceName = StringTable->insert( jointFrictionMaxForceName );
  103. static StringTableEntry jointTargetFrequencyName = jointDistanceFrequencyName;
  104. static StringTableEntry jointTargetDampingRatioName = jointDistanceDampingRatioName;
  105. static StringTableEntry jointMotorNodeName = StringTable->insert( "Motor" );
  106. static StringTableEntry jointMotorLinearOffsetName = StringTable->insert( "LinearOffset" );
  107. static StringTableEntry jointMotorAngularOffsetName = StringTable->insert( "AngularOffset" );
  108. static StringTableEntry jointMotorMaxForceName = jointFrictionMaxForceName;
  109. static StringTableEntry jointMotorMaxTorqueName = jointRevoluteMotorMaxTorqueName;
  110. static StringTableEntry jointMotorCorrectionFactorName = StringTable->insert( "CorrectionFactor" );
  111. // Controller custom node names.
  112. static StringTableEntry controllerCustomNodeName = StringTable->insert( "Controllers" );
  113. // Asset preload custom node names.
  114. static StringTableEntry assetPreloadNodeName = StringTable->insert( "AssetPreloads" );
  115. static StringTableEntry assetNodeName = StringTable->insert( "Asset" );
  116. //-----------------------------------------------------------------------------
  117. Scene::Scene() :
  118. /// World.
  119. mpWorld(NULL),
  120. mWorldGravity(0.0f, 0.0f),
  121. mVelocityIterations(8),
  122. mPositionIterations(3),
  123. /// Joint access.
  124. mJointMasterId(1),
  125. /// Scene time.
  126. mSceneTime(0.0f),
  127. mScenePause(false),
  128. /// Debug and metrics.
  129. mDebugMask(0X00000000),
  130. mpDebugSceneObject(NULL),
  131. /// Window rendering.
  132. mpCurrentRenderWindow(NULL),
  133. /// Miscellaneous.
  134. mIsEditorScene(0),
  135. mUpdateCallback(false),
  136. mRenderCallback(false),
  137. mSceneIndex(0)
  138. {
  139. // Set Vector Associations.
  140. VECTOR_SET_ASSOCIATION( mSceneObjects );
  141. VECTOR_SET_ASSOCIATION( mDeleteRequests );
  142. VECTOR_SET_ASSOCIATION( mDeleteRequestsTemp );
  143. VECTOR_SET_ASSOCIATION( mEndContacts );
  144. VECTOR_SET_ASSOCIATION( mAssetPreloads );
  145. // Initialize layer sort mode.
  146. for ( U32 n = 0; n < MAX_LAYERS_SUPPORTED; ++n )
  147. mLayerSortModes[n] = SceneRenderQueue::RENDER_SORT_NEWEST;
  148. // Set debug stats for batch renderer.
  149. mBatchRenderer.setDebugStats( &mDebugStats );
  150. // Register the scene controllers set.
  151. mControllers = new SimSet();
  152. mControllers->registerObject();
  153. // Assign scene index.
  154. mSceneIndex = ++sSceneMasterIndex;
  155. sSceneCount++;
  156. }
  157. //-----------------------------------------------------------------------------
  158. Scene::~Scene()
  159. {
  160. // Unregister the scene controllers set.
  161. if ( mControllers.notNull() )
  162. mControllers->deleteObject();
  163. // Decrease scene count.
  164. --sSceneCount;
  165. }
  166. //-----------------------------------------------------------------------------
  167. bool Scene::onAdd()
  168. {
  169. // Call Parent.
  170. if(!Parent::onAdd())
  171. return false;
  172. // Create physics world.
  173. mpWorld = new b2World( mWorldGravity );
  174. // Set contact filter.
  175. mpWorld->SetContactFilter( &mContactFilter );
  176. // Set contact listener.
  177. mpWorld->SetContactListener( this );
  178. // Set destruction listener.
  179. mpWorld->SetDestructionListener( this );
  180. // Create ground body.
  181. b2BodyDef groundBodyDef;
  182. groundBodyDef.userData = static_cast<PhysicsProxy*>(this);
  183. mpGroundBody = mpWorld->CreateBody(&groundBodyDef);
  184. mpGroundBody->SetAwake( false );
  185. // Create world query.
  186. mpWorldQuery = new WorldQuery(this);
  187. // Set loading scene.
  188. Scene::LoadingScene = this;
  189. // Turn-on tick processing.
  190. setProcessTicks( true );
  191. // Return Okay.
  192. return true;
  193. }
  194. //-----------------------------------------------------------------------------
  195. void Scene::onRemove()
  196. {
  197. // Turn-off tick processing.
  198. setProcessTicks( false );
  199. // Clear Scene.
  200. clearScene();
  201. // Process Delete Requests.
  202. processDeleteRequests(true);
  203. // Delete ground body.
  204. mpWorld->DestroyBody( mpGroundBody );
  205. mpGroundBody = NULL;
  206. // Delete physics world and world query.
  207. delete mpWorldQuery;
  208. delete mpWorld;
  209. mpWorldQuery = NULL;
  210. mpWorld = NULL;
  211. // Detach All Scene Windows.
  212. detachAllSceneWindows();
  213. // Call Parent. Clear scene handles all the object removal, so we can skip
  214. // that part and just do the sim-object stuff.
  215. SimObject::onRemove();
  216. }
  217. //-----------------------------------------------------------------------------
  218. void Scene::onDeleteNotify( SimObject* object )
  219. {
  220. // Ignore if we're not monitoring a debug banner scene object.
  221. if ( mpDebugSceneObject == NULL )
  222. return;
  223. // Ignore if it's not the one we're monitoring.
  224. SceneObject* pSceneObject = dynamic_cast<SceneObject*>( object );
  225. if ( pSceneObject != mpDebugSceneObject )
  226. return;
  227. // Reset the monitored scene object.
  228. mpDebugSceneObject = NULL;
  229. }
  230. //-----------------------------------------------------------------------------
  231. void Scene::initPersistFields()
  232. {
  233. // Call Parent.
  234. Parent::initPersistFields();
  235. // Physics.
  236. addProtectedField("Gravity", TypeVector2, Offset(mWorldGravity, Scene), &setGravity, &getGravity, &writeGravity, "" );
  237. addField("VelocityIterations", TypeS32, Offset(mVelocityIterations, Scene), &writeVelocityIterations, "" );
  238. addField("PositionIterations", TypeS32, Offset(mPositionIterations, Scene), &writePositionIterations, "" );
  239. // Layer sort modes.
  240. char buffer[64];
  241. for ( U32 n = 0; n < MAX_LAYERS_SUPPORTED; n++ )
  242. {
  243. dSprintf( buffer, 64, "layerSortMode%d", n );
  244. addField( buffer, TypeEnum, OffsetNonConst(mLayerSortModes[n], Scene), &writeLayerSortMode, 1, &SceneRenderQueue::renderSortTable, "");
  245. }
  246. addProtectedField("Controllers", TypeSimObjectPtr, Offset(mControllers, Scene), &defaultProtectedNotSetFn, &defaultProtectedGetFn, &defaultProtectedNotWriteFn, "The scene controllers to use.");
  247. // Callbacks.
  248. addField("UpdateCallback", TypeBool, Offset(mUpdateCallback, Scene), &writeUpdateCallback, "");
  249. addField("RenderCallback", TypeBool, Offset(mRenderCallback, Scene), &writeRenderCallback, "");
  250. }
  251. //-----------------------------------------------------------------------------
  252. void Scene::BeginContact( b2Contact* pContact )
  253. {
  254. // Ignore contact if it's not a touching contact.
  255. if ( !pContact->IsTouching() )
  256. return;
  257. PROFILE_SCOPE(Scene_BeginContact);
  258. // Fetch fixtures.
  259. b2Fixture* pFixtureA = pContact->GetFixtureA();
  260. b2Fixture* pFixtureB = pContact->GetFixtureB();
  261. // Fetch physics proxies.
  262. PhysicsProxy* pPhysicsProxyA = static_cast<PhysicsProxy*>(pFixtureA->GetBody()->GetUserData());
  263. PhysicsProxy* pPhysicsProxyB = static_cast<PhysicsProxy*>(pFixtureB->GetBody()->GetUserData());
  264. // Ignore stuff that's not a scene object.
  265. if ( pPhysicsProxyA->getPhysicsProxyType() != PhysicsProxy::PHYSIC_PROXY_SCENEOBJECT ||
  266. pPhysicsProxyB->getPhysicsProxyType() != PhysicsProxy::PHYSIC_PROXY_SCENEOBJECT )
  267. {
  268. return;
  269. }
  270. // Fetch scene objects.
  271. SceneObject* pSceneObjectA = static_cast<SceneObject*>(pPhysicsProxyA);
  272. SceneObject* pSceneObjectB = static_cast<SceneObject*>(pPhysicsProxyB);
  273. // Initialize the contact.
  274. TickContact tickContact;
  275. tickContact.initialize( pContact, pSceneObjectA, pSceneObjectB, pFixtureA, pFixtureB );
  276. // Add contact.
  277. mBeginContacts.insert( pContact, tickContact );
  278. }
  279. //-----------------------------------------------------------------------------
  280. void Scene::EndContact( b2Contact* pContact )
  281. {
  282. PROFILE_SCOPE(Scene_EndContact);
  283. // Fetch fixtures.
  284. b2Fixture* pFixtureA = pContact->GetFixtureA();
  285. b2Fixture* pFixtureB = pContact->GetFixtureB();
  286. // Fetch physics proxies.
  287. PhysicsProxy* pPhysicsProxyA = static_cast<PhysicsProxy*>(pFixtureA->GetBody()->GetUserData());
  288. PhysicsProxy* pPhysicsProxyB = static_cast<PhysicsProxy*>(pFixtureB->GetBody()->GetUserData());
  289. // Ignore stuff that's not a scene object.
  290. if ( pPhysicsProxyA->getPhysicsProxyType() != PhysicsProxy::PHYSIC_PROXY_SCENEOBJECT ||
  291. pPhysicsProxyB->getPhysicsProxyType() != PhysicsProxy::PHYSIC_PROXY_SCENEOBJECT )
  292. {
  293. return;
  294. }
  295. // Fetch scene objects.
  296. SceneObject* pSceneObjectA = static_cast<SceneObject*>(pPhysicsProxyA);
  297. SceneObject* pSceneObjectB = static_cast<SceneObject*>(pPhysicsProxyB);
  298. // Initialize the contact.
  299. TickContact tickContact;
  300. tickContact.initialize( pContact, pSceneObjectA, pSceneObjectB, pFixtureA, pFixtureB );
  301. // Add contact.
  302. mEndContacts.push_back( tickContact );
  303. }
  304. //-----------------------------------------------------------------------------
  305. void Scene::PostSolve( b2Contact* pContact, const b2ContactImpulse* pImpulse )
  306. {
  307. // Find contact mapping.
  308. typeContactHash::iterator contactItr = mBeginContacts.find( pContact );
  309. // Finish if we didn't find the contact.
  310. if ( contactItr == mBeginContacts.end() )
  311. return;
  312. // Fetch contact.
  313. TickContact& tickContact = contactItr->value;
  314. // Add the impulse.
  315. for ( U32 index = 0; index < b2_maxManifoldPoints; ++index )
  316. {
  317. tickContact.mNormalImpulses[index] += pImpulse->normalImpulses[index];
  318. tickContact.mTangentImpulses[index] += pImpulse->tangentImpulses[index];
  319. }
  320. }
  321. //-----------------------------------------------------------------------------
  322. void Scene::forwardContacts( void )
  323. {
  324. // Debug Profiling.
  325. PROFILE_SCOPE(Scene_ForwardContacts);
  326. // Iterate end contacts.
  327. for( typeContactVector::iterator contactItr = mEndContacts.begin(); contactItr != mEndContacts.end(); ++contactItr )
  328. {
  329. // Fetch tick contact.
  330. TickContact& tickContact = *contactItr;
  331. // Inform the scene objects.
  332. tickContact.mpSceneObjectA->onEndCollision( tickContact );
  333. tickContact.mpSceneObjectB->onEndCollision( tickContact );
  334. }
  335. // Iterate begin contacts.
  336. for( typeContactHash::iterator contactItr = mBeginContacts.begin(); contactItr != mBeginContacts.end(); ++contactItr )
  337. {
  338. // Fetch tick contact.
  339. TickContact& tickContact = contactItr->value;
  340. // Inform the scene objects.
  341. tickContact.mpSceneObjectA->onBeginCollision( tickContact );
  342. tickContact.mpSceneObjectB->onBeginCollision( tickContact );
  343. }
  344. }
  345. //-----------------------------------------------------------------------------
  346. void Scene::dispatchBeginContactCallbacks( void )
  347. {
  348. // Debug Profiling.
  349. PROFILE_SCOPE(Scene_DispatchBeginContactCallbacks);
  350. // Sanity!
  351. AssertFatal( b2_maxManifoldPoints == 2, "Scene::dispatchBeginContactCallbacks() - Invalid assumption about max manifold points." );
  352. // Fetch contact count.
  353. const U32 contactCount = mBeginContacts.size();
  354. // Finish if no contacts.
  355. if ( contactCount == 0 )
  356. return;
  357. // Iterate all contacts.
  358. for ( typeContactHash::iterator contactItr = mBeginContacts.begin(); contactItr != mBeginContacts.end(); ++contactItr )
  359. {
  360. // Fetch contact.
  361. const TickContact& tickContact = contactItr->value;
  362. // Fetch scene objects.
  363. SceneObject* pSceneObjectA = tickContact.mpSceneObjectA;
  364. SceneObject* pSceneObjectB = tickContact.mpSceneObjectB;
  365. // Skip if either object is being deleted.
  366. if ( pSceneObjectA->isBeingDeleted() || pSceneObjectB->isBeingDeleted() )
  367. continue;
  368. // Skip if both objects don't have collision callback active.
  369. if ( !pSceneObjectA->getCollisionCallback() && !pSceneObjectB->getCollisionCallback() )
  370. continue;
  371. // Fetch normal and contact points.
  372. const U32& pointCount = tickContact.mPointCount;
  373. const b2Vec2& normal = tickContact.mWorldManifold.normal;
  374. const b2Vec2& point1 = tickContact.mWorldManifold.points[0];
  375. const b2Vec2& point2 = tickContact.mWorldManifold.points[1];
  376. const S32 shapeIndexA = pSceneObjectA->getCollisionShapeIndex( tickContact.mpFixtureA );
  377. const S32 shapeIndexB = pSceneObjectB->getCollisionShapeIndex( tickContact.mpFixtureB );
  378. // Sanity!
  379. AssertFatal( shapeIndexA >= 0, "Scene::dispatchBeginContactCallbacks() - Cannot find shape index reported on physics proxy of a fixture." );
  380. AssertFatal( shapeIndexB >= 0, "Scene::dispatchBeginContactCallbacks() - Cannot find shape index reported on physics proxy of a fixture." );
  381. // Fetch collision impulse information
  382. const F32 normalImpulse1 = tickContact.mNormalImpulses[0];
  383. const F32 normalImpulse2 = tickContact.mNormalImpulses[1];
  384. const F32 tangentImpulse1 = tickContact.mTangentImpulses[0];
  385. const F32 tangentImpulse2 = tickContact.mTangentImpulses[1];
  386. // Format objects.
  387. char sceneObjectABuffer[16];
  388. char sceneObjectBBuffer[16];
  389. dSprintf( sceneObjectABuffer, sizeof(sceneObjectABuffer), "%d", pSceneObjectA->getId() );
  390. dSprintf( sceneObjectBBuffer, sizeof(sceneObjectBBuffer), "%d", pSceneObjectB->getId() );
  391. // Format miscellaneous information twice so object b can see things from his point of view.
  392. char miscInfoBufferA[128];
  393. char miscInfoBufferB[128];
  394. if ( pointCount == 2 )
  395. {
  396. dSprintf(miscInfoBufferA, sizeof(miscInfoBufferA),
  397. "%d %d %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f",
  398. shapeIndexA, shapeIndexB,
  399. -normal.x, -normal.y,
  400. point1.x, point1.y,
  401. normalImpulse1,
  402. tangentImpulse1,
  403. point2.x, point2.y,
  404. normalImpulse2,
  405. tangentImpulse2 );
  406. dSprintf(miscInfoBufferB, sizeof(miscInfoBufferB),
  407. "%d %d %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f",
  408. shapeIndexB, shapeIndexA,
  409. normal.x, normal.y,
  410. point1.x, point1.y,
  411. normalImpulse1,
  412. tangentImpulse1,
  413. point2.x, point2.y,
  414. normalImpulse2,
  415. tangentImpulse2);
  416. }
  417. else if ( pointCount == 1 )
  418. {
  419. dSprintf(miscInfoBufferA, sizeof(miscInfoBufferA),
  420. "%d %d %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f",
  421. shapeIndexA, shapeIndexB,
  422. -normal.x, -normal.y,
  423. point1.x, point1.y,
  424. normalImpulse1,
  425. tangentImpulse1 );
  426. dSprintf(miscInfoBufferB, sizeof(miscInfoBufferB),
  427. "%d %d %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f",
  428. shapeIndexB, shapeIndexA,
  429. normal.x, normal.y,
  430. point1.x, point1.y,
  431. normalImpulse1,
  432. tangentImpulse1);
  433. }
  434. else
  435. {
  436. dSprintf(miscInfoBufferA, sizeof(miscInfoBufferA),
  437. "%d %d",
  438. shapeIndexA, shapeIndexB );
  439. dSprintf(miscInfoBufferB, sizeof(miscInfoBufferB),
  440. "%d %d",
  441. shapeIndexB, shapeIndexA);
  442. }
  443. // Does the scene handle the collision callback?
  444. Namespace* pNamespace = getNamespace();
  445. if ( pNamespace != NULL && pNamespace->lookup( StringTable->insert( "onSceneCollision" ) ) != NULL )
  446. {
  447. // Yes, so perform script callback on the Scene.
  448. Con::executef( this, 4, "onSceneCollision",
  449. sceneObjectABuffer,
  450. sceneObjectBBuffer,
  451. miscInfoBufferA );
  452. }
  453. else
  454. {
  455. // No, so call it on its behaviors.
  456. const char* args[5] = { "onSceneCollision", "", sceneObjectABuffer, sceneObjectBBuffer, miscInfoBufferA };
  457. callOnBehaviors( 5, args );
  458. }
  459. // Is object A allowed to collide with object B?
  460. if ( (pSceneObjectA->mCollisionGroupMask & pSceneObjectB->mSceneGroupMask) != 0 &&
  461. (pSceneObjectA->mCollisionLayerMask & pSceneObjectB->mSceneLayerMask) != 0 )
  462. {
  463. // Yes, so does it handle the collision callback?
  464. if ( pSceneObjectA->isMethod("onCollision") )
  465. {
  466. // Yes, so perform the script callback on it.
  467. Con::executef( pSceneObjectA, 3, "onCollision",
  468. sceneObjectBBuffer,
  469. miscInfoBufferA );
  470. }
  471. else
  472. {
  473. // No, so call it on its behaviors.
  474. const char* args[4] = { "onCollision", "", sceneObjectBBuffer, miscInfoBufferA };
  475. pSceneObjectA->callOnBehaviors( 4, args );
  476. }
  477. }
  478. // Is object B allowed to collide with object A?
  479. if ( (pSceneObjectB->mCollisionGroupMask & pSceneObjectA->mSceneGroupMask) != 0 &&
  480. (pSceneObjectB->mCollisionLayerMask & pSceneObjectA->mSceneLayerMask) != 0 )
  481. {
  482. // Yes, so does it handle the collision callback?
  483. if ( pSceneObjectB->isMethod("onCollision") )
  484. {
  485. // Yes, so perform the script callback on it.
  486. Con::executef( pSceneObjectB, 3, "onCollision",
  487. sceneObjectABuffer,
  488. miscInfoBufferB );
  489. }
  490. else
  491. {
  492. // No, so call it on its behaviors.
  493. const char* args[4] = { "onCollision", "", sceneObjectABuffer, miscInfoBufferB };
  494. pSceneObjectB->callOnBehaviors( 4, args );
  495. }
  496. }
  497. }
  498. }
  499. //-----------------------------------------------------------------------------
  500. void Scene::dispatchEndContactCallbacks( void )
  501. {
  502. // Debug Profiling.
  503. PROFILE_SCOPE(Scene_DispatchEndContactCallbacks);
  504. // Sanity!
  505. AssertFatal( b2_maxManifoldPoints == 2, "Scene::dispatchEndContactCallbacks() - Invalid assumption about max manifold points." );
  506. // Fetch contact count.
  507. const U32 contactCount = mEndContacts.size();
  508. // Finish if no contacts.
  509. if ( contactCount == 0 )
  510. return;
  511. // Iterate all contacts.
  512. for ( typeContactVector::iterator contactItr = mEndContacts.begin(); contactItr != mEndContacts.end(); ++contactItr )
  513. {
  514. // Fetch contact.
  515. const TickContact& tickContact = *contactItr;
  516. // Fetch scene objects.
  517. SceneObject* pSceneObjectA = tickContact.mpSceneObjectA;
  518. SceneObject* pSceneObjectB = tickContact.mpSceneObjectB;
  519. // Skip if either object is being deleted.
  520. if ( pSceneObjectA->isBeingDeleted() || pSceneObjectB->isBeingDeleted() )
  521. continue;
  522. // Skip if both objects don't have collision callback active.
  523. if ( !pSceneObjectA->getCollisionCallback() && !pSceneObjectB->getCollisionCallback() )
  524. continue;
  525. // Fetch shape index.
  526. const S32 shapeIndexA = pSceneObjectA->getCollisionShapeIndex( tickContact.mpFixtureA );
  527. const S32 shapeIndexB = pSceneObjectB->getCollisionShapeIndex( tickContact.mpFixtureB );
  528. // Sanity!
  529. AssertFatal( shapeIndexA >= 0, "Scene::dispatchEndContactCallbacks() - Cannot find shape index reported on physics proxy of a fixture." );
  530. AssertFatal( shapeIndexB >= 0, "Scene::dispatchEndContactCallbacks() - Cannot find shape index reported on physics proxy of a fixture." );
  531. // Format objects.
  532. char sceneObjectABuffer[16];
  533. char sceneObjectBBuffer[16];
  534. dSprintf( sceneObjectABuffer, sizeof(sceneObjectABuffer), "%d", pSceneObjectA->getId() );
  535. dSprintf( sceneObjectBBuffer, sizeof(sceneObjectBBuffer), "%d", pSceneObjectB->getId() );
  536. // Format miscellaneous information.
  537. char miscInfoBuffer[32];
  538. dSprintf(miscInfoBuffer, sizeof(miscInfoBuffer), "%d %d", shapeIndexA, shapeIndexB );
  539. // Does the scene handle the collision callback?
  540. Namespace* pNamespace = getNamespace();
  541. if ( pNamespace != NULL && pNamespace->lookup( StringTable->insert( "onSceneEndCollision" ) ) != NULL )
  542. {
  543. // Yes, so does the scene handle the collision callback?
  544. Con::executef( this, 4, "onSceneEndCollision",
  545. sceneObjectABuffer,
  546. sceneObjectBBuffer,
  547. miscInfoBuffer );
  548. }
  549. else
  550. {
  551. // No, so call it on its behaviors.
  552. const char* args[5] = { "onSceneEndCollision", "", sceneObjectABuffer, sceneObjectBBuffer, miscInfoBuffer };
  553. callOnBehaviors( 5, args );
  554. }
  555. // Is object A allowed to collide with object B?
  556. if ( (pSceneObjectA->mCollisionGroupMask & pSceneObjectB->mSceneGroupMask) != 0 &&
  557. (pSceneObjectA->mCollisionLayerMask & pSceneObjectB->mSceneLayerMask) != 0 )
  558. {
  559. // Yes, so does it handle the collision callback?
  560. if ( pSceneObjectA->isMethod("onEndCollision") )
  561. {
  562. // Yes, so perform the script callback on it.
  563. Con::executef( pSceneObjectA, 3, "onEndCollision",
  564. sceneObjectBBuffer,
  565. miscInfoBuffer );
  566. }
  567. else
  568. {
  569. // No, so call it on its behaviors.
  570. const char* args[4] = { "onEndCollision", "", sceneObjectBBuffer, miscInfoBuffer };
  571. pSceneObjectA->callOnBehaviors( 4, args );
  572. }
  573. }
  574. // Is object B allowed to collide with object A?
  575. if ( (pSceneObjectB->mCollisionGroupMask & pSceneObjectA->mSceneGroupMask) != 0 &&
  576. (pSceneObjectB->mCollisionLayerMask & pSceneObjectA->mSceneLayerMask) != 0 )
  577. {
  578. // Yes, so does it handle the collision callback?
  579. if ( pSceneObjectB->isMethod("onEndCollision") )
  580. {
  581. // Yes, so perform the script callback on it.
  582. Con::executef( pSceneObjectB, 3, "onEndCollision",
  583. sceneObjectABuffer,
  584. miscInfoBuffer );
  585. }
  586. else
  587. {
  588. // No, so call it on its behaviors.
  589. const char* args[4] = { "onEndCollision", "", sceneObjectABuffer, miscInfoBuffer };
  590. pSceneObjectB->callOnBehaviors( 4, args );
  591. }
  592. }
  593. }
  594. }
  595. //-----------------------------------------------------------------------------
  596. void Scene::processTick( void )
  597. {
  598. // Debug Profiling.
  599. PROFILE_SCOPE(Scene_ProcessTick);
  600. // Finish if the Scene is not added to the simulation.
  601. if ( !isProperlyAdded() )
  602. return;
  603. // Process Delete Requests.
  604. processDeleteRequests(false);
  605. // Update debug stats.
  606. mDebugStats.fps = Con::getFloatVariable("fps::framePeriod", 0.0f);
  607. mDebugStats.frameCount = (U32)Con::getIntVariable("fps::frameCount", 0);
  608. mDebugStats.bodyCount = (U32)mpWorld->GetBodyCount();
  609. mDebugStats.jointCount = (U32)mpWorld->GetJointCount();
  610. mDebugStats.contactCount = (U32)mpWorld->GetContactCount();
  611. mDebugStats.proxyCount = (U32)mpWorld->GetProxyCount();
  612. mDebugStats.objectsCount = (U32)mSceneObjects.size();
  613. mDebugStats.worldProfile = mpWorld->GetProfile();
  614. // Set particle stats.
  615. mDebugStats.particlesAlloc = ParticleSystem::Instance->getAllocatedParticleCount();
  616. mDebugStats.particlesUsed = ParticleSystem::Instance->getActiveParticleCount();
  617. mDebugStats.particlesFree = mDebugStats.particlesAlloc - mDebugStats.particlesUsed;
  618. // Finish if scene is paused.
  619. if ( !getScenePause() )
  620. {
  621. // Reset object stats.
  622. U32 objectsEnabled = 0;
  623. U32 objectsVisible = 0;
  624. U32 objectsAwake = 0;
  625. // Fetch if a "normal" i.e. non-editor scene.
  626. const bool isNormalScene = !getIsEditorScene();
  627. // Update scene time.
  628. mSceneTime += Tickable::smTickSec;
  629. // Clear ticked scene objects.
  630. mTickedSceneObjects.clear();
  631. // Iterate scene objects.
  632. for( S32 n = 0; n < mSceneObjects.size(); ++n )
  633. {
  634. // Fetch scene object.
  635. SceneObject* pSceneObject = mSceneObjects[n];
  636. // Update awake/asleep counts.
  637. if ( pSceneObject->getAwake() )
  638. objectsAwake++;
  639. // Update visible.
  640. if ( pSceneObject->getVisible() )
  641. objectsVisible++;
  642. // Push scene object if it's eligible for ticking.
  643. if ( pSceneObject->isEnabled() )
  644. {
  645. // Update enabled.
  646. objectsEnabled++;
  647. // Add to ticked objects if object is not being deleted and this is a "normal" scene or
  648. // the object is marked as allowing editor ticks.
  649. if ( !pSceneObject->isBeingDeleted() && (isNormalScene || pSceneObject->getIsEditorTickAllowed() ) )
  650. mTickedSceneObjects.push_back( pSceneObject );
  651. }
  652. }
  653. // Update object stats.
  654. mDebugStats.objectsEnabled = objectsEnabled;
  655. mDebugStats.objectsVisible = objectsVisible;
  656. mDebugStats.objectsAwake = objectsAwake;
  657. // Debug Status Reference.
  658. DebugStats* pDebugStats = &mDebugStats;
  659. // Fetch ticked scene object count.
  660. const S32 tickedSceneObjectCount = mTickedSceneObjects.size();
  661. // ****************************************************
  662. // Pre-integrate objects.
  663. // ****************************************************
  664. // Iterate ticked scene objects.
  665. for ( S32 i = 0; i < tickedSceneObjectCount; ++i )
  666. {
  667. // Debug Profiling.
  668. PROFILE_SCOPE(Scene_PreIntegrate);
  669. // Pre-integrate.
  670. mTickedSceneObjects[i]->preIntegrate( mSceneTime, Tickable::smTickSec, pDebugStats );
  671. }
  672. // ****************************************************
  673. // Integrate controllers.
  674. // ****************************************************
  675. // Fetch the controller set.
  676. SimSet* pControllerSet = getControllers();
  677. // Do we have any scene controllers?
  678. if ( pControllerSet != NULL )
  679. {
  680. // Debug Profiling.
  681. PROFILE_SCOPE(Scene_IntegrateSceneControllers);
  682. // Yes, so fetch scene controller count.
  683. const S32 sceneControllerCount = (S32)pControllerSet->size();
  684. // Iterate scene controllers.
  685. for( S32 i = 0; i < sceneControllerCount; i++ )
  686. {
  687. // Fetch the scene controller.
  688. SceneController* pController = dynamic_cast<SceneController*>((*pControllerSet)[i]);
  689. // Skip if not a controller.
  690. if ( pController == NULL )
  691. continue;
  692. // Integrate.
  693. pController->integrate( this, mSceneTime, Tickable::smTickSec, pDebugStats );
  694. }
  695. }
  696. // Debug Profiling.
  697. PROFILE_START(Scene_IntegratePhysicsSystem);
  698. // Reset contacts.
  699. mBeginContacts.clear();
  700. mEndContacts.clear();
  701. // Only step the physics if a "normal" scene.
  702. if ( isNormalScene )
  703. {
  704. // Step the physics.
  705. mpWorld->Step( Tickable::smTickSec, mVelocityIterations, mPositionIterations );
  706. }
  707. // Debug Profiling.
  708. PROFILE_END(); // Scene_IntegratePhysicsSystem
  709. // Forward the contacts.
  710. forwardContacts();
  711. // ****************************************************
  712. // Integrate objects.
  713. // ****************************************************
  714. // Iterate ticked scene objects.
  715. for ( S32 i = 0; i < tickedSceneObjectCount; ++i )
  716. {
  717. // Debug Profiling.
  718. PROFILE_SCOPE(Scene_IntegrateObject);
  719. // Integrate.
  720. mTickedSceneObjects[i]->integrateObject( mSceneTime, Tickable::smTickSec, pDebugStats );
  721. }
  722. // ****************************************************
  723. // Post-Integrate Stage.
  724. // ****************************************************
  725. // Iterate ticked scene objects.
  726. for ( S32 i = 0; i < tickedSceneObjectCount; ++i )
  727. {
  728. // Debug Profiling.
  729. PROFILE_SCOPE(Scene_PostIntegrate);
  730. // Post-integrate.
  731. mTickedSceneObjects[i]->postIntegrate( mSceneTime, Tickable::smTickSec, pDebugStats );
  732. }
  733. // Scene update callback.
  734. if( mUpdateCallback )
  735. {
  736. // Debug Profiling.
  737. PROFILE_SCOPE(Scene_OnSceneUpdatetCallback);
  738. Con::executef( this, 1, "onSceneUpdate" );
  739. }
  740. // Only dispatch contacts if a "normal" scene.
  741. if ( isNormalScene )
  742. {
  743. // Dispatch contacts callbacks.
  744. dispatchEndContactCallbacks();
  745. dispatchBeginContactCallbacks();
  746. }
  747. // Clear ticked scene objects.
  748. mTickedSceneObjects.clear();
  749. }
  750. // Update debug stat ranges.
  751. mDebugStats.updateRanges();
  752. }
  753. //-----------------------------------------------------------------------------
  754. void Scene::interpolateTick( F32 timeDelta )
  755. {
  756. // Finish if scene is paused.
  757. if ( getScenePause() ) return;
  758. // Debug Profiling.
  759. PROFILE_SCOPE(Scene_InterpolateTick);
  760. // ****************************************************
  761. // Interpolate scene objects.
  762. // ****************************************************
  763. // Fetch the scene object count.
  764. const S32 sceneObjectCount = mSceneObjects.size();
  765. // Iterate scene objects.
  766. for( S32 n = 0; n < sceneObjectCount; ++n )
  767. {
  768. // Fetch scene object.
  769. SceneObject* pSceneObject = mSceneObjects[n];
  770. // Skip interpolation of scene object if it's not eligible.
  771. if ( !pSceneObject->isEnabled() || pSceneObject->isBeingDeleted() )
  772. continue;
  773. pSceneObject->interpolateObject( timeDelta );
  774. }
  775. }
  776. //-----------------------------------------------------------------------------
  777. void Scene::sceneRender( const SceneRenderState* pSceneRenderState )
  778. {
  779. // Debug Profiling.
  780. PROFILE_SCOPE(Scene_RenderSceneTotal);
  781. // Fetch debug stats.
  782. DebugStats* pDebugStats = pSceneRenderState->mpDebugStats;
  783. // Reset Render Stats.
  784. pDebugStats->renderPicked = 0;
  785. pDebugStats->renderRequests = 0;
  786. pDebugStats->renderFallbacks = 0;
  787. pDebugStats->batchTrianglesSubmitted = 0;
  788. pDebugStats->batchDrawCallsStrict = 0;
  789. pDebugStats->batchDrawCallsSorted = 0;
  790. pDebugStats->batchFlushes = 0;
  791. pDebugStats->batchBlendStateFlush = 0;
  792. pDebugStats->batchColorStateFlush = 0;
  793. pDebugStats->batchAlphaStateFlush = 0;
  794. pDebugStats->batchTextureChangeFlush = 0;
  795. pDebugStats->batchBufferFullFlush = 0;
  796. pDebugStats->batchIsolatedFlush = 0;
  797. pDebugStats->batchLayerFlush = 0;
  798. pDebugStats->batchNoBatchFlush = 0;
  799. pDebugStats->batchAnonymousFlush = 0;
  800. // Set batch renderer wireframe mode.
  801. mBatchRenderer.setWireframeMode( getDebugMask() & SCENE_DEBUG_WIREFRAME_RENDER );
  802. // Debug Profiling.
  803. PROFILE_START(Scene_RenderSceneVisibleQuery);
  804. // Rotate the render AABB by the camera angle.
  805. b2AABB cameraAABB;
  806. CoreMath::mRotateAABB( pSceneRenderState->mRenderAABB, pSceneRenderState->mRenderAngle, cameraAABB );
  807. // Rotate the world matrix by the camera angle.
  808. const Vector2& cameraPosition = pSceneRenderState->mRenderPosition;
  809. glTranslatef( cameraPosition.x, cameraPosition.y, 0.0f );
  810. glRotatef( mRadToDeg(pSceneRenderState->mRenderAngle), 0.0f, 0.0f, 1.0f );
  811. glTranslatef( -cameraPosition.x, -cameraPosition.y, 0.0f );
  812. // Clear world query.
  813. mpWorldQuery->clearQuery();
  814. // Set filter.
  815. WorldQueryFilter queryFilter( pSceneRenderState->mRenderLayerMask, pSceneRenderState->mRenderGroupMask, true, true, false, false );
  816. mpWorldQuery->setQueryFilter( queryFilter );
  817. // Query render AABB.
  818. mpWorldQuery->aabbQueryAABB( cameraAABB );
  819. // Debug Profiling.
  820. PROFILE_END(); //Scene_RenderSceneVisibleQuery
  821. // Are there any query results?
  822. if ( mpWorldQuery->getQueryResultsCount() > 0 )
  823. {
  824. // Debug Profiling.
  825. PROFILE_SCOPE(Scene_RenderSceneCompileRenderRequests);
  826. // Fetch the primary scene render queue.
  827. SceneRenderQueue* pSceneRenderQueue = SceneRenderQueueFactory.createObject();
  828. // Yes so step through layers.
  829. for ( S32 layer = MAX_LAYERS_SUPPORTED-1; layer >= 0 ; layer-- )
  830. {
  831. // Fetch layer.
  832. typeWorldQueryResultVector& layerResults = mpWorldQuery->getLayeredQueryResults( layer );
  833. // Fetch layer object count.
  834. const U32 layerObjectCount = layerResults.size();
  835. // Are there any objects to render in this layer?
  836. if ( layerObjectCount > 0 )
  837. {
  838. // Yes, so increase render picked.
  839. pDebugStats->renderPicked += layerObjectCount;
  840. // Iterate query results.
  841. for( typeWorldQueryResultVector::iterator worldQueryItr = layerResults.begin(); worldQueryItr != layerResults.end(); ++worldQueryItr )
  842. {
  843. // Fetch scene object.
  844. SceneObject* pSceneObject = worldQueryItr->mpSceneObject;
  845. // Skip if the object should not render.
  846. if ( !pSceneObject->shouldRender() )
  847. continue;
  848. // Can the scene object prepare a render?
  849. if ( pSceneObject->canPrepareRender() )
  850. {
  851. // Yes. so is it batch isolated.
  852. if ( pSceneObject->getBatchIsolated() )
  853. {
  854. // Yes, so create a default render request on the primary queue.
  855. SceneRenderRequest* pIsolatedSceneRenderRequest = Scene::createDefaultRenderRequest( pSceneRenderQueue, pSceneObject );
  856. // Create a new isolated render queue.
  857. pIsolatedSceneRenderRequest->mpIsolatedRenderQueue = SceneRenderQueueFactory.createObject();
  858. // Prepare in the isolated queue.
  859. pSceneObject->scenePrepareRender( pSceneRenderState, pIsolatedSceneRenderRequest->mpIsolatedRenderQueue );
  860. // Increase render request count.
  861. pDebugStats->renderRequests += (U32)pIsolatedSceneRenderRequest->mpIsolatedRenderQueue->getRenderRequests().size();
  862. // Adjust for the extra private render request.
  863. pDebugStats->renderRequests -= 1;
  864. }
  865. else
  866. {
  867. // No, so prepare in primary queue.
  868. pSceneObject->scenePrepareRender( pSceneRenderState, pSceneRenderQueue );
  869. }
  870. }
  871. else
  872. {
  873. // No, so create a default render request for it.
  874. Scene::createDefaultRenderRequest( pSceneRenderQueue, pSceneObject );
  875. }
  876. }
  877. // Fetch render requests.
  878. SceneRenderQueue::typeRenderRequestVector& sceneRenderRequests = pSceneRenderQueue->getRenderRequests();
  879. // Fetch render request count.
  880. const U32 renderRequestCount = (U32)sceneRenderRequests.size();
  881. // Increase render request count.
  882. pDebugStats->renderRequests += renderRequestCount;
  883. // Do we have more than a single render request?
  884. if ( renderRequestCount > 1 )
  885. {
  886. // Debug Profiling.
  887. PROFILE_SCOPE(Scene_RenderSceneLayerSorting);
  888. // Yes, so fetch layer sort mode.
  889. SceneRenderQueue::RenderSort& mode = mLayerSortModes[layer];
  890. // Temporarily switch to normal sort if batch sort but batcher disabled.
  891. if ( !mBatchRenderer.getBatchEnabled() && mode == SceneRenderQueue::RENDER_SORT_BATCH )
  892. mode = SceneRenderQueue::RENDER_SORT_NEWEST;
  893. // Set render queue mode.
  894. pSceneRenderQueue->setSortMode( mode );
  895. // Sort the render requests.
  896. pSceneRenderQueue->sort();
  897. }
  898. // Iterate render requests.
  899. for( SceneRenderQueue::typeRenderRequestVector::iterator renderRequestItr = sceneRenderRequests.begin(); renderRequestItr != sceneRenderRequests.end(); ++renderRequestItr )
  900. {
  901. // Debug Profiling.
  902. PROFILE_SCOPE(Scene_RenderSceneRequests);
  903. // Fetch render request.
  904. SceneRenderRequest* pSceneRenderRequest = *renderRequestItr;
  905. // Fetch scene render object.
  906. SceneRenderObject* pSceneRenderObject = pSceneRenderRequest->mpSceneRenderObject;
  907. // Flush if the object is not render batched and we're in strict order mode.
  908. if ( !pSceneRenderObject->isBatchRendered() && mBatchRenderer.getStrictOrderMode() )
  909. {
  910. mBatchRenderer.flush( pDebugStats->batchNoBatchFlush );
  911. }
  912. // Flush if the object is batch isolated.
  913. else if ( pSceneRenderObject->getBatchIsolated() )
  914. {
  915. mBatchRenderer.flush( pDebugStats->batchIsolatedFlush );
  916. }
  917. // Yes, so is the object batch rendered?
  918. if ( pSceneRenderObject->isBatchRendered() )
  919. {
  920. // Yes, so set the blend mode.
  921. mBatchRenderer.setBlendMode( pSceneRenderRequest );
  922. // Set the alpha test mode.
  923. mBatchRenderer.setAlphaTestMode( pSceneRenderRequest );
  924. }
  925. // Set batch strict order mode.
  926. // NOTE: We keep reasserting this because an object is free to change it during rendering.
  927. mBatchRenderer.setStrictOrderMode( pSceneRenderQueue->getStrictOrderMode() );
  928. // Is the object batch isolated?
  929. if ( pSceneRenderObject->getBatchIsolated() )
  930. {
  931. // Yes, so fetch isolated render queue.
  932. SceneRenderQueue* pIsolatedRenderQueue = pSceneRenderRequest->mpIsolatedRenderQueue;
  933. // Sanity!
  934. AssertFatal( pIsolatedRenderQueue != NULL, "Cannot render batch isolated with an isolated render queue." );
  935. // Sort the isolated render requests.
  936. pIsolatedRenderQueue->sort();
  937. // Fetch isolated render requests.
  938. SceneRenderQueue::typeRenderRequestVector& isolatedRenderRequests = pIsolatedRenderQueue->getRenderRequests();
  939. // Can the object render?
  940. if ( pSceneRenderObject->validRender() )
  941. {
  942. // Yes, so iterate isolated render requests.
  943. for( SceneRenderQueue::typeRenderRequestVector::iterator isolatedRenderRequestItr = isolatedRenderRequests.begin(); isolatedRenderRequestItr != isolatedRenderRequests.end(); ++isolatedRenderRequestItr )
  944. {
  945. pSceneRenderObject->sceneRender( pSceneRenderState, *isolatedRenderRequestItr, &mBatchRenderer );
  946. }
  947. }
  948. else
  949. {
  950. // No, so iterate isolated render requests.
  951. for( SceneRenderQueue::typeRenderRequestVector::iterator isolatedRenderRequestItr = isolatedRenderRequests.begin(); isolatedRenderRequestItr != isolatedRenderRequests.end(); ++isolatedRenderRequestItr )
  952. {
  953. pSceneRenderObject->sceneRenderFallback( pSceneRenderState, *isolatedRenderRequestItr, &mBatchRenderer );
  954. }
  955. // Increase render fallbacks.
  956. pDebugStats->renderFallbacks++;
  957. }
  958. // Flush isolated batch.
  959. mBatchRenderer.flush( pDebugStats->batchIsolatedFlush );
  960. }
  961. else
  962. {
  963. // No, so can the object render?
  964. if ( pSceneRenderObject->validRender() )
  965. {
  966. // Yes, so render object.
  967. pSceneRenderObject->sceneRender( pSceneRenderState, pSceneRenderRequest, &mBatchRenderer );
  968. }
  969. else
  970. {
  971. // No, so render using fallback.
  972. pSceneRenderObject->sceneRenderFallback( pSceneRenderState, pSceneRenderRequest, &mBatchRenderer );
  973. // Increase render fallbacks.
  974. pDebugStats->renderFallbacks++;
  975. }
  976. }
  977. }
  978. // Flush.
  979. // NOTE: We cannot batch between layers as we adhere to a strict layer render order.
  980. mBatchRenderer.flush( pDebugStats->batchLayerFlush );
  981. // Iterate query results.
  982. for( typeWorldQueryResultVector::iterator worldQueryItr = layerResults.begin(); worldQueryItr != layerResults.end(); ++worldQueryItr )
  983. {
  984. // Debug Profiling.
  985. PROFILE_SCOPE(Scene_RenderObjectOverlays);
  986. // Fetch scene object.
  987. SceneObject* pSceneObject = worldQueryItr->mpSceneObject;
  988. // Render object overlay.
  989. pSceneObject->sceneRenderOverlay( pSceneRenderState );
  990. }
  991. }
  992. // Reset render queue.
  993. pSceneRenderQueue->resetState();
  994. }
  995. // Cache render queue..
  996. SceneRenderQueueFactory.cacheObject( pSceneRenderQueue );
  997. }
  998. // Draw controllers.
  999. if ( getDebugMask() & Scene::SCENE_DEBUG_CONTROLLERS )
  1000. {
  1001. // Fetch the controller set.
  1002. SimSet* pControllerSet = getControllers();
  1003. // Do we have any scene controllers?
  1004. if ( pControllerSet != NULL )
  1005. {
  1006. // Debug Profiling.
  1007. PROFILE_SCOPE(Scene_RenderControllers);
  1008. // Yes, so fetch scene controller count.
  1009. const S32 sceneControllerCount = (S32)pControllerSet->size();
  1010. // Iterate scene controllers.
  1011. for( S32 i = 0; i < sceneControllerCount; i++ )
  1012. {
  1013. // Fetch the scene controller.
  1014. SceneController* pController = dynamic_cast<SceneController*>((*pControllerSet)[i]);
  1015. // Skip if not a controller.
  1016. if ( pController == NULL )
  1017. continue;
  1018. // Render the overlay.
  1019. pController->renderOverlay( this, pSceneRenderState, &mBatchRenderer );
  1020. }
  1021. // Flush isolated batch.
  1022. mBatchRenderer.flush( pDebugStats->batchIsolatedFlush );
  1023. }
  1024. }
  1025. // Draw Joints.
  1026. if ( getDebugMask() & Scene::SCENE_DEBUG_JOINTS )
  1027. {
  1028. // Debug Profiling.
  1029. PROFILE_SCOPE(Scene_RenderSceneJointOverlays);
  1030. mDebugDraw.DrawJoints( mpWorld );
  1031. }
  1032. // Update debug stat ranges.
  1033. mDebugStats.updateRanges();
  1034. // Are we using the render callback?
  1035. if( mRenderCallback )
  1036. {
  1037. // Debug Profiling.
  1038. PROFILE_SCOPE(Scene_OnSceneRendertCallback);
  1039. // Yes, so perform callback.
  1040. Con::executef( this, 1, "onSceneRender" );
  1041. }
  1042. }
  1043. //-----------------------------------------------------------------------------
  1044. void Scene::clearScene( bool deleteObjects )
  1045. {
  1046. while( mSceneObjects.size() > 0 )
  1047. {
  1048. // Fetch first scene object.
  1049. SceneObject* pSceneObject = mSceneObjects[0];
  1050. // Remove Object from Scene.
  1051. removeFromScene( pSceneObject );
  1052. // Queue Object for deletion.
  1053. if ( deleteObjects )
  1054. pSceneObject->safeDelete();
  1055. }
  1056. // Fetch the controller set.
  1057. SimSet* pControllerSet = getControllers();
  1058. // Do we have any scene controllers?
  1059. if ( pControllerSet != NULL )
  1060. {
  1061. // Yes, so delete them all.
  1062. while( pControllerSet->size() > 0 )
  1063. pControllerSet->at(0)->deleteObject();
  1064. }
  1065. // Clear asset preloads.
  1066. clearAssetPreloads();
  1067. }
  1068. //-----------------------------------------------------------------------------
  1069. void Scene::addToScene( SceneObject* pSceneObject )
  1070. {
  1071. if ( pSceneObject == NULL )
  1072. return;
  1073. // Fetch current scene.
  1074. Scene* pCurrentScene = pSceneObject->getScene();
  1075. // Ignore if already in the scene.
  1076. if ( pCurrentScene == this )
  1077. return;
  1078. #if defined(TORQUE_DEBUG)
  1079. // Sanity!
  1080. for ( S32 n = 0; n < mSceneObjects.size(); ++n )
  1081. {
  1082. AssertFatal( mSceneObjects[n] != pSceneObject, "A scene object has become corrupt." );
  1083. }
  1084. #endif
  1085. // Check that object is not already in a scene.
  1086. if ( pCurrentScene )
  1087. {
  1088. // Remove from scene.
  1089. pCurrentScene->removeFromScene( pSceneObject );
  1090. }
  1091. // Add scene object.
  1092. mSceneObjects.push_back( pSceneObject );
  1093. // Register with the scene.
  1094. pSceneObject->OnRegisterScene( this );
  1095. // Perform callback only if properly added to the simulation.
  1096. if ( pSceneObject->isProperlyAdded() )
  1097. {
  1098. Con::executef(pSceneObject, 2, "onAddToScene", getIdString());
  1099. }
  1100. else
  1101. {
  1102. // Warning.
  1103. Con::warnf("Scene object added to scene but the object is not registered with the simulation. No 'onAddToScene' can be performed! Use Target scene.");
  1104. }
  1105. }
  1106. //-----------------------------------------------------------------------------
  1107. void Scene::removeFromScene( SceneObject* pSceneObject )
  1108. {
  1109. if ( pSceneObject == NULL )
  1110. return;
  1111. // Check if object is actually in a scene.
  1112. if ( !pSceneObject->getScene() )
  1113. {
  1114. Con::warnf("Scene::removeFromScene() - Object '%s' is not in a scene!.", pSceneObject->getIdString());
  1115. return;
  1116. }
  1117. // Remove as debug-object if set.
  1118. if ( pSceneObject == getDebugSceneObject() )
  1119. setDebugSceneObject( NULL );
  1120. // Process Destroy Notifications.
  1121. pSceneObject->processDestroyNotifications();
  1122. // Dismount Any Camera.
  1123. pSceneObject->dismountCamera();
  1124. // Remove from the SceneWindow last pickers
  1125. for( U32 i = 0; i < (U32)mAttachedSceneWindows.size(); ++i )
  1126. {
  1127. (dynamic_cast<SceneWindow*>(mAttachedSceneWindows[i]))->removeFromInputEventPick(pSceneObject);
  1128. }
  1129. // Unregister from scene.
  1130. pSceneObject->OnUnregisterScene( this );
  1131. // Find scene object and remove it quickly.
  1132. for ( S32 n = 0; n < mSceneObjects.size(); ++n )
  1133. {
  1134. if ( mSceneObjects[n] == pSceneObject )
  1135. {
  1136. mSceneObjects.erase_fast( n );
  1137. break;
  1138. }
  1139. }
  1140. // Perform callback.
  1141. Con::executef( pSceneObject, 2, "onRemoveFromScene", getIdString() );
  1142. }
  1143. //-----------------------------------------------------------------------------
  1144. SceneObject* Scene::getSceneObject( const U32 objectIndex ) const
  1145. {
  1146. // Sanity!
  1147. AssertFatal( objectIndex < getSceneObjectCount(), "Scene::getSceneObject() - Invalid object index." );
  1148. return mSceneObjects[objectIndex];
  1149. }
  1150. //-----------------------------------------------------------------------------
  1151. U32 Scene::getSceneObjects( typeSceneObjectVector& objects ) const
  1152. {
  1153. // No objects if scene is empty!
  1154. if ( getSceneObjectCount() == 0 )
  1155. return 0;
  1156. // Merge with objects.
  1157. objects.merge( mSceneObjects );
  1158. return getSceneObjectCount();
  1159. }
  1160. //-----------------------------------------------------------------------------
  1161. U32 Scene::getSceneObjects( typeSceneObjectVector& objects, const U32 sceneLayer ) const
  1162. {
  1163. // No objects if scene is empty!
  1164. if ( getSceneObjectCount() == 0 )
  1165. return 0;
  1166. // Reset object count.
  1167. U32 count = 0;
  1168. // Iterate scene objects.
  1169. for( S32 n = 0; n < mSceneObjects.size(); ++n )
  1170. {
  1171. // Fetch scene object.
  1172. SceneObject* pSceneObject = mSceneObjects[n];
  1173. // Skip if not the correct layer.
  1174. if ( pSceneObject->getSceneLayer() != sceneLayer )
  1175. continue;
  1176. // Add to objects.
  1177. objects.push_back( pSceneObject );
  1178. // Increase count.
  1179. count++;
  1180. }
  1181. return count;
  1182. }
  1183. //-----------------------------------------------------------------------------
  1184. const AssetPtr<AssetBase>* Scene::getAssetPreload( const S32 index ) const
  1185. {
  1186. // Is the index valid?
  1187. if ( index < 0 || index >= mAssetPreloads.size() )
  1188. {
  1189. // Yes, so warn.
  1190. Con::warnf( "Scene::getAssetPreload() - Out of range index '%d'. There are only '%d' asset preloads.", index, mAssetPreloads.size() );
  1191. return NULL;
  1192. }
  1193. return mAssetPreloads[index];
  1194. }
  1195. //-----------------------------------------------------------------------------
  1196. void Scene::addAssetPreload( const char* pAssetId )
  1197. {
  1198. // Sanity!
  1199. AssertFatal( pAssetId != NULL, "Scene::addAssetPreload() - Cannot add a NULL asset preload." );
  1200. // Fetch asset Id.
  1201. StringTableEntry assetId = StringTable->insert( pAssetId );
  1202. // Ignore if asset already added.
  1203. const S32 assetPreloadCount = mAssetPreloads.size();
  1204. for( S32 index = 0; index < assetPreloadCount; ++index )
  1205. {
  1206. if ( mAssetPreloads[index]->getAssetId() == assetId )
  1207. return;
  1208. }
  1209. // Create asset pointer.
  1210. AssetPtr<AssetBase>* pAssetPtr = new AssetPtr<AssetBase>( pAssetId );
  1211. // Was the asset acquired?
  1212. if ( pAssetPtr->isNull() )
  1213. {
  1214. // No, so warn.
  1215. Con::warnf( "Scene::addAssetPreload() - Failed to acquire asset '%s' so not added as a preload.", pAssetId );
  1216. // No, so delete the asset pointer.
  1217. delete pAssetPtr;
  1218. return;
  1219. }
  1220. // Add asset.
  1221. mAssetPreloads.push_back( pAssetPtr );
  1222. }
  1223. //-----------------------------------------------------------------------------
  1224. void Scene::removeAssetPreload( const char* pAssetId )
  1225. {
  1226. // Sanity!
  1227. AssertFatal( pAssetId != NULL, "Scene::removeAssetPreload() - Cannot remove a NULL asset preload." );
  1228. // Fetch asset Id.
  1229. StringTableEntry assetId = StringTable->insert( pAssetId );
  1230. // Remove asset Id.
  1231. const S32 assetPreloadCount = mAssetPreloads.size();
  1232. for( S32 index = 0; index < assetPreloadCount; ++index )
  1233. {
  1234. if ( mAssetPreloads[index]->getAssetId() == assetId )
  1235. {
  1236. delete mAssetPreloads[index];
  1237. mAssetPreloads.erase_fast( index );
  1238. return;
  1239. }
  1240. }
  1241. }
  1242. //-----------------------------------------------------------------------------
  1243. void Scene::clearAssetPreloads( void )
  1244. {
  1245. // Delete all the asset preloads.
  1246. while( mAssetPreloads.size() > 0 )
  1247. {
  1248. delete mAssetPreloads.back();
  1249. mAssetPreloads.pop_back();
  1250. }
  1251. }
  1252. //-----------------------------------------------------------------------------
  1253. void Scene::mergeScene( const Scene* pScene )
  1254. {
  1255. // Fetch the scene object count.
  1256. const U32 count = pScene->getSceneObjectCount();
  1257. // Finish if there are not objects to copy.
  1258. if ( count == 0 )
  1259. return;
  1260. for( U32 index = 0; index < count; ++index )
  1261. {
  1262. // Fetch a clone of the scene object.
  1263. SceneObject* pSceneObject = (SceneObject*)pScene->getSceneObject( index )->clone( true );
  1264. // Add the clone.
  1265. addToScene( pSceneObject );
  1266. }
  1267. }
  1268. //-----------------------------------------------------------------------------
  1269. b2Joint* Scene::findJoint( const S32 jointId )
  1270. {
  1271. // Find joint.
  1272. typeJointHash::iterator itr = mJoints.find( jointId );
  1273. return itr == mJoints.end() ? NULL : itr->value;
  1274. }
  1275. //-----------------------------------------------------------------------------
  1276. b2JointType Scene::getJointType( const S32 jointId )
  1277. {
  1278. // Sanity!
  1279. if ( jointId >= mJointMasterId )
  1280. {
  1281. Con::warnf("The joint Id of %d is invalid.", jointId);
  1282. return e_unknownJoint;
  1283. }
  1284. return findJoint( jointId )->GetType();
  1285. }
  1286. //-----------------------------------------------------------------------------
  1287. S32 Scene::findJointId( b2Joint* pJoint )
  1288. {
  1289. // Sanity!
  1290. AssertFatal( pJoint != NULL, "Joint cannot be NULL." );
  1291. // Find joint.
  1292. typeReverseJointHash::iterator itr = mReverseJoints.find( pJoint );
  1293. if ( itr == mReverseJoints.end() )
  1294. {
  1295. Con::warnf("The joint Id could not be found via a joint reference of %x", pJoint);
  1296. return 0;
  1297. }
  1298. return itr->value;
  1299. }
  1300. //-----------------------------------------------------------------------------
  1301. S32 Scene::createJoint( b2JointDef* pJointDef )
  1302. {
  1303. // Sanity!
  1304. AssertFatal( pJointDef != NULL, "Joint definition cannot be NULL." );
  1305. // Create Joint.
  1306. b2Joint* pJoint = mpWorld->CreateJoint( pJointDef );
  1307. // Allocate joint Id.
  1308. const S32 jointId = mJointMasterId++;
  1309. // Insert joint.
  1310. typeJointHash::iterator itr;
  1311. itr = mJoints.insert( jointId, pJoint );
  1312. // Sanity!
  1313. AssertFatal( itr != mJoints.end(), "Joint already in hash table." );
  1314. // Insert reverse joint.
  1315. mReverseJoints.insert( pJoint, jointId );
  1316. return jointId;
  1317. }
  1318. //-----------------------------------------------------------------------------
  1319. bool Scene::deleteJoint( const U32 jointId )
  1320. {
  1321. // Fetch joint.
  1322. b2Joint* pJoint = findJoint( jointId );
  1323. // Finish if no joint.
  1324. if ( pJoint == NULL )
  1325. return false;
  1326. // Destroy joint.
  1327. // This should result in the joint references also being destroyed
  1328. // as the scene is a destruction listener.
  1329. mpWorld->DestroyJoint( pJoint );
  1330. return true;
  1331. }
  1332. //-----------------------------------------------------------------------------
  1333. bool Scene::hasJoints( SceneObject* pSceneObject )
  1334. {
  1335. // Sanity!
  1336. AssertFatal( pSceneObject != NULL, "Scene object cannot be NULL!" );
  1337. AssertFatal( pSceneObject->getScene() != this, "Scene object is not in this scene" );
  1338. // Fetch body.
  1339. b2Body* pBody = pSceneObject->getBody();
  1340. // Fetch joint edge.
  1341. b2JointEdge* pJointEdge = pBody->GetJointList();
  1342. if ( pJointEdge == NULL || pJointEdge->joint == NULL )
  1343. return false;
  1344. // Found at least one joint.
  1345. return true;
  1346. }
  1347. //-----------------------------------------------------------------------------
  1348. S32 Scene::createDistanceJoint(
  1349. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  1350. const b2Vec2& localAnchorA, const b2Vec2& localAnchorB,
  1351. const F32 length,
  1352. const F32 frequency,
  1353. const F32 dampingRatio,
  1354. const bool collideConnected )
  1355. {
  1356. // Sanity!
  1357. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  1358. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  1359. {
  1360. // Warn.
  1361. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  1362. return -1;
  1363. }
  1364. // Check for two invalid objects.
  1365. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  1366. {
  1367. Con::warnf("Scene::createDistanceJoint() - Cannot create joint without at least a single scene object." );
  1368. return -1;
  1369. }
  1370. // Fetch bodies.
  1371. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  1372. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  1373. // Populate definition.
  1374. b2DistanceJointDef jointDef;
  1375. jointDef.userData = static_cast<PhysicsProxy*>(this);
  1376. jointDef.collideConnected = collideConnected;
  1377. jointDef.bodyA = pBodyA;
  1378. jointDef.bodyB = pBodyB;
  1379. jointDef.localAnchorA = localAnchorA;
  1380. jointDef.localAnchorB = localAnchorB;
  1381. jointDef.length = length < 0.0f ? (pBodyB->GetWorldPoint( localAnchorB ) - pBodyA->GetWorldPoint( localAnchorA )).Length() : length;
  1382. jointDef.frequencyHz = frequency;
  1383. jointDef.dampingRatio = dampingRatio;
  1384. // Create joint.
  1385. return createJoint( &jointDef );
  1386. }
  1387. //-----------------------------------------------------------------------------
  1388. void Scene::setDistanceJointLength(
  1389. const U32 jointId,
  1390. const F32 length )
  1391. {
  1392. // Fetch joint.
  1393. b2Joint* pJoint = findJoint( jointId );
  1394. // Ignore invalid joint.
  1395. if ( !pJoint )
  1396. return;
  1397. // Fetch joint type.
  1398. const b2JointType jointType = pJoint->GetType();
  1399. if ( jointType != e_distanceJoint )
  1400. {
  1401. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1402. return;
  1403. }
  1404. // Cast joint.
  1405. b2DistanceJoint* pRealJoint = static_cast<b2DistanceJoint*>( pJoint );
  1406. // Access joint.
  1407. pRealJoint->SetLength( length );
  1408. }
  1409. //-----------------------------------------------------------------------------
  1410. F32 Scene::getDistanceJointLength( const U32 jointId )
  1411. {
  1412. // Fetch joint.
  1413. b2Joint* pJoint = findJoint( jointId );
  1414. // Ignore invalid joint.
  1415. if ( !pJoint )
  1416. return -1.0f;
  1417. // Fetch joint type.
  1418. const b2JointType jointType = pJoint->GetType();
  1419. if ( jointType != e_distanceJoint )
  1420. {
  1421. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1422. return -1.0f;
  1423. }
  1424. // Cast joint.
  1425. b2DistanceJoint* pRealJoint = static_cast<b2DistanceJoint*>( pJoint );
  1426. // Access joint.
  1427. return pRealJoint->GetLength();
  1428. }
  1429. //-----------------------------------------------------------------------------
  1430. void Scene::setDistanceJointFrequency(
  1431. const U32 jointId,
  1432. const F32 frequency )
  1433. {
  1434. // Fetch joint.
  1435. b2Joint* pJoint = findJoint( jointId );
  1436. // Ignore invalid joint.
  1437. if ( !pJoint )
  1438. return;
  1439. // Fetch joint type.
  1440. const b2JointType jointType = pJoint->GetType();
  1441. if ( jointType != e_distanceJoint )
  1442. {
  1443. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1444. return;
  1445. }
  1446. // Cast joint.
  1447. b2DistanceJoint* pRealJoint = static_cast<b2DistanceJoint*>( pJoint );
  1448. // Access joint.
  1449. pRealJoint->SetFrequency( frequency );
  1450. }
  1451. //-----------------------------------------------------------------------------
  1452. F32 Scene::getDistanceJointFrequency( const U32 jointId )
  1453. {
  1454. // Fetch joint.
  1455. b2Joint* pJoint = findJoint( jointId );
  1456. // Ignore invalid joint.
  1457. if ( !pJoint )
  1458. return -1.0f;
  1459. // Fetch joint type.
  1460. const b2JointType jointType = pJoint->GetType();
  1461. if ( jointType != e_distanceJoint )
  1462. {
  1463. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1464. return -1.0f;
  1465. }
  1466. // Cast joint.
  1467. b2DistanceJoint* pRealJoint = static_cast<b2DistanceJoint*>( pJoint );
  1468. // Access joint.
  1469. return pRealJoint->GetFrequency();
  1470. }
  1471. //-----------------------------------------------------------------------------
  1472. void Scene::setDistanceJointDampingRatio(
  1473. const U32 jointId,
  1474. const F32 dampingRatio )
  1475. {
  1476. // Fetch joint.
  1477. b2Joint* pJoint = findJoint( jointId );
  1478. // Ignore invalid joint.
  1479. if ( !pJoint )
  1480. return;
  1481. // Fetch joint type.
  1482. const b2JointType jointType = pJoint->GetType();
  1483. if ( jointType != e_distanceJoint )
  1484. {
  1485. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1486. return;
  1487. }
  1488. // Cast joint.
  1489. b2DistanceJoint* pRealJoint = static_cast<b2DistanceJoint*>( pJoint );
  1490. // Access joint.
  1491. pRealJoint->SetDampingRatio( dampingRatio );
  1492. }
  1493. //-----------------------------------------------------------------------------
  1494. F32 Scene::getDistanceJointDampingRatio( const U32 jointId )
  1495. {
  1496. // Fetch joint.
  1497. b2Joint* pJoint = findJoint( jointId );
  1498. // Ignore invalid joint.
  1499. if ( !pJoint )
  1500. return -1.0f;
  1501. // Fetch joint type.
  1502. const b2JointType jointType = pJoint->GetType();
  1503. if ( jointType != e_distanceJoint )
  1504. {
  1505. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1506. return -1.0f;
  1507. }
  1508. // Cast joint.
  1509. b2DistanceJoint* pRealJoint = static_cast<b2DistanceJoint*>( pJoint );
  1510. // Access joint.
  1511. return pRealJoint->GetDampingRatio();
  1512. }
  1513. //-----------------------------------------------------------------------------
  1514. S32 Scene::createRopeJoint(
  1515. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  1516. const b2Vec2& localAnchorA, const b2Vec2& localAnchorB,
  1517. const F32 maxLength,
  1518. const bool collideConnected )
  1519. {
  1520. // Sanity!
  1521. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  1522. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  1523. {
  1524. // Warn.
  1525. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  1526. return -1;
  1527. }
  1528. // Check for two invalid objects.
  1529. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  1530. {
  1531. Con::warnf("Scene::createRopeJoint() - Cannot create joint without at least a single scene object." );
  1532. return -1;
  1533. }
  1534. // Fetch bodies.
  1535. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  1536. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  1537. // Populate definition.
  1538. b2RopeJointDef jointDef;
  1539. jointDef.userData = static_cast<PhysicsProxy*>(this);
  1540. jointDef.collideConnected = collideConnected;
  1541. jointDef.bodyA = pBodyA;
  1542. jointDef.bodyB = pBodyB;
  1543. jointDef.localAnchorA = localAnchorA;
  1544. jointDef.localAnchorB = localAnchorB;
  1545. jointDef.maxLength = maxLength < 0.0f ? (pBodyB->GetWorldPoint( localAnchorB ) - pBodyA->GetWorldPoint( localAnchorA )).Length() : maxLength;
  1546. // Create joint.
  1547. return createJoint( &jointDef );
  1548. }
  1549. //-----------------------------------------------------------------------------
  1550. void Scene::setRopeJointMaxLength(
  1551. const U32 jointId,
  1552. const F32 maxLength )
  1553. {
  1554. // Fetch joint.
  1555. b2Joint* pJoint = findJoint( jointId );
  1556. // Ignore invalid joint.
  1557. if ( !pJoint )
  1558. return;
  1559. // Fetch joint type.
  1560. const b2JointType jointType = pJoint->GetType();
  1561. if ( jointType != e_ropeJoint )
  1562. {
  1563. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1564. return;
  1565. }
  1566. // Cast joint.
  1567. b2RopeJoint* pRealJoint = static_cast<b2RopeJoint*>( pJoint );
  1568. // Access joint.
  1569. pRealJoint->SetMaxLength( maxLength );
  1570. }
  1571. //-----------------------------------------------------------------------------
  1572. F32 Scene::getRopeJointMaxLength( const U32 jointId )
  1573. {
  1574. // Fetch joint.
  1575. b2Joint* pJoint = findJoint( jointId );
  1576. // Ignore invalid joint.
  1577. if ( !pJoint )
  1578. return -1.0f;
  1579. // Fetch joint type.
  1580. const b2JointType jointType = pJoint->GetType();
  1581. if ( jointType != e_ropeJoint )
  1582. {
  1583. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1584. return -1.0f;
  1585. }
  1586. // Cast joint.
  1587. b2RopeJoint* pRealJoint = static_cast<b2RopeJoint*>( pJoint );
  1588. // Access joint.
  1589. return pRealJoint->GetMaxLength();
  1590. }
  1591. //-----------------------------------------------------------------------------
  1592. S32 Scene::createRevoluteJoint(
  1593. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  1594. const b2Vec2& localAnchorA, const b2Vec2& localAnchorB,
  1595. const bool collideConnected )
  1596. {
  1597. // Sanity!
  1598. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  1599. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  1600. {
  1601. // Warn.
  1602. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  1603. return -1;
  1604. }
  1605. // Check for two invalid objects.
  1606. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  1607. {
  1608. Con::warnf("Scene::createRevoluteJoint() - Cannot create joint without at least a single scene object." );
  1609. return -1;
  1610. }
  1611. // Fetch bodies.
  1612. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  1613. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  1614. // Populate definition.
  1615. b2RevoluteJointDef jointDef;
  1616. jointDef.userData = static_cast<PhysicsProxy*>(this);
  1617. jointDef.collideConnected = collideConnected;
  1618. jointDef.bodyA = pBodyA;
  1619. jointDef.bodyB = pBodyB;
  1620. jointDef.referenceAngle = pBodyB->GetAngle() - pBodyA->GetAngle();
  1621. jointDef.localAnchorA = localAnchorA;
  1622. jointDef.localAnchorB = localAnchorB;
  1623. // Create joint.
  1624. return createJoint( &jointDef );
  1625. }
  1626. //-----------------------------------------------------------------------------
  1627. void Scene::setRevoluteJointLimit(
  1628. const U32 jointId,
  1629. const bool enableLimit,
  1630. const F32 lowerAngle, const F32 upperAngle )
  1631. {
  1632. // Fetch joint.
  1633. b2Joint* pJoint = findJoint( jointId );
  1634. // Ignore invalid joint.
  1635. if ( !pJoint )
  1636. return;
  1637. // Fetch joint type.
  1638. const b2JointType jointType = pJoint->GetType();
  1639. if ( jointType != e_revoluteJoint )
  1640. {
  1641. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1642. return;
  1643. }
  1644. // Cast joint.
  1645. b2RevoluteJoint* pRealJoint = static_cast<b2RevoluteJoint*>( pJoint );
  1646. // Access joint.
  1647. pRealJoint->SetLimits( lowerAngle, upperAngle );
  1648. pRealJoint->EnableLimit( enableLimit );
  1649. }
  1650. //-----------------------------------------------------------------------------
  1651. bool Scene::getRevoluteJointLimit(
  1652. const U32 jointId,
  1653. bool& enableLimit,
  1654. F32& lowerAngle, F32& upperAngle )
  1655. {
  1656. // Fetch joint.
  1657. b2Joint* pJoint = findJoint( jointId );
  1658. // Ignore invalid joint.
  1659. if ( !pJoint )
  1660. return false;
  1661. // Fetch joint type.
  1662. const b2JointType jointType = pJoint->GetType();
  1663. if ( jointType != e_revoluteJoint )
  1664. {
  1665. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1666. return false;
  1667. }
  1668. // Cast joint.
  1669. b2RevoluteJoint* pRealJoint = static_cast<b2RevoluteJoint*>( pJoint );
  1670. // Access joint.
  1671. enableLimit = pRealJoint->IsLimitEnabled();
  1672. lowerAngle = pRealJoint->GetLowerLimit();
  1673. upperAngle = pRealJoint->GetUpperLimit();
  1674. return true;
  1675. }
  1676. //-----------------------------------------------------------------------------
  1677. void Scene::setRevoluteJointMotor(
  1678. const U32 jointId,
  1679. const bool enableMotor,
  1680. const F32 motorSpeed,
  1681. const F32 maxMotorTorque )
  1682. {
  1683. // Fetch joint.
  1684. b2Joint* pJoint = findJoint( jointId );
  1685. // Ignore invalid joint.
  1686. if ( !pJoint )
  1687. return;
  1688. // Fetch joint type.
  1689. const b2JointType jointType = pJoint->GetType();
  1690. if ( jointType != e_revoluteJoint )
  1691. {
  1692. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1693. return;
  1694. }
  1695. // Cast joint.
  1696. b2RevoluteJoint* pRealJoint = static_cast<b2RevoluteJoint*>( pJoint );
  1697. // Access joint.
  1698. pRealJoint->SetMotorSpeed( motorSpeed );
  1699. pRealJoint->SetMaxMotorTorque( maxMotorTorque );
  1700. pRealJoint->EnableMotor( enableMotor );
  1701. }
  1702. //-----------------------------------------------------------------------------
  1703. bool Scene::getRevoluteJointMotor(
  1704. const U32 jointId,
  1705. bool& enableMotor,
  1706. F32& motorSpeed,
  1707. F32& maxMotorTorque )
  1708. {
  1709. // Fetch joint.
  1710. b2Joint* pJoint = findJoint( jointId );
  1711. // Ignore invalid joint.
  1712. if ( !pJoint )
  1713. return false;
  1714. // Fetch joint type.
  1715. const b2JointType jointType = pJoint->GetType();
  1716. if ( jointType != e_revoluteJoint )
  1717. {
  1718. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1719. return false;
  1720. }
  1721. // Cast joint.
  1722. b2RevoluteJoint* pRealJoint = static_cast<b2RevoluteJoint*>( pJoint );
  1723. // Access joint.
  1724. enableMotor = pRealJoint->IsMotorEnabled();
  1725. motorSpeed = pRealJoint->GetMotorSpeed();
  1726. maxMotorTorque = pRealJoint->GetMaxMotorTorque();
  1727. return true;
  1728. }
  1729. //-----------------------------------------------------------------------------
  1730. F32 Scene::getRevoluteJointAngle( const U32 jointId )
  1731. {
  1732. // Fetch joint.
  1733. b2Joint* pJoint = findJoint( jointId );
  1734. // Ignore invalid joint.
  1735. if ( !pJoint )
  1736. return 0.0f;
  1737. // Fetch joint type.
  1738. const b2JointType jointType = pJoint->GetType();
  1739. if ( jointType != e_revoluteJoint )
  1740. {
  1741. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1742. return 0.0f;
  1743. }
  1744. // Cast joint.
  1745. b2RevoluteJoint* pRealJoint = static_cast<b2RevoluteJoint*>( pJoint );
  1746. // Access joint.
  1747. return pRealJoint->GetJointAngle();
  1748. }
  1749. //-----------------------------------------------------------------------------
  1750. F32 Scene::getRevoluteJointSpeed( const U32 jointId )
  1751. {
  1752. // Fetch joint.
  1753. b2Joint* pJoint = findJoint( jointId );
  1754. // Ignore invalid joint.
  1755. if ( !pJoint )
  1756. return 0.0f;
  1757. // Fetch joint type.
  1758. const b2JointType jointType = pJoint->GetType();
  1759. if ( jointType != e_revoluteJoint )
  1760. {
  1761. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1762. return 0.0f;
  1763. }
  1764. // Cast joint.
  1765. b2RevoluteJoint* pRealJoint = static_cast<b2RevoluteJoint*>( pJoint );
  1766. // Access joint.
  1767. return pRealJoint->GetJointSpeed();
  1768. }
  1769. //-----------------------------------------------------------------------------
  1770. S32 Scene::createWeldJoint(
  1771. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  1772. const b2Vec2& localAnchorA, const b2Vec2& localAnchorB,
  1773. const F32 frequency,
  1774. const F32 dampingRatio,
  1775. const bool collideConnected )
  1776. {
  1777. // Sanity!
  1778. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  1779. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  1780. {
  1781. // Warn.
  1782. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  1783. return -1;
  1784. }
  1785. // Check for two invalid objects.
  1786. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  1787. {
  1788. Con::warnf("Scene::createWeldJoint() - Cannot create joint without at least a single scene object." );
  1789. return -1;
  1790. }
  1791. // Fetch bodies.
  1792. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  1793. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  1794. // Populate definition.
  1795. b2WeldJointDef jointDef;
  1796. jointDef.userData = static_cast<PhysicsProxy*>(this);
  1797. jointDef.collideConnected = collideConnected;
  1798. jointDef.bodyA = pBodyA;
  1799. jointDef.bodyB = pBodyB;
  1800. jointDef.referenceAngle = pBodyB->GetAngle() - pBodyA->GetAngle();
  1801. jointDef.localAnchorA = localAnchorA;
  1802. jointDef.localAnchorB = localAnchorB;
  1803. jointDef.frequencyHz = frequency;
  1804. jointDef.dampingRatio = dampingRatio;
  1805. // Create joint.
  1806. return createJoint( &jointDef );
  1807. }
  1808. //-----------------------------------------------------------------------------
  1809. void Scene::setWeldJointFrequency(
  1810. const U32 jointId,
  1811. const F32 frequency )
  1812. {
  1813. // Fetch joint.
  1814. b2Joint* pJoint = findJoint( jointId );
  1815. // Ignore invalid joint.
  1816. if ( !pJoint )
  1817. return;
  1818. // Fetch joint type.
  1819. const b2JointType jointType = pJoint->GetType();
  1820. if ( jointType != e_weldJoint )
  1821. {
  1822. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1823. return;
  1824. }
  1825. // Cast joint.
  1826. b2WeldJoint* pRealJoint = static_cast<b2WeldJoint*>( pJoint );
  1827. // Access joint.
  1828. pRealJoint->SetFrequency( frequency );
  1829. }
  1830. //-----------------------------------------------------------------------------
  1831. F32 Scene::getWeldJointFrequency( const U32 jointId )
  1832. {
  1833. // Fetch joint.
  1834. b2Joint* pJoint = findJoint( jointId );
  1835. // Ignore invalid joint.
  1836. if ( !pJoint )
  1837. return -1.0f;
  1838. // Fetch joint type.
  1839. const b2JointType jointType = pJoint->GetType();
  1840. if ( jointType != e_weldJoint )
  1841. {
  1842. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1843. return -1.0f;
  1844. }
  1845. // Cast joint.
  1846. b2WeldJoint* pRealJoint = static_cast<b2WeldJoint*>( pJoint );
  1847. // Access joint.
  1848. return pRealJoint->GetFrequency();
  1849. }
  1850. //-----------------------------------------------------------------------------
  1851. void Scene::setWeldJointDampingRatio(
  1852. const U32 jointId,
  1853. const F32 dampingRatio )
  1854. {
  1855. // Fetch joint.
  1856. b2Joint* pJoint = findJoint( jointId );
  1857. // Ignore invalid joint.
  1858. if ( !pJoint )
  1859. return;
  1860. // Fetch joint type.
  1861. const b2JointType jointType = pJoint->GetType();
  1862. if ( jointType != e_weldJoint )
  1863. {
  1864. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1865. return;
  1866. }
  1867. // Cast joint.
  1868. b2WeldJoint* pRealJoint = static_cast<b2WeldJoint*>( pJoint );
  1869. // Access joint.
  1870. pRealJoint->SetDampingRatio( dampingRatio );
  1871. }
  1872. //-----------------------------------------------------------------------------
  1873. F32 Scene::getWeldJointDampingRatio( const U32 jointId )
  1874. {
  1875. // Fetch joint.
  1876. b2Joint* pJoint = findJoint( jointId );
  1877. // Ignore invalid joint.
  1878. if ( !pJoint )
  1879. return -1.0f;
  1880. // Fetch joint type.
  1881. const b2JointType jointType = pJoint->GetType();
  1882. if ( jointType != e_weldJoint )
  1883. {
  1884. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1885. return -1.0f;
  1886. }
  1887. // Cast joint.
  1888. b2WeldJoint* pRealJoint = static_cast<b2WeldJoint*>( pJoint );
  1889. // Access joint.
  1890. return pRealJoint->GetDampingRatio();
  1891. }
  1892. //-----------------------------------------------------------------------------
  1893. S32 Scene::createWheelJoint(
  1894. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  1895. const b2Vec2& localAnchorA, const b2Vec2& localAnchorB,
  1896. const b2Vec2& worldAxis,
  1897. const bool collideConnected )
  1898. {
  1899. // Sanity!
  1900. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  1901. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  1902. {
  1903. // Warn.
  1904. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  1905. return -1;
  1906. }
  1907. // Check for two invalid objects.
  1908. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  1909. {
  1910. Con::warnf("Scene::createWheelJoint() - Cannot create joint without at least a single scene object." );
  1911. return -1;
  1912. }
  1913. // Fetch bodies.
  1914. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  1915. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  1916. // Populate definition.
  1917. b2WheelJointDef jointDef;
  1918. jointDef.userData = static_cast<PhysicsProxy*>(this);
  1919. jointDef.collideConnected = collideConnected;
  1920. jointDef.bodyA = pBodyA;
  1921. jointDef.bodyB = pBodyB;
  1922. jointDef.localAnchorA = localAnchorA;
  1923. jointDef.localAnchorB = localAnchorB;
  1924. jointDef.localAxisA = pBodyA->GetLocalVector( worldAxis );
  1925. // Create joint.
  1926. return createJoint( &jointDef );
  1927. }
  1928. //-----------------------------------------------------------------------------
  1929. void Scene::setWheelJointMotor(
  1930. const U32 jointId,
  1931. const bool enableMotor,
  1932. const F32 motorSpeed,
  1933. const F32 maxMotorTorque )
  1934. {
  1935. // Fetch joint.
  1936. b2Joint* pJoint = findJoint( jointId );
  1937. // Ignore invalid joint.
  1938. if ( !pJoint )
  1939. return;
  1940. // Fetch joint type.
  1941. const b2JointType jointType = pJoint->GetType();
  1942. if ( jointType != e_wheelJoint )
  1943. {
  1944. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1945. return;
  1946. }
  1947. // Cast joint.
  1948. b2WheelJoint* pRealJoint = static_cast<b2WheelJoint*>( pJoint );
  1949. // Access joint.
  1950. pRealJoint->SetMotorSpeed( motorSpeed );
  1951. pRealJoint->SetMaxMotorTorque( maxMotorTorque );
  1952. pRealJoint->EnableMotor( enableMotor );
  1953. }
  1954. //-----------------------------------------------------------------------------
  1955. bool Scene::getWheelJointMotor(
  1956. const U32 jointId,
  1957. bool& enableMotor,
  1958. F32& motorSpeed,
  1959. F32& maxMotorTorque )
  1960. {
  1961. // Fetch joint.
  1962. b2Joint* pJoint = findJoint( jointId );
  1963. // Ignore invalid joint.
  1964. if ( !pJoint )
  1965. return false;
  1966. // Fetch joint type.
  1967. const b2JointType jointType = pJoint->GetType();
  1968. if ( jointType != e_wheelJoint )
  1969. {
  1970. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1971. return false;
  1972. }
  1973. // Cast joint.
  1974. b2WheelJoint* pRealJoint = static_cast<b2WheelJoint*>( pJoint );
  1975. // Access joint.
  1976. enableMotor = pRealJoint->IsMotorEnabled();
  1977. motorSpeed = pRealJoint->GetMotorSpeed();
  1978. maxMotorTorque = pRealJoint->GetMaxMotorTorque();
  1979. return true;
  1980. }
  1981. //-----------------------------------------------------------------------------
  1982. void Scene::setWheelJointFrequency(
  1983. const U32 jointId,
  1984. const F32 frequency )
  1985. {
  1986. // Fetch joint.
  1987. b2Joint* pJoint = findJoint( jointId );
  1988. // Ignore invalid joint.
  1989. if ( !pJoint )
  1990. return;
  1991. // Fetch joint type.
  1992. const b2JointType jointType = pJoint->GetType();
  1993. if ( jointType != e_wheelJoint )
  1994. {
  1995. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  1996. return;
  1997. }
  1998. // Cast joint.
  1999. b2WheelJoint* pRealJoint = static_cast<b2WheelJoint*>( pJoint );
  2000. // Access joint.
  2001. pRealJoint->SetSpringFrequencyHz( frequency );
  2002. }
  2003. //-----------------------------------------------------------------------------
  2004. F32 Scene::getWheelJointFrequency( const U32 jointId )
  2005. {
  2006. // Fetch joint.
  2007. b2Joint* pJoint = findJoint( jointId );
  2008. // Ignore invalid joint.
  2009. if ( !pJoint )
  2010. return -1.0f;
  2011. // Fetch joint type.
  2012. const b2JointType jointType = pJoint->GetType();
  2013. if ( jointType != e_wheelJoint )
  2014. {
  2015. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2016. return -1.0f;
  2017. }
  2018. // Cast joint.
  2019. b2WheelJoint* pRealJoint = static_cast<b2WheelJoint*>( pJoint );
  2020. // Access joint.
  2021. return pRealJoint->GetSpringFrequencyHz();
  2022. }
  2023. //-----------------------------------------------------------------------------
  2024. void Scene::setWheelJointDampingRatio(
  2025. const U32 jointId,
  2026. const F32 dampingRatio )
  2027. {
  2028. // Fetch joint.
  2029. b2Joint* pJoint = findJoint( jointId );
  2030. // Ignore invalid joint.
  2031. if ( !pJoint )
  2032. return;
  2033. // Fetch joint type.
  2034. const b2JointType jointType = pJoint->GetType();
  2035. if ( jointType != e_wheelJoint )
  2036. {
  2037. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2038. return;
  2039. }
  2040. // Cast joint.
  2041. b2WheelJoint* pRealJoint = static_cast<b2WheelJoint*>( pJoint );
  2042. // Access joint.
  2043. pRealJoint->SetSpringDampingRatio( dampingRatio );
  2044. }
  2045. //-----------------------------------------------------------------------------
  2046. F32 Scene::getWheelJointDampingRatio( const U32 jointId )
  2047. {
  2048. // Fetch joint.
  2049. b2Joint* pJoint = findJoint( jointId );
  2050. // Ignore invalid joint.
  2051. if ( !pJoint )
  2052. return -1.0f;
  2053. // Fetch joint type.
  2054. const b2JointType jointType = pJoint->GetType();
  2055. if ( jointType != e_wheelJoint )
  2056. {
  2057. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2058. return -1.0f;
  2059. }
  2060. // Cast joint.
  2061. b2WheelJoint* pRealJoint = static_cast<b2WheelJoint*>( pJoint );
  2062. // Access joint.
  2063. return pRealJoint->GetSpringDampingRatio();
  2064. }
  2065. //-----------------------------------------------------------------------------
  2066. S32 Scene::createFrictionJoint(
  2067. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  2068. const b2Vec2& localAnchorA, const b2Vec2& localAnchorB,
  2069. const F32 maxForce,
  2070. const F32 maxTorque,
  2071. const bool collideConnected )
  2072. {
  2073. // Sanity!
  2074. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  2075. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  2076. {
  2077. // Warn.
  2078. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  2079. return -1;
  2080. }
  2081. // Check for two invalid objects.
  2082. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  2083. {
  2084. Con::warnf("Scene::createFrictionJoint() - Cannot create joint without at least a single scene object." );
  2085. return -1;
  2086. }
  2087. // Fetch bodies.
  2088. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  2089. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  2090. // Populate definition.
  2091. b2FrictionJointDef jointDef;
  2092. jointDef.userData = static_cast<PhysicsProxy*>(this);
  2093. jointDef.collideConnected = collideConnected;
  2094. jointDef.bodyA = pBodyA;
  2095. jointDef.bodyB = pBodyB;
  2096. jointDef.localAnchorA = localAnchorA;
  2097. jointDef.localAnchorB = localAnchorB;
  2098. jointDef.maxForce = maxForce;
  2099. jointDef.maxTorque = maxTorque;
  2100. // Create joint.
  2101. return createJoint( &jointDef );
  2102. }
  2103. //-----------------------------------------------------------------------------
  2104. void Scene::setFrictionJointMaxForce(
  2105. const U32 jointId,
  2106. const F32 maxForce )
  2107. {
  2108. // Fetch joint.
  2109. b2Joint* pJoint = findJoint( jointId );
  2110. // Ignore invalid joint.
  2111. if ( !pJoint )
  2112. return;
  2113. // Fetch joint type.
  2114. const b2JointType jointType = pJoint->GetType();
  2115. if ( jointType != e_frictionJoint )
  2116. {
  2117. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2118. return;
  2119. }
  2120. // Cast joint.
  2121. b2FrictionJoint* pRealJoint = static_cast<b2FrictionJoint*>( pJoint );
  2122. // Access joint.
  2123. pRealJoint->SetMaxForce( maxForce );
  2124. }
  2125. //-----------------------------------------------------------------------------
  2126. F32 Scene::getFrictionJointMaxForce( const U32 jointId )
  2127. {
  2128. // Fetch joint.
  2129. b2Joint* pJoint = findJoint( jointId );
  2130. // Ignore invalid joint.
  2131. if ( !pJoint )
  2132. return -1.0f;
  2133. // Fetch joint type.
  2134. const b2JointType jointType = pJoint->GetType();
  2135. if ( jointType != e_frictionJoint )
  2136. {
  2137. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2138. return -1.0f;
  2139. }
  2140. // Cast joint.
  2141. b2FrictionJoint* pRealJoint = static_cast<b2FrictionJoint*>( pJoint );
  2142. // Access joint.
  2143. return pRealJoint->GetMaxForce();
  2144. }
  2145. //-----------------------------------------------------------------------------
  2146. void Scene::setFrictionJointMaxTorque(
  2147. const U32 jointId,
  2148. const F32 maxTorque )
  2149. {
  2150. // Fetch joint.
  2151. b2Joint* pJoint = findJoint( jointId );
  2152. // Ignore invalid joint.
  2153. if ( !pJoint )
  2154. return;
  2155. // Fetch joint type.
  2156. const b2JointType jointType = pJoint->GetType();
  2157. if ( jointType != e_frictionJoint )
  2158. {
  2159. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2160. return;
  2161. }
  2162. // Cast joint.
  2163. b2FrictionJoint* pRealJoint = static_cast<b2FrictionJoint*>( pJoint );
  2164. // Access joint.
  2165. pRealJoint->SetMaxTorque( maxTorque );
  2166. }
  2167. //-----------------------------------------------------------------------------
  2168. F32 Scene::getFrictionJointMaxTorque( const U32 jointId )
  2169. {
  2170. // Fetch joint.
  2171. b2Joint* pJoint = findJoint( jointId );
  2172. // Ignore invalid joint.
  2173. if ( !pJoint )
  2174. return -1.0f;
  2175. // Fetch joint type.
  2176. const b2JointType jointType = pJoint->GetType();
  2177. if ( jointType != e_frictionJoint )
  2178. {
  2179. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2180. return -1.0f;
  2181. }
  2182. // Cast joint.
  2183. b2FrictionJoint* pRealJoint = static_cast<b2FrictionJoint*>( pJoint );
  2184. // Access joint.
  2185. return pRealJoint->GetMaxTorque();
  2186. }
  2187. //-----------------------------------------------------------------------------
  2188. S32 Scene::createPrismaticJoint(
  2189. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  2190. const b2Vec2& localAnchorA, const b2Vec2& localAnchorB,
  2191. const b2Vec2& worldAxis,
  2192. const bool collideConnected )
  2193. {
  2194. // Sanity!
  2195. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  2196. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  2197. {
  2198. // Warn.
  2199. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  2200. return -1;
  2201. }
  2202. // Check for two invalid objects.
  2203. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  2204. {
  2205. Con::warnf("Scene::createPrismaticJoint() - Cannot create joint without at least a single scene object." );
  2206. return -1;
  2207. }
  2208. // Fetch bodies.
  2209. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  2210. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  2211. // Populate definition.
  2212. b2PrismaticJointDef jointDef;
  2213. jointDef.userData = static_cast<PhysicsProxy*>(this);
  2214. jointDef.collideConnected = collideConnected;
  2215. jointDef.bodyA = pBodyA;
  2216. jointDef.bodyB = pBodyB;
  2217. jointDef.referenceAngle = pBodyB->GetAngle() - pBodyA->GetAngle();
  2218. jointDef.localAnchorA = localAnchorA;
  2219. jointDef.localAnchorB = localAnchorB;
  2220. jointDef.localAxisA = pBodyA->GetLocalVector( worldAxis );
  2221. // Create joint.
  2222. return createJoint( &jointDef );
  2223. }
  2224. //-----------------------------------------------------------------------------
  2225. void Scene::setPrismaticJointLimit(
  2226. const U32 jointId,
  2227. const bool enableLimit,
  2228. const F32 lowerTranslation, const F32 upperTranslation )
  2229. {
  2230. // Fetch joint.
  2231. b2Joint* pJoint = findJoint( jointId );
  2232. // Ignore invalid joint.
  2233. if ( !pJoint )
  2234. return;
  2235. // Fetch joint type.
  2236. const b2JointType jointType = pJoint->GetType();
  2237. if ( jointType != e_prismaticJoint )
  2238. {
  2239. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2240. return;
  2241. }
  2242. // Cast joint.
  2243. b2PrismaticJoint* pRealJoint = static_cast<b2PrismaticJoint*>( pJoint );
  2244. // Access joint.
  2245. pRealJoint->SetLimits( lowerTranslation, upperTranslation );
  2246. pRealJoint->EnableLimit( enableLimit );
  2247. }
  2248. //-----------------------------------------------------------------------------
  2249. bool Scene::getPrismaticJointLimit(
  2250. const U32 jointId,
  2251. bool& enableLimit,
  2252. F32& lowerTranslation, F32& upperTranslation )
  2253. {
  2254. // Fetch joint.
  2255. b2Joint* pJoint = findJoint( jointId );
  2256. // Ignore invalid joint.
  2257. if ( !pJoint )
  2258. return false;
  2259. // Fetch joint type.
  2260. const b2JointType jointType = pJoint->GetType();
  2261. if ( jointType != e_prismaticJoint )
  2262. {
  2263. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2264. return false;
  2265. }
  2266. // Cast joint.
  2267. b2PrismaticJoint* pRealJoint = static_cast<b2PrismaticJoint*>( pJoint );
  2268. // Access joint.
  2269. enableLimit = pRealJoint->IsLimitEnabled();
  2270. lowerTranslation = pRealJoint->GetLowerLimit();
  2271. upperTranslation = pRealJoint->GetUpperLimit();
  2272. return true;
  2273. }
  2274. //-----------------------------------------------------------------------------
  2275. void Scene::setPrismaticJointMotor(
  2276. const U32 jointId,
  2277. const bool enableMotor,
  2278. const F32 motorSpeed,
  2279. const F32 maxMotorForce )
  2280. {
  2281. // Fetch joint.
  2282. b2Joint* pJoint = findJoint( jointId );
  2283. // Ignore invalid joint.
  2284. if ( !pJoint )
  2285. return;
  2286. // Fetch joint type.
  2287. const b2JointType jointType = pJoint->GetType();
  2288. if ( jointType != e_prismaticJoint )
  2289. {
  2290. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2291. return;
  2292. }
  2293. // Cast joint.
  2294. b2PrismaticJoint* pRealJoint = static_cast<b2PrismaticJoint*>( pJoint );
  2295. // Access joint.
  2296. pRealJoint->SetMotorSpeed( motorSpeed );
  2297. pRealJoint->SetMaxMotorForce( maxMotorForce );
  2298. pRealJoint->EnableMotor( enableMotor );
  2299. }
  2300. //-----------------------------------------------------------------------------
  2301. bool Scene::getPrismaticJointMotor(
  2302. const U32 jointId,
  2303. bool& enableMotor,
  2304. F32& motorSpeed,
  2305. F32& maxMotorForce )
  2306. {
  2307. // Fetch joint.
  2308. b2Joint* pJoint = findJoint( jointId );
  2309. // Ignore invalid joint.
  2310. if ( !pJoint )
  2311. return false;
  2312. // Fetch joint type.
  2313. const b2JointType jointType = pJoint->GetType();
  2314. if ( jointType != e_prismaticJoint )
  2315. {
  2316. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2317. return false;
  2318. }
  2319. // Cast joint.
  2320. b2PrismaticJoint* pRealJoint = static_cast<b2PrismaticJoint*>( pJoint );
  2321. // Access joint.
  2322. enableMotor = pRealJoint->IsMotorEnabled();
  2323. motorSpeed = pRealJoint->GetMotorSpeed();
  2324. maxMotorForce = pRealJoint->GetMaxMotorForce();
  2325. return true;
  2326. }
  2327. //-----------------------------------------------------------------------------
  2328. S32 Scene::createPulleyJoint(
  2329. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  2330. const b2Vec2& localAnchorA, const b2Vec2& localAnchorB,
  2331. const b2Vec2& worldGroundAnchorA, const b2Vec2& worldGroundAnchorB,
  2332. const F32 ratio,
  2333. const F32 lengthA, const F32 lengthB,
  2334. const bool collideConnected )
  2335. {
  2336. // Sanity!
  2337. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  2338. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  2339. {
  2340. // Warn.
  2341. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  2342. return -1;
  2343. }
  2344. // Check for two invalid objects.
  2345. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  2346. {
  2347. Con::warnf("Scene::createPulleyJoint() - Cannot create joint without at least a single scene object." );
  2348. return -1;
  2349. }
  2350. // Fetch bodies.
  2351. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  2352. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  2353. // Populate definition.
  2354. b2PulleyJointDef jointDef;
  2355. jointDef.userData = static_cast<PhysicsProxy*>(this);
  2356. jointDef.collideConnected = collideConnected;
  2357. jointDef.bodyA = pBodyA;
  2358. jointDef.bodyB = pBodyB;
  2359. jointDef.groundAnchorA = worldGroundAnchorA;
  2360. jointDef.groundAnchorB = worldGroundAnchorB;
  2361. jointDef.localAnchorA = localAnchorA;
  2362. jointDef.localAnchorB = localAnchorB;
  2363. jointDef.lengthA = lengthA < 0.0f ? (pBodyA->GetWorldPoint( localAnchorA ) - worldGroundAnchorA).Length() : lengthA;
  2364. jointDef.lengthB = lengthB < 0.0f ? (pBodyA->GetWorldPoint( localAnchorB ) - worldGroundAnchorB).Length() : lengthB;
  2365. jointDef.ratio = ratio > b2_epsilon ? ratio : b2_epsilon + b2_epsilon;
  2366. // Create joint.
  2367. return createJoint( &jointDef );
  2368. }
  2369. //-----------------------------------------------------------------------------
  2370. S32 Scene::createTargetJoint(
  2371. const SceneObject* pSceneObject,
  2372. const b2Vec2& worldTarget,
  2373. const F32 maxForce,
  2374. const bool useCenterOfMass,
  2375. const F32 frequency,
  2376. const F32 dampingRatio,
  2377. const bool collideConnected )
  2378. {
  2379. // Sanity!
  2380. if ( pSceneObject != NULL && pSceneObject->getScene() == NULL )
  2381. {
  2382. // Warn.
  2383. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  2384. return -1;
  2385. }
  2386. // Check for invalid object.
  2387. if ( pSceneObject == NULL )
  2388. {
  2389. Con::warnf("Scene::createPulleyJoint() - Cannot create joint without a scene object." );
  2390. return -1;
  2391. }
  2392. // Fetch bodies.
  2393. b2Body* pBody = pSceneObject->getBody();
  2394. // Populate definition.
  2395. b2MouseJointDef jointDef;
  2396. jointDef.userData = static_cast<PhysicsProxy*>(this);
  2397. jointDef.collideConnected = collideConnected;
  2398. jointDef.bodyA = getGroundBody();
  2399. jointDef.bodyB = pBody;
  2400. jointDef.target = useCenterOfMass ? pBody->GetWorldCenter() : worldTarget;
  2401. jointDef.maxForce = maxForce;
  2402. jointDef.frequencyHz = frequency;
  2403. jointDef.dampingRatio = dampingRatio;
  2404. // Create joint.
  2405. const U32 jointId = createJoint( &jointDef );
  2406. // Cast joint.
  2407. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( findJoint( jointId ) );
  2408. // Are we using the center of mass?
  2409. if ( !useCenterOfMass )
  2410. {
  2411. // No, so set the target as the world target.
  2412. // NOTE:- This is done because initially the target (mouse) joint assumes the target
  2413. // coincides with the body anchor.
  2414. pRealJoint->SetTarget( worldTarget );
  2415. }
  2416. return jointId;
  2417. }
  2418. //-----------------------------------------------------------------------------
  2419. void Scene::setTargetJointTarget(
  2420. const U32 jointId,
  2421. const b2Vec2& worldTarget )
  2422. {
  2423. // Fetch joint.
  2424. b2Joint* pJoint = findJoint( jointId );
  2425. // Ignore invalid joint.
  2426. if ( !pJoint )
  2427. return;
  2428. // Fetch joint type.
  2429. const b2JointType jointType = pJoint->GetType();
  2430. if ( jointType != e_mouseJoint )
  2431. {
  2432. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2433. return;
  2434. }
  2435. // Cast joint.
  2436. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( pJoint );
  2437. // Access joint.
  2438. pRealJoint->SetTarget( worldTarget );
  2439. }
  2440. //-----------------------------------------------------------------------------
  2441. b2Vec2 Scene::getTargetJointTarget( const U32 jointId )
  2442. {
  2443. // Fetch joint.
  2444. b2Joint* pJoint = findJoint( jointId );
  2445. // Ignore invalid joint.
  2446. if ( !pJoint )
  2447. return b2Vec2_zero;
  2448. // Fetch joint type.
  2449. const b2JointType jointType = pJoint->GetType();
  2450. if ( jointType != e_mouseJoint )
  2451. {
  2452. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2453. return b2Vec2_zero;
  2454. }
  2455. // Cast joint.
  2456. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( pJoint );
  2457. // Access joint.
  2458. return pRealJoint->GetTarget();
  2459. }
  2460. //-----------------------------------------------------------------------------
  2461. void Scene::setTargetJointMaxForce(
  2462. const U32 jointId,
  2463. const F32 maxForce )
  2464. {
  2465. // Fetch joint.
  2466. b2Joint* pJoint = findJoint( jointId );
  2467. // Ignore invalid joint.
  2468. if ( !pJoint )
  2469. return;
  2470. // Fetch joint type.
  2471. const b2JointType jointType = pJoint->GetType();
  2472. if ( jointType != e_mouseJoint )
  2473. {
  2474. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2475. return;
  2476. }
  2477. // Cast joint.
  2478. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( pJoint );
  2479. // Access joint.
  2480. pRealJoint->SetMaxForce( maxForce );
  2481. }
  2482. //-----------------------------------------------------------------------------
  2483. F32 Scene::getTargetJointMaxForce( const U32 jointId )
  2484. {
  2485. // Fetch joint.
  2486. b2Joint* pJoint = findJoint( jointId );
  2487. // Ignore invalid joint.
  2488. if ( !pJoint )
  2489. return -1.0f;
  2490. // Fetch joint type.
  2491. const b2JointType jointType = pJoint->GetType();
  2492. if ( jointType != e_mouseJoint )
  2493. {
  2494. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2495. return -1.0f;
  2496. }
  2497. // Cast joint.
  2498. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( pJoint );
  2499. // Access joint.
  2500. return pRealJoint->GetMaxForce();
  2501. }
  2502. //-----------------------------------------------------------------------------
  2503. void Scene::setTargetJointFrequency(
  2504. const U32 jointId,
  2505. const F32 frequency )
  2506. {
  2507. // Fetch joint.
  2508. b2Joint* pJoint = findJoint( jointId );
  2509. // Ignore invalid joint.
  2510. if ( !pJoint )
  2511. return;
  2512. // Fetch joint type.
  2513. const b2JointType jointType = pJoint->GetType();
  2514. if ( jointType != e_mouseJoint )
  2515. {
  2516. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2517. return;
  2518. }
  2519. // Cast joint.
  2520. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( pJoint );
  2521. // Access joint.
  2522. pRealJoint->SetFrequency( frequency );
  2523. }
  2524. //-----------------------------------------------------------------------------
  2525. F32 Scene::getTargetJointFrequency( const U32 jointId )
  2526. {
  2527. // Fetch joint.
  2528. b2Joint* pJoint = findJoint( jointId );
  2529. // Ignore invalid joint.
  2530. if ( !pJoint )
  2531. return -1.0f;
  2532. // Fetch joint type.
  2533. const b2JointType jointType = pJoint->GetType();
  2534. if ( jointType != e_mouseJoint )
  2535. {
  2536. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2537. return -1.0f;
  2538. }
  2539. // Cast joint.
  2540. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( pJoint );
  2541. // Access joint.
  2542. return pRealJoint->GetFrequency();
  2543. }
  2544. //-----------------------------------------------------------------------------
  2545. void Scene::setTargetJointDampingRatio(
  2546. const U32 jointId,
  2547. const F32 dampingRatio )
  2548. {
  2549. // Fetch joint.
  2550. b2Joint* pJoint = findJoint( jointId );
  2551. // Ignore invalid joint.
  2552. if ( !pJoint )
  2553. return;
  2554. // Fetch joint type.
  2555. const b2JointType jointType = pJoint->GetType();
  2556. if ( jointType != e_mouseJoint )
  2557. {
  2558. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2559. return;
  2560. }
  2561. // Cast joint.
  2562. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( pJoint );
  2563. // Access joint.
  2564. pRealJoint->SetDampingRatio( dampingRatio );
  2565. }
  2566. //-----------------------------------------------------------------------------
  2567. F32 Scene::getTargetJointDampingRatio( const U32 jointId )
  2568. {
  2569. // Fetch joint.
  2570. b2Joint* pJoint = findJoint( jointId );
  2571. // Ignore invalid joint.
  2572. if ( !pJoint )
  2573. return -1.0f;
  2574. // Fetch joint type.
  2575. const b2JointType jointType = pJoint->GetType();
  2576. if ( jointType != e_mouseJoint )
  2577. {
  2578. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2579. return -1.0f;
  2580. }
  2581. // Cast joint.
  2582. b2MouseJoint* pRealJoint = static_cast<b2MouseJoint*>( pJoint );
  2583. // Access joint.
  2584. return pRealJoint->GetDampingRatio();
  2585. }
  2586. //-----------------------------------------------------------------------------
  2587. S32 Scene::createMotorJoint(
  2588. const SceneObject* pSceneObjectA, const SceneObject* pSceneObjectB,
  2589. const b2Vec2 linearOffset,
  2590. const F32 angularOffset,
  2591. const F32 maxForce,
  2592. const F32 maxTorque,
  2593. const F32 correctionFactor,
  2594. const bool collideConnected )
  2595. {
  2596. // Sanity!
  2597. if ( (pSceneObjectA != NULL && pSceneObjectA->getScene() == NULL) ||
  2598. (pSceneObjectB != NULL && pSceneObjectB->getScene() == NULL) )
  2599. {
  2600. // Warn.
  2601. Con::printf( "Cannot add a joint to a scene object that is not in a scene." );
  2602. return -1;
  2603. }
  2604. // Check for two invalid objects.
  2605. if ( pSceneObjectA == NULL && pSceneObjectB == NULL )
  2606. {
  2607. Con::warnf("Scene::createMotorJoint() - Cannot create joint without at least a single scene object." );
  2608. return -1;
  2609. }
  2610. // Fetch bodies.
  2611. b2Body* pBodyA = pSceneObjectA != NULL ? pSceneObjectA->getBody() : getGroundBody();
  2612. b2Body* pBodyB = pSceneObjectB != NULL ? pSceneObjectB->getBody() : getGroundBody();
  2613. // Populate definition.
  2614. b2MotorJointDef jointDef;
  2615. jointDef.userData = static_cast<PhysicsProxy*>(this);
  2616. jointDef.collideConnected = collideConnected;
  2617. jointDef.bodyA = pBodyA;
  2618. jointDef.bodyB = pBodyB;
  2619. jointDef.linearOffset = linearOffset;
  2620. jointDef.angularOffset = angularOffset;
  2621. jointDef.correctionFactor = correctionFactor;
  2622. jointDef.maxForce = maxForce;
  2623. jointDef.maxTorque = maxTorque;
  2624. // Create joint.
  2625. return createJoint( &jointDef );
  2626. }
  2627. //-----------------------------------------------------------------------------
  2628. void Scene::setMotorJointLinearOffset(
  2629. const U32 jointId,
  2630. const b2Vec2& linearOffset )
  2631. {
  2632. // Fetch joint.
  2633. b2Joint* pJoint = findJoint( jointId );
  2634. // Ignore invalid joint.
  2635. if ( !pJoint )
  2636. return;
  2637. // Fetch joint type.
  2638. const b2JointType jointType = pJoint->GetType();
  2639. if ( jointType != e_motorJoint )
  2640. {
  2641. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2642. return;
  2643. }
  2644. // Cast joint.
  2645. b2MotorJoint* pRealJoint = static_cast<b2MotorJoint*>( pJoint );
  2646. // Access joint.
  2647. pRealJoint->SetLinearOffset( linearOffset );
  2648. }
  2649. //-----------------------------------------------------------------------------
  2650. b2Vec2 Scene::getMotorJointLinearOffset( const U32 jointId )
  2651. {
  2652. // Fetch joint.
  2653. b2Joint* pJoint = findJoint( jointId );
  2654. // Ignore invalid joint.
  2655. if ( !pJoint )
  2656. return b2Vec2_zero;
  2657. // Fetch joint type.
  2658. const b2JointType jointType = pJoint->GetType();
  2659. if ( jointType != e_motorJoint )
  2660. {
  2661. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2662. return b2Vec2_zero;
  2663. }
  2664. // Cast joint.
  2665. b2MotorJoint* pRealJoint = static_cast<b2MotorJoint*>( pJoint );
  2666. // Access joint.
  2667. return pRealJoint->GetLinearOffset();
  2668. }
  2669. //-----------------------------------------------------------------------------
  2670. void Scene::setMotorJointAngularOffset(
  2671. const U32 jointId,
  2672. const F32 angularOffset )
  2673. {
  2674. // Fetch joint.
  2675. b2Joint* pJoint = findJoint( jointId );
  2676. // Ignore invalid joint.
  2677. if ( !pJoint )
  2678. return;
  2679. // Fetch joint type.
  2680. const b2JointType jointType = pJoint->GetType();
  2681. if ( jointType != e_motorJoint )
  2682. {
  2683. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2684. return;
  2685. }
  2686. // Cast joint.
  2687. b2MotorJoint* pRealJoint = static_cast<b2MotorJoint*>( pJoint );
  2688. // Access joint.
  2689. pRealJoint->SetAngularOffset( angularOffset );
  2690. }
  2691. //-----------------------------------------------------------------------------
  2692. F32 Scene::getMotorJointAngularOffset( const U32 jointId )
  2693. {
  2694. // Fetch joint.
  2695. b2Joint* pJoint = findJoint( jointId );
  2696. // Ignore invalid joint.
  2697. if ( !pJoint )
  2698. return -1.0f;
  2699. // Fetch joint type.
  2700. const b2JointType jointType = pJoint->GetType();
  2701. if ( jointType != e_motorJoint )
  2702. {
  2703. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2704. return -1.0f;
  2705. }
  2706. // Cast joint.
  2707. b2MotorJoint* pRealJoint = static_cast<b2MotorJoint*>( pJoint );
  2708. // Access joint.
  2709. return pRealJoint->GetAngularOffset();
  2710. }
  2711. //-----------------------------------------------------------------------------
  2712. void Scene::setMotorJointMaxForce(
  2713. const U32 jointId,
  2714. const F32 maxForce )
  2715. {
  2716. // Fetch joint.
  2717. b2Joint* pJoint = findJoint( jointId );
  2718. // Ignore invalid joint.
  2719. if ( !pJoint )
  2720. return;
  2721. // Fetch joint type.
  2722. const b2JointType jointType = pJoint->GetType();
  2723. if ( jointType != e_motorJoint )
  2724. {
  2725. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2726. return;
  2727. }
  2728. // Cast joint.
  2729. b2MotorJoint* pRealJoint = static_cast<b2MotorJoint*>( pJoint );
  2730. // Access joint.
  2731. pRealJoint->SetMaxForce( maxForce );
  2732. }
  2733. //-----------------------------------------------------------------------------
  2734. F32 Scene::getMotorJointMaxForce( const U32 jointId )
  2735. {
  2736. // Fetch joint.
  2737. b2Joint* pJoint = findJoint( jointId );
  2738. // Ignore invalid joint.
  2739. if ( !pJoint )
  2740. return -1.0f;
  2741. // Fetch joint type.
  2742. const b2JointType jointType = pJoint->GetType();
  2743. if ( jointType != e_motorJoint )
  2744. {
  2745. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2746. return -1.0f;
  2747. }
  2748. // Cast joint.
  2749. b2MotorJoint* pRealJoint = static_cast<b2MotorJoint*>( pJoint );
  2750. // Access joint.
  2751. return pRealJoint->GetMaxForce();
  2752. }
  2753. //-----------------------------------------------------------------------------
  2754. void Scene::setMotorJointMaxTorque(
  2755. const U32 jointId,
  2756. const F32 maxTorque )
  2757. {
  2758. // Fetch joint.
  2759. b2Joint* pJoint = findJoint( jointId );
  2760. // Ignore invalid joint.
  2761. if ( !pJoint )
  2762. return;
  2763. // Fetch joint type.
  2764. const b2JointType jointType = pJoint->GetType();
  2765. if ( jointType != e_motorJoint )
  2766. {
  2767. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2768. return;
  2769. }
  2770. // Cast joint.
  2771. b2MotorJoint* pRealJoint = static_cast<b2MotorJoint*>( pJoint );
  2772. // Access joint.
  2773. pRealJoint->SetMaxTorque( maxTorque );
  2774. }
  2775. //-----------------------------------------------------------------------------
  2776. F32 Scene::getMotorJointMaxTorque( const U32 jointId )
  2777. {
  2778. // Fetch joint.
  2779. b2Joint* pJoint = findJoint( jointId );
  2780. // Ignore invalid joint.
  2781. if ( !pJoint )
  2782. return -1.0f;
  2783. // Fetch joint type.
  2784. const b2JointType jointType = pJoint->GetType();
  2785. if ( jointType != e_motorJoint )
  2786. {
  2787. Con::warnf( "Invalid joint type of %s.", getJointTypeDescription(jointType) );
  2788. return -1.0f;
  2789. }
  2790. // Cast joint.
  2791. b2MotorJoint* pRealJoint = static_cast<b2MotorJoint*>( pJoint );
  2792. // Access joint.
  2793. return pRealJoint->GetMaxTorque();
  2794. }
  2795. //-----------------------------------------------------------------------------
  2796. void Scene::setDebugSceneObject( SceneObject* pSceneObject )
  2797. {
  2798. // Ignore no change.
  2799. if ( mpDebugSceneObject == pSceneObject )
  2800. return;
  2801. // Remove delete notification for existing monitored object.
  2802. if ( mpDebugSceneObject != NULL )
  2803. clearNotify( mpDebugSceneObject );
  2804. // Set monitored scene object.
  2805. mpDebugSceneObject = pSceneObject;
  2806. // Finish if resetting monitored object.
  2807. if ( pSceneObject == NULL )
  2808. return;
  2809. // Add delete notification for new monitored object.
  2810. deleteNotify( pSceneObject );
  2811. }
  2812. //-----------------------------------------------------------------------------
  2813. void Scene::setLayerSortMode( const U32 layer, const SceneRenderQueue::RenderSort sortMode )
  2814. {
  2815. // Is the layer valid?
  2816. if ( layer > MAX_LAYERS_SUPPORTED )
  2817. {
  2818. // No, so warn.
  2819. Con::warnf( "Scene::setLayerSortMode() - Layer '%d' is out of range.", layer );
  2820. return;
  2821. }
  2822. // Is the sort mode valid?
  2823. if ( sortMode == SceneRenderQueue::RENDER_SORT_INVALID )
  2824. {
  2825. // No, so warn.
  2826. Con::warnf( "Scene::setLayerSortMode() - Sort mode is invalid for layer '%d'.", layer );
  2827. return;
  2828. }
  2829. mLayerSortModes[layer] = sortMode;
  2830. }
  2831. //-----------------------------------------------------------------------------
  2832. SceneRenderQueue::RenderSort Scene::getLayerSortMode( const U32 layer )
  2833. {
  2834. // Is the layer valid?
  2835. if ( layer > MAX_LAYERS_SUPPORTED )
  2836. {
  2837. // No, so warn.
  2838. Con::warnf( "Scene::getLayerSortMode() - Layer '%d' is out of range.", layer );
  2839. return SceneRenderQueue::RENDER_SORT_INVALID;
  2840. }
  2841. return mLayerSortModes[layer];
  2842. }
  2843. //-----------------------------------------------------------------------------
  2844. void Scene::attachSceneWindow( SceneWindow* pSceneWindow2D )
  2845. {
  2846. // Ignore if already attached.
  2847. if ( isSceneWindowAttached( pSceneWindow2D ) )
  2848. return;
  2849. // Add to Attached List.
  2850. mAttachedSceneWindows.addObject( pSceneWindow2D );
  2851. }
  2852. //-----------------------------------------------------------------------------
  2853. void Scene::detachSceneWindow( SceneWindow* pSceneWindow2D )
  2854. {
  2855. // Ignore if not attached.
  2856. if ( !isSceneWindowAttached( pSceneWindow2D ) )
  2857. return;
  2858. // Add to Attached List.
  2859. mAttachedSceneWindows.removeObject( pSceneWindow2D );
  2860. }
  2861. //-----------------------------------------------------------------------------
  2862. void Scene::detachAllSceneWindows( void )
  2863. {
  2864. // Detach All Scene Windows.
  2865. while( mAttachedSceneWindows.size() > 0 )
  2866. dynamic_cast<SceneWindow*>(mAttachedSceneWindows[mAttachedSceneWindows.size()-1])->resetScene();
  2867. }
  2868. //-----------------------------------------------------------------------------
  2869. bool Scene::isSceneWindowAttached( SceneWindow* pSceneWindow2D )
  2870. {
  2871. for( SimSet::iterator itr = mAttachedSceneWindows.begin(); itr != mAttachedSceneWindows.end(); itr++ )
  2872. if ( pSceneWindow2D == dynamic_cast<SceneWindow*>(*itr) )
  2873. // Found.
  2874. return true;
  2875. // Not Found.
  2876. return false;
  2877. }
  2878. //-----------------------------------------------------------------------------
  2879. void Scene::addDeleteRequest( SceneObject* pSceneObject )
  2880. {
  2881. // Ignore if it's already being safe-deleted.
  2882. if ( pSceneObject->isBeingDeleted() )
  2883. return;
  2884. // Populate Delete Request.
  2885. tDeleteRequest deleteRequest = { pSceneObject->getId(), NULL, false };
  2886. // Push Delete Request.
  2887. mDeleteRequests.push_back( deleteRequest );
  2888. // Flag Delete in Progress.
  2889. pSceneObject->mBeingSafeDeleted = true;
  2890. }
  2891. //-----------------------------------------------------------------------------
  2892. void Scene::processDeleteRequests( const bool forceImmediate )
  2893. {
  2894. // Ignore if there's no delete requests!
  2895. if ( mDeleteRequests.size() == 0 )
  2896. return;
  2897. // Validate All Delete Requests.
  2898. U32 safeDeleteReadyCount = 0;
  2899. for ( U32 requestIndex = 0; requestIndex < (U32)mDeleteRequests.size(); )
  2900. {
  2901. // Fetch Reference to Delete Request.
  2902. tDeleteRequest& deleteRequest = mDeleteRequests[requestIndex];
  2903. // Fetch Object.
  2904. // NOTE:- Let's be safer and check that it's definitely a scene-object.
  2905. SceneObject* pSceneObject = dynamic_cast<SceneObject*>( Sim::findObject( deleteRequest.mObjectId ) );
  2906. // Does this object exist?
  2907. if ( pSceneObject )
  2908. {
  2909. // Yes, so write object.
  2910. deleteRequest.mpSceneObject = pSceneObject;
  2911. // Calculate Safe-Ready Flag.
  2912. deleteRequest.mSafeDeleteReady = forceImmediate || pSceneObject->getSafeDelete();
  2913. // Is it ready to safe-delete?
  2914. if ( deleteRequest.mSafeDeleteReady )
  2915. {
  2916. // Yes, so increase safe-ready count.
  2917. ++safeDeleteReadyCount;
  2918. }
  2919. }
  2920. else
  2921. {
  2922. // No, so it looks like the object got deleted prematurely; let's just remove
  2923. // the request instead.
  2924. mDeleteRequests.erase_fast( requestIndex );
  2925. // Repeat this item.
  2926. continue;
  2927. }
  2928. // Skip to next request index.
  2929. ++requestIndex;
  2930. }
  2931. // Stop if there's no delete requests!
  2932. if ( mDeleteRequests.size() == 0 )
  2933. return;
  2934. // Transfer Delete-Requests to Temporary version.
  2935. // NOTE:- We do this because we may delete objects which have dependencies. This would
  2936. // cause objects to be added to the safe-delete list. We don't want to work on
  2937. // the list whilst this is happening so we'll transfer it to a temporary list.
  2938. mDeleteRequestsTemp = mDeleteRequests;
  2939. // Can we process all remaining delete-requests?
  2940. if ( safeDeleteReadyCount == (U32)mDeleteRequestsTemp.size() )
  2941. {
  2942. // Yes, so process ALL safe-ready delete-requests.
  2943. for ( U32 requestIndex = 0; requestIndex < (U32)mDeleteRequestsTemp.size(); ++requestIndex )
  2944. {
  2945. // Yes, so fetch object.
  2946. SceneObject* pSceneObject = mDeleteRequestsTemp[requestIndex].mpSceneObject;
  2947. // Do script callback.
  2948. Con::executef(this, 2, "onSafeDelete", pSceneObject->getIdString() );
  2949. // Destroy the object.
  2950. pSceneObject->deleteObject();
  2951. }
  2952. // Remove All delete-requests.
  2953. mDeleteRequestsTemp.clear();
  2954. }
  2955. else
  2956. {
  2957. // No, so process only safe-ready delete-requests.
  2958. for ( U32 requestIndex = 0; requestIndex <(U32) mDeleteRequestsTemp.size(); )
  2959. {
  2960. // Fetch Reference to Delete Request.
  2961. tDeleteRequest& deleteRequest = mDeleteRequestsTemp[requestIndex];
  2962. // Is the Object Safe-Ready?
  2963. if ( deleteRequest.mSafeDeleteReady )
  2964. {
  2965. // Yes, so fetch object.
  2966. SceneObject* pSceneObject = deleteRequest.mpSceneObject;
  2967. // Do script callback.
  2968. Con::executef(this, 2, "onSafeDelete", pSceneObject->getIdString() );
  2969. // Destroy the object.
  2970. pSceneObject->deleteObject();
  2971. // Quickly remove delete-request.
  2972. mDeleteRequestsTemp.erase_fast( requestIndex );
  2973. // Repeat this item.
  2974. continue;
  2975. }
  2976. // Skip to next request index.
  2977. ++requestIndex;
  2978. }
  2979. }
  2980. }
  2981. //-----------------------------------------------------------------------------
  2982. void Scene::SayGoodbye( b2Joint* pJoint )
  2983. {
  2984. // Find the joint id.
  2985. const U32 jointId = findJointId( pJoint );
  2986. // Ignore a bad joint.
  2987. if ( jointId == 0 )
  2988. return;
  2989. // Remove joint references.
  2990. mJoints.erase( jointId );
  2991. mReverseJoints.erase( pJoint );
  2992. }
  2993. //-----------------------------------------------------------------------------
  2994. SceneObject* Scene::create( const char* pType )
  2995. {
  2996. // Sanity!
  2997. AssertFatal( pType != NULL, "Scene::create() - Cannot create a NULL type." );
  2998. // Find the class rep.
  2999. AbstractClassRep* pClassRep = AbstractClassRep::findClassRep( pType );
  3000. // Did we find the type?
  3001. if ( pClassRep == NULL )
  3002. {
  3003. // No, so warn.
  3004. Con::warnf( "Scene::create() - Could not find type '%s' to create.", pType );
  3005. return NULL;
  3006. }
  3007. // Find the scene object rep.
  3008. AbstractClassRep* pSceneObjectRep = AbstractClassRep::findClassRep( "SceneObject" );
  3009. // Sanity!
  3010. AssertFatal( pSceneObjectRep != NULL, "Scene::create() - Could not find SceneObject class rep." );
  3011. // Is the type derived from scene object?
  3012. if ( !pClassRep->isClass( pSceneObjectRep ) )
  3013. {
  3014. // No, so warn.
  3015. Con::warnf( "Scene::create() - Type '%s' is not derived from SceneObject.", pType );
  3016. return NULL;
  3017. }
  3018. // Create the type.
  3019. SceneObject* pSceneObject = dynamic_cast<SceneObject*>( pClassRep->create() );
  3020. // Sanity!
  3021. AssertFatal( pSceneObject != NULL, "Scene::create() - Failed to create type via class rep." );
  3022. // Attempt to register the object.
  3023. if ( !pSceneObject->registerObject() )
  3024. {
  3025. // No, so warn.
  3026. Con::warnf( "Scene::create() - Failed to register type '%s'.", pType );
  3027. delete pSceneObject;
  3028. return NULL;
  3029. }
  3030. // Add to the scene.
  3031. addToScene( pSceneObject );
  3032. return pSceneObject;
  3033. }
  3034. //-----------------------------------------------------------------------------
  3035. void Scene::onTamlPreRead( void )
  3036. {
  3037. // Call parent.
  3038. Parent::onTamlPreRead();
  3039. }
  3040. //-----------------------------------------------------------------------------
  3041. void Scene::onTamlPostRead( const TamlCustomNodes& customNodes )
  3042. {
  3043. // Call parent.
  3044. Parent::onTamlPostRead( customNodes );
  3045. // Reset the loading scene.
  3046. Scene::LoadingScene = NULL;
  3047. // Find joint custom node.
  3048. const TamlCustomNode* pJointNode = customNodes.findNode( jointCustomNodeName );
  3049. // Do we have any joints?
  3050. if ( pJointNode != NULL )
  3051. {
  3052. // Yes, so fetch children joint nodes.
  3053. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3054. // Iterate joints.
  3055. for( TamlCustomNodeVector::const_iterator jointNodeItr = jointChildren.begin(); jointNodeItr != jointChildren.end(); ++jointNodeItr )
  3056. {
  3057. // Fetch joint node,
  3058. TamlCustomNode* pJointNode = *jointNodeItr;
  3059. // Fetch node name.
  3060. StringTableEntry nodeName = pJointNode->getNodeName();
  3061. // Is this a distance joint?
  3062. if ( nodeName == jointDistanceNodeName )
  3063. {
  3064. // Fetch joint children.
  3065. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3066. // Fetch joint objects.
  3067. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3068. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3069. // Did we get any connected objects?
  3070. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3071. {
  3072. // No, so warn.
  3073. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3074. continue;
  3075. }
  3076. b2Vec2 localAnchorA = b2Vec2_zero;
  3077. b2Vec2 localAnchorB = b2Vec2_zero;
  3078. bool collideConnected = false;
  3079. F32 length = -1.0f;
  3080. F32 frequency = 0.0f;
  3081. F32 dampingRatio = 0.0f;
  3082. // Fetch joint fields.
  3083. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3084. // Iterate property fields.
  3085. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3086. {
  3087. // Fetch field node.
  3088. TamlCustomField* pField = *jointFieldItr;
  3089. // Fetch property field name.
  3090. StringTableEntry fieldName = pField->getFieldName();
  3091. // Fetch fields.
  3092. if ( fieldName == jointLocalAnchorAName )
  3093. {
  3094. pField->getFieldValue( localAnchorA );
  3095. }
  3096. else if ( fieldName == jointLocalAnchorBName )
  3097. {
  3098. pField->getFieldValue( localAnchorB );
  3099. }
  3100. else if ( fieldName == jointCollideConnectedName )
  3101. {
  3102. pField->getFieldValue( collideConnected );
  3103. }
  3104. else if ( fieldName == jointDistanceLengthName )
  3105. {
  3106. pField->getFieldValue( length );
  3107. }
  3108. else if ( fieldName == jointDistanceFrequencyName )
  3109. {
  3110. pField->getFieldValue( frequency );
  3111. }
  3112. else if ( fieldName == jointDistanceDampingRatioName )
  3113. {
  3114. pField->getFieldValue( dampingRatio );
  3115. }
  3116. }
  3117. // Create joint.
  3118. createDistanceJoint( pSceneObjectA, pSceneObjectB, localAnchorA, localAnchorB, length, frequency, dampingRatio, collideConnected );
  3119. }
  3120. // is this a rope joint?
  3121. else if ( nodeName == jointRopeNodeName )
  3122. {
  3123. // Fetch joint children.
  3124. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3125. // Fetch joint objects.
  3126. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3127. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3128. // Did we get any connected objects?
  3129. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3130. {
  3131. // No, so warn.
  3132. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3133. continue;
  3134. }
  3135. b2Vec2 localAnchorA = b2Vec2_zero;
  3136. b2Vec2 localAnchorB = b2Vec2_zero;
  3137. bool collideConnected = false;
  3138. F32 maxLength = -1.0f;
  3139. // Fetch joint fields.
  3140. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3141. // Iterate property fields.
  3142. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3143. {
  3144. // Fetch field node.
  3145. TamlCustomField* pField = *jointFieldItr;
  3146. // Fetch property field name.
  3147. StringTableEntry fieldName = pField->getFieldName();
  3148. // Fetch fields.
  3149. if ( fieldName == jointLocalAnchorAName )
  3150. {
  3151. pField->getFieldValue( localAnchorA );
  3152. }
  3153. else if ( fieldName == jointLocalAnchorBName )
  3154. {
  3155. pField->getFieldValue( localAnchorB );
  3156. }
  3157. else if ( fieldName == jointCollideConnectedName )
  3158. {
  3159. pField->getFieldValue( collideConnected );
  3160. }
  3161. else if ( fieldName == jointRopeMaxLengthName )
  3162. {
  3163. pField->getFieldValue( maxLength );
  3164. }
  3165. }
  3166. // Create joint.
  3167. createRopeJoint( pSceneObjectA, pSceneObjectB, localAnchorA, localAnchorB, maxLength, collideConnected );
  3168. }
  3169. // Is this a revolute joint?
  3170. else if ( nodeName == jointRevoluteNodeName )
  3171. {
  3172. // Fetch joint children.
  3173. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3174. // Fetch joint objects.
  3175. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3176. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3177. // Did we get any connected objects?
  3178. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3179. {
  3180. // No, so warn.
  3181. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3182. continue;
  3183. }
  3184. b2Vec2 localAnchorA = b2Vec2_zero;
  3185. b2Vec2 localAnchorB = b2Vec2_zero;
  3186. bool collideConnected = false;
  3187. bool enableLimit = false;
  3188. F32 lowerAngle = 0.0f;
  3189. F32 upperAngle = 0.0f;
  3190. bool enableMotor = false;
  3191. F32 motorSpeed = b2_pi;
  3192. F32 maxMotorTorque = 0.0f;
  3193. // Fetch joint fields.
  3194. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3195. // Iterate property fields.
  3196. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3197. {
  3198. // Fetch field node.
  3199. TamlCustomField* pField = *jointFieldItr;
  3200. // Fetch property field name.
  3201. StringTableEntry fieldName = pField->getFieldName();
  3202. // Fetch fields.
  3203. if ( fieldName == jointLocalAnchorAName )
  3204. {
  3205. pField->getFieldValue( localAnchorA );
  3206. }
  3207. else if ( fieldName == jointLocalAnchorBName )
  3208. {
  3209. pField->getFieldValue( localAnchorB );
  3210. }
  3211. else if ( fieldName == jointCollideConnectedName )
  3212. {
  3213. pField->getFieldValue( collideConnected );
  3214. }
  3215. else if ( fieldName == jointRevoluteLimitLowerAngleName )
  3216. {
  3217. pField->getFieldValue( lowerAngle );
  3218. lowerAngle = mDegToRad( lowerAngle );
  3219. enableLimit = true;
  3220. }
  3221. else if ( fieldName == jointRevoluteLimitUpperAngleName )
  3222. {
  3223. pField->getFieldValue( upperAngle );
  3224. upperAngle = mDegToRad( upperAngle );
  3225. enableLimit = true;
  3226. }
  3227. else if ( fieldName == jointRevoluteMotorSpeedName )
  3228. {
  3229. pField->getFieldValue( motorSpeed );
  3230. motorSpeed = mDegToRad( motorSpeed );
  3231. enableMotor = true;
  3232. }
  3233. else if ( fieldName == jointRevoluteMotorMaxTorqueName )
  3234. {
  3235. pField->getFieldValue( maxMotorTorque );
  3236. enableMotor = true;
  3237. }
  3238. }
  3239. // Create joint.
  3240. const U32 jointId = createRevoluteJoint( pSceneObjectA, pSceneObjectB, localAnchorA, localAnchorB, collideConnected );
  3241. if ( enableLimit )
  3242. setRevoluteJointLimit( jointId, true, lowerAngle, upperAngle );
  3243. if ( enableMotor )
  3244. setRevoluteJointMotor( jointId, true, motorSpeed, maxMotorTorque );
  3245. }
  3246. // is this a weld joint?
  3247. else if ( nodeName == jointWeldNodeName )
  3248. {
  3249. // Fetch joint children.
  3250. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3251. // Fetch joint objects.
  3252. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3253. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3254. // Did we get any connected objects?
  3255. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3256. {
  3257. // No, so warn.
  3258. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3259. continue;
  3260. }
  3261. b2Vec2 localAnchorA = b2Vec2_zero;
  3262. b2Vec2 localAnchorB = b2Vec2_zero;
  3263. bool collideConnected = false;
  3264. F32 frequency = 0.0f;
  3265. F32 dampingRatio = 0.0f;
  3266. // Fetch joint fields.
  3267. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3268. // Iterate property fields.
  3269. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3270. {
  3271. // Fetch field node.
  3272. TamlCustomField* pField = *jointFieldItr;
  3273. // Fetch property field name.
  3274. StringTableEntry fieldName = pField->getFieldName();
  3275. // Fetch fields.
  3276. if ( fieldName == jointLocalAnchorAName )
  3277. {
  3278. pField->getFieldValue( localAnchorA );
  3279. }
  3280. else if ( fieldName == jointLocalAnchorBName )
  3281. {
  3282. pField->getFieldValue( localAnchorB );
  3283. }
  3284. else if ( fieldName == jointCollideConnectedName )
  3285. {
  3286. pField->getFieldValue( collideConnected );
  3287. }
  3288. else if ( fieldName == jointWeldFrequencyName )
  3289. {
  3290. pField->getFieldValue( frequency );
  3291. }
  3292. else if ( fieldName == jointWeldDampingRatioName )
  3293. {
  3294. pField->getFieldValue( dampingRatio );
  3295. }
  3296. }
  3297. // Create joint.
  3298. createWeldJoint( pSceneObjectA, pSceneObjectB, localAnchorA, localAnchorB, frequency, dampingRatio, collideConnected );
  3299. }
  3300. // Is this a wheel joint?
  3301. else if ( nodeName == jointWheelNodeName )
  3302. {
  3303. // Fetch joint children.
  3304. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3305. // Fetch joint objects.
  3306. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3307. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3308. // Did we get any connected objects?
  3309. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3310. {
  3311. // No, so warn.
  3312. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3313. continue;
  3314. }
  3315. b2Vec2 localAnchorA = b2Vec2_zero;
  3316. b2Vec2 localAnchorB = b2Vec2_zero;
  3317. bool collideConnected = false;
  3318. bool enableMotor = false;
  3319. F32 motorSpeed = b2_pi;
  3320. F32 maxMotorTorque = 0.0f;
  3321. F32 frequency = 0.0f;
  3322. F32 dampingRatio = 0.0f;
  3323. b2Vec2 worldAxis( 0.0f, 1.0f );
  3324. // Fetch joint fields.
  3325. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3326. // Iterate property fields.
  3327. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3328. {
  3329. // Fetch field node.
  3330. TamlCustomField* pField = *jointFieldItr;
  3331. // Fetch property field name.
  3332. StringTableEntry fieldName = pField->getFieldName();
  3333. // Fetch fields.
  3334. if ( fieldName == jointLocalAnchorAName )
  3335. {
  3336. pField->getFieldValue( localAnchorA );
  3337. }
  3338. else if ( fieldName == jointLocalAnchorBName )
  3339. {
  3340. pField->getFieldValue( localAnchorB );
  3341. }
  3342. else if ( fieldName == jointCollideConnectedName )
  3343. {
  3344. pField->getFieldValue( collideConnected );
  3345. }
  3346. else if ( fieldName == jointWheelMotorSpeedName )
  3347. {
  3348. pField->getFieldValue( motorSpeed );
  3349. motorSpeed = mDegToRad( motorSpeed );
  3350. enableMotor = true;
  3351. }
  3352. else if ( fieldName == jointWheelMotorMaxTorqueName )
  3353. {
  3354. pField->getFieldValue( maxMotorTorque );
  3355. enableMotor = true;
  3356. }
  3357. else if ( fieldName == jointWheelFrequencyName )
  3358. {
  3359. pField->getFieldValue( frequency );
  3360. }
  3361. else if ( fieldName == jointWheelDampingRatioName )
  3362. {
  3363. pField->getFieldValue( dampingRatio );
  3364. }
  3365. else if ( fieldName == jointWheelWorldAxisName )
  3366. {
  3367. pField->getFieldValue( worldAxis );
  3368. }
  3369. }
  3370. // Create joint.
  3371. const U32 jointId = createWheelJoint( pSceneObjectA, pSceneObjectB, localAnchorA, localAnchorB, worldAxis, collideConnected );
  3372. if ( enableMotor )
  3373. setWheelJointMotor( jointId, true, motorSpeed, maxMotorTorque );
  3374. setWheelJointFrequency( jointId, frequency );
  3375. setWheelJointDampingRatio( jointId, dampingRatio );
  3376. }
  3377. // Is this a friction joint?
  3378. else if ( nodeName == jointFrictionNodeName )
  3379. {
  3380. // Fetch joint children.
  3381. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3382. // Fetch joint objects.
  3383. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3384. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3385. // Did we get any connected objects?
  3386. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3387. {
  3388. // No, so warn.
  3389. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3390. continue;
  3391. }
  3392. b2Vec2 localAnchorA = b2Vec2_zero;
  3393. b2Vec2 localAnchorB = b2Vec2_zero;
  3394. bool collideConnected = false;
  3395. F32 maxForce = 0.0f;
  3396. F32 maxTorque = 0.0f;
  3397. // Fetch joint fields.
  3398. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3399. // Iterate property fields.
  3400. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3401. {
  3402. // Fetch field node.
  3403. TamlCustomField* pField = *jointFieldItr;
  3404. // Fetch property field name.
  3405. StringTableEntry fieldName = pField->getFieldName();
  3406. // Fetch fields.
  3407. if ( fieldName == jointLocalAnchorAName )
  3408. {
  3409. pField->getFieldValue( localAnchorA );
  3410. }
  3411. else if ( fieldName == jointLocalAnchorBName )
  3412. {
  3413. pField->getFieldValue( localAnchorB );
  3414. }
  3415. else if ( fieldName == jointCollideConnectedName )
  3416. {
  3417. pField->getFieldValue( collideConnected );
  3418. }
  3419. else if ( fieldName == jointFrictionMaxForceName )
  3420. {
  3421. pField->getFieldValue( maxForce );
  3422. }
  3423. else if ( fieldName == jointFrictionMaxTorqueName )
  3424. {
  3425. pField->getFieldValue( maxTorque );
  3426. }
  3427. }
  3428. // Create joint.
  3429. createFrictionJoint( pSceneObjectA, pSceneObjectB, localAnchorA, localAnchorB, maxForce, maxTorque, collideConnected );
  3430. }
  3431. // Is this a prismatic joint?
  3432. else if ( nodeName == jointPrismaticNodeName )
  3433. {
  3434. // Fetch joint children.
  3435. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3436. // Fetch joint objects.
  3437. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3438. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3439. // Did we get any connected objects?
  3440. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3441. {
  3442. // No, so warn.
  3443. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3444. continue;
  3445. }
  3446. b2Vec2 localAnchorA = b2Vec2_zero;
  3447. b2Vec2 localAnchorB = b2Vec2_zero;
  3448. bool collideConnected = false;
  3449. bool enableLimit;
  3450. F32 lowerTransLimit = 0.0f;
  3451. F32 upperTransLimit = 1.0f;
  3452. bool enableMotor = false;
  3453. F32 motorSpeed = b2_pi;
  3454. F32 maxMotorForce = 0.0f;
  3455. b2Vec2 worldAxis( 0.0f, 1.0f );
  3456. // Fetch joint fields.
  3457. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3458. // Iterate property fields.
  3459. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3460. {
  3461. // Fetch field node.
  3462. TamlCustomField* pField = *jointFieldItr;
  3463. // Fetch property field name.
  3464. StringTableEntry fieldName = pField->getFieldName();
  3465. // Fetch fields.
  3466. if ( fieldName == jointLocalAnchorAName )
  3467. {
  3468. pField->getFieldValue( localAnchorA );
  3469. }
  3470. else if ( fieldName == jointLocalAnchorBName )
  3471. {
  3472. pField->getFieldValue( localAnchorB );
  3473. }
  3474. else if ( fieldName == jointCollideConnectedName )
  3475. {
  3476. pField->getFieldValue( collideConnected );
  3477. }
  3478. else if ( fieldName == jointPrismaticLimitLowerTransName )
  3479. {
  3480. pField->getFieldValue( lowerTransLimit );
  3481. enableLimit = true;
  3482. }
  3483. else if ( fieldName == jointPrismaticLimitUpperTransName )
  3484. {
  3485. pField->getFieldValue( upperTransLimit );
  3486. enableLimit = true;
  3487. }
  3488. else if ( fieldName == jointPrismaticMotorSpeedName )
  3489. {
  3490. pField->getFieldValue( motorSpeed );
  3491. motorSpeed = mDegToRad( motorSpeed );
  3492. enableMotor = true;
  3493. }
  3494. else if ( fieldName == jointPrismaticMotorMaxForceName )
  3495. {
  3496. pField->getFieldValue( maxMotorForce );
  3497. enableMotor = true;
  3498. }
  3499. else if ( fieldName == jointPrismaticWorldAxisName )
  3500. {
  3501. pField->getFieldValue( worldAxis );
  3502. }
  3503. }
  3504. // Create joint.
  3505. const U32 jointId = createPrismaticJoint( pSceneObjectA, pSceneObjectB, localAnchorA, localAnchorB, worldAxis, collideConnected );
  3506. if ( enableLimit )
  3507. setPrismaticJointLimit( jointId, true, lowerTransLimit, upperTransLimit );
  3508. if ( enableMotor )
  3509. setPrismaticJointMotor( jointId, true, motorSpeed, maxMotorForce );
  3510. }
  3511. // Is this a pulley joint?
  3512. else if ( nodeName == jointPulleyNodeName )
  3513. {
  3514. // Fetch joint children.
  3515. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3516. // Fetch joint objects.
  3517. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3518. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3519. // Did we get any connected objects?
  3520. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3521. {
  3522. // No, so warn.
  3523. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3524. continue;
  3525. }
  3526. b2Vec2 localAnchorA = b2Vec2_zero;
  3527. b2Vec2 localAnchorB = b2Vec2_zero;
  3528. bool collideConnected = false;
  3529. F32 lengthA = -1.0f;
  3530. F32 lengthB = -1.0f;
  3531. F32 ratio = 0.5f;
  3532. b2Vec2 worldGroundAnchorA = b2Vec2_zero;
  3533. b2Vec2 worldGroundAnchorB = b2Vec2_zero;
  3534. // Fetch joint fields.
  3535. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3536. // Iterate property fields.
  3537. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3538. {
  3539. // Fetch field node.
  3540. TamlCustomField* pField = *jointFieldItr;
  3541. // Fetch property field name.
  3542. StringTableEntry fieldName = pField->getFieldName();
  3543. // Fetch fields.
  3544. if ( fieldName == jointLocalAnchorAName )
  3545. {
  3546. pField->getFieldValue( localAnchorA );
  3547. }
  3548. else if ( fieldName == jointLocalAnchorBName )
  3549. {
  3550. pField->getFieldValue( localAnchorB );
  3551. }
  3552. else if ( fieldName == jointCollideConnectedName )
  3553. {
  3554. pField->getFieldValue( collideConnected );
  3555. }
  3556. else if ( fieldName == jointPulleyLengthAName )
  3557. {
  3558. pField->getFieldValue( lengthA );
  3559. }
  3560. else if ( fieldName == jointPulleyLengthBName )
  3561. {
  3562. pField->getFieldValue( lengthB );
  3563. }
  3564. else if ( fieldName == jointPulleyRatioName )
  3565. {
  3566. pField->getFieldValue( ratio );
  3567. }
  3568. else if ( fieldName == jointPulleyGroundAnchorAName )
  3569. {
  3570. pField->getFieldValue( worldGroundAnchorA );
  3571. }
  3572. else if ( fieldName == jointPulleyGroundAnchorBName )
  3573. {
  3574. pField->getFieldValue( worldGroundAnchorB );
  3575. }
  3576. }
  3577. // Create joint.
  3578. createPulleyJoint( pSceneObjectA, pSceneObjectB, localAnchorA, localAnchorB, worldGroundAnchorA, worldGroundAnchorB, ratio, lengthA, lengthB, collideConnected );
  3579. }
  3580. // Is this a target joint?
  3581. else if ( nodeName == jointTargetNodeName )
  3582. {
  3583. // Fetch joint children.
  3584. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3585. // Fetch joint objects.
  3586. SceneObject* pSceneObject = jointChildren.size() == 1 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3587. // Did we get any connected objects?
  3588. if( pSceneObject == NULL )
  3589. {
  3590. // No, so warn.
  3591. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has an invalid connected object.", nodeName );
  3592. continue;
  3593. }
  3594. bool collideConnected = false;
  3595. b2Vec2 worldTarget = b2Vec2_zero;
  3596. F32 maxForce = 1.0f;
  3597. F32 frequency = 5.0f;
  3598. F32 dampingRatio = 0.7f;
  3599. // Fetch joint fields.
  3600. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3601. // Iterate property fields.
  3602. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3603. {
  3604. // Fetch field node.
  3605. TamlCustomField* pField = *jointFieldItr;
  3606. // Fetch property field name.
  3607. StringTableEntry fieldName = pField->getFieldName();
  3608. // Fetch fields.
  3609. if ( fieldName == jointCollideConnectedName )
  3610. {
  3611. pField->getFieldValue( collideConnected );
  3612. }
  3613. else if ( fieldName == jointTargetWorldTargetName )
  3614. {
  3615. pField->getFieldValue( worldTarget );
  3616. }
  3617. else if ( fieldName == jointTargetMaxForceName )
  3618. {
  3619. pField->getFieldValue( maxForce );
  3620. }
  3621. else if ( fieldName == jointTargetFrequencyName )
  3622. {
  3623. pField->getFieldValue( frequency );
  3624. }
  3625. else if ( fieldName == jointTargetDampingRatioName )
  3626. {
  3627. pField->getFieldValue( dampingRatio );
  3628. }
  3629. }
  3630. // Create joint.
  3631. createTargetJoint( pSceneObject, worldTarget, maxForce, frequency, dampingRatio, collideConnected );
  3632. }
  3633. // Is this a motor joint?
  3634. else if ( nodeName == jointMotorNodeName )
  3635. {
  3636. // Fetch joint children.
  3637. const TamlCustomNodeVector& jointChildren = pJointNode->getChildren();
  3638. // Fetch joint objects.
  3639. SceneObject* pSceneObjectA = jointChildren.size() > 0 ? jointChildren[0]->getProxyObject<SceneObject>(true) : NULL;
  3640. SceneObject* pSceneObjectB = jointChildren.size() == 2 ? jointChildren[1]->getProxyObject<SceneObject>(true) : NULL;
  3641. // Did we get any connected objects?
  3642. if( pSceneObjectA == NULL && pSceneObjectB == NULL )
  3643. {
  3644. // No, so warn.
  3645. Con::warnf( "Scene::onTamlPostRead() - Encountered a joint '%s' but it has invalid connected objects.", nodeName );
  3646. continue;
  3647. }
  3648. bool collideConnected = false;
  3649. b2Vec2 linearOffset = b2Vec2_zero;
  3650. F32 angularOffset = 0.0f;
  3651. F32 maxForce = 1.0f;
  3652. F32 maxTorque = 1.0f;
  3653. F32 correctionFactor = 0.3f;
  3654. // Fetch joint fields.
  3655. const TamlCustomFieldVector& jointFields = pJointNode->getFields();
  3656. // Iterate property fields.
  3657. for ( TamlCustomFieldVector::const_iterator jointFieldItr = jointFields.begin(); jointFieldItr != jointFields.end(); ++jointFieldItr )
  3658. {
  3659. // Fetch field node.
  3660. TamlCustomField* pField = *jointFieldItr;
  3661. // Fetch property field name.
  3662. StringTableEntry fieldName = pField->getFieldName();
  3663. // Fetch fields.
  3664. if ( fieldName == jointCollideConnectedName )
  3665. {
  3666. pField->getFieldValue( collideConnected );
  3667. }
  3668. else if ( fieldName == jointMotorLinearOffsetName )
  3669. {
  3670. pField->getFieldValue( linearOffset );
  3671. }
  3672. else if ( fieldName == jointMotorAngularOffsetName )
  3673. {
  3674. pField->getFieldValue( angularOffset );
  3675. angularOffset = mDegToRad( angularOffset );
  3676. }
  3677. else if ( fieldName == jointMotorMaxForceName )
  3678. {
  3679. pField->getFieldValue( maxForce );
  3680. }
  3681. else if ( fieldName == jointMotorMaxTorqueName )
  3682. {
  3683. pField->getFieldValue( maxTorque );
  3684. }
  3685. else if ( fieldName == jointMotorCorrectionFactorName )
  3686. {
  3687. pField->getFieldValue( correctionFactor );
  3688. }
  3689. }
  3690. // Create joint.
  3691. createMotorJoint( pSceneObjectA, pSceneObjectB, linearOffset, angularOffset, maxForce, maxTorque, correctionFactor, collideConnected );
  3692. }
  3693. // Unknown joint type!
  3694. else
  3695. {
  3696. // Warn.
  3697. Con::warnf( "Unknown joint type of '%s' encountered.", nodeName );
  3698. // Sanity!
  3699. AssertFatal( false, "Scene::onTamlCustomRead() - Unknown joint type detected." );
  3700. continue;
  3701. }
  3702. }
  3703. }
  3704. // Find controller custom node.
  3705. const TamlCustomNode* pControllerCustomNode = customNodes.findNode( controllerCustomNodeName );
  3706. // Do we have any controllers?
  3707. if ( pControllerCustomNode != NULL )
  3708. {
  3709. // Yes, so fetch the scene controllers.
  3710. SimSet* pControllerSet = getControllers();
  3711. // Fetch children controller nodes.
  3712. const TamlCustomNodeVector& controllerChildren = pControllerCustomNode->getChildren();
  3713. // Iterate controllers.
  3714. for( TamlCustomNodeVector::const_iterator controllerNodeItr = controllerChildren.begin(); controllerNodeItr != controllerChildren.end(); ++controllerNodeItr )
  3715. {
  3716. // Fetch controller node.
  3717. TamlCustomNode* pControllerNode = *controllerNodeItr;
  3718. // Is the node a proxy object?
  3719. if ( !pControllerNode->isProxyObject() )
  3720. {
  3721. // No, so warn.
  3722. Con::warnf("Scene::onTamlPostRead() - Reading scene controllers but node '%s'is not an object.", pControllerNode->getNodeName() );
  3723. continue;
  3724. }
  3725. // Add the proxy object.
  3726. SimObject* pProxyObject = pControllerNode->getProxyObject<SimObject>(false);
  3727. // Is it a scene controller?
  3728. if ( dynamic_cast<SceneController*>( pProxyObject ) == NULL )
  3729. {
  3730. // No, so warn.
  3731. Con::warnf("Scene::onTamlPostRead() - Reading scene controllers but node '%s'is not a scene controller.", pControllerNode->getNodeName() );
  3732. // Delete the object.
  3733. pProxyObject->deleteObject();
  3734. continue;
  3735. }
  3736. // Add to scene controllers.
  3737. pControllerSet->addObject( pProxyObject );
  3738. }
  3739. }
  3740. // Find asset preload custom node.
  3741. const TamlCustomNode* pAssetPreloadNode = customNodes.findNode( assetPreloadNodeName );
  3742. // Do we have any asset preloads?
  3743. if ( pAssetPreloadNode != NULL )
  3744. {
  3745. // Yes, so clear any existing asset preloads.
  3746. clearAssetPreloads();
  3747. // Yes, so fetch asset Id type prefix.
  3748. StringTableEntry assetIdTypePrefix = ConsoleBaseType::getType( TypeAssetId )->getTypePrefix();
  3749. // Fetch the prefix length.
  3750. const S32 assetIdPrefixLength = dStrlen( assetIdTypePrefix );
  3751. // Fetch the preload children nodes.
  3752. const TamlCustomNodeVector& preloadChildren = pAssetPreloadNode->getChildren();
  3753. // Iterate asset preloads.
  3754. for( TamlCustomNodeVector::const_iterator assetPreloadNodeItr = preloadChildren.begin(); assetPreloadNodeItr != preloadChildren.end(); ++assetPreloadNodeItr )
  3755. {
  3756. // Fetch asset node.
  3757. const TamlCustomNode* pAssetNode = *assetPreloadNodeItr;
  3758. // Ignore non-asset nodes.
  3759. if ( pAssetNode->getNodeName() != assetNodeName )
  3760. continue;
  3761. // Find the asset Id field.
  3762. const TamlCustomField* pAssetIdField = pAssetNode->findField( "Id" );
  3763. // Did we find the field?
  3764. if ( pAssetIdField == NULL )
  3765. {
  3766. // No, so warn.
  3767. Con::warnf("Scene::onTamlPostRead() - Found asset preload but failed to find asset Id field." );
  3768. continue;
  3769. }
  3770. // Fetch field value.
  3771. const char* pFieldValue = pAssetIdField->getFieldValue();
  3772. // Calculate the field value start (skip any type prefix).
  3773. const S32 prefixOffset = dStrnicmp( pFieldValue, assetIdTypePrefix, assetIdPrefixLength ) == 0 ? assetIdPrefixLength : 0;
  3774. // Add asset preload.
  3775. addAssetPreload( pFieldValue + prefixOffset );
  3776. }
  3777. }
  3778. }
  3779. //-----------------------------------------------------------------------------
  3780. void Scene::onTamlCustomWrite( TamlCustomNodes& customNodes )
  3781. {
  3782. // Call parent.
  3783. Parent::onTamlCustomWrite( customNodes );
  3784. // Fetch joint count.
  3785. const U32 jointCount = getJointCount();
  3786. // Do we have any joints?
  3787. if ( jointCount > 0 )
  3788. {
  3789. // Yes, so add joint custom node.
  3790. TamlCustomNode* pJointCustomNode = customNodes.addNode( jointCustomNodeName );
  3791. // Iterate joints.
  3792. for( typeJointHash::iterator jointItr = mJoints.begin(); jointItr != mJoints.end(); ++jointItr )
  3793. {
  3794. // Fetch base joint.
  3795. b2Joint* pBaseJoint = jointItr->value;
  3796. // Add joint node.
  3797. // NOTE: The name of the node will get updated shortly.
  3798. TamlCustomNode* pJointNode = pJointCustomNode->addNode( StringTable->EmptyString );
  3799. // Fetch common details.
  3800. b2Body* pBodyA = pBaseJoint->GetBodyA();
  3801. b2Body* pBodyB = pBaseJoint->GetBodyB();
  3802. // Fetch physics proxies.
  3803. PhysicsProxy* pPhysicsProxyA = static_cast<PhysicsProxy*>(pBodyA->GetUserData());
  3804. PhysicsProxy* pPhysicsProxyB = static_cast<PhysicsProxy*>(pBodyB->GetUserData());
  3805. // Fetch physics proxy type.
  3806. PhysicsProxy::ePhysicsProxyType proxyTypeA = static_cast<PhysicsProxy*>(pBodyA->GetUserData())->getPhysicsProxyType();
  3807. PhysicsProxy::ePhysicsProxyType proxyTypeB = static_cast<PhysicsProxy*>(pBodyB->GetUserData())->getPhysicsProxyType();
  3808. // Fetch scene objects.
  3809. SceneObject* pSceneObjectA = proxyTypeA == PhysicsProxy::PHYSIC_PROXY_SCENEOBJECT ? static_cast<SceneObject*>(pPhysicsProxyA) : NULL;
  3810. SceneObject* pSceneObjectB = proxyTypeB == PhysicsProxy::PHYSIC_PROXY_SCENEOBJECT ? static_cast<SceneObject*>(pPhysicsProxyB) : NULL;
  3811. // Populate joint appropriately.
  3812. switch( pBaseJoint->GetType() )
  3813. {
  3814. case e_distanceJoint:
  3815. {
  3816. // Set joint name.
  3817. pJointNode->setNodeName( jointDistanceNodeName );
  3818. // Fetch joint.
  3819. const b2DistanceJoint* pJoint = dynamic_cast<const b2DistanceJoint*>( pBaseJoint );
  3820. // Sanity!
  3821. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid distance joint type returned." );
  3822. // Add length.
  3823. pJointNode->addField( jointDistanceLengthName, pJoint->GetLength() );
  3824. // Add frequency.
  3825. if ( mNotZero( pJoint->GetFrequency() ) )
  3826. pJointNode->addField( jointDistanceFrequencyName, pJoint->GetFrequency() );
  3827. // Add damping ratio.
  3828. if ( mNotZero( pJoint->GetDampingRatio() ) )
  3829. pJointNode->addField( jointDistanceDampingRatioName, pJoint->GetDampingRatio() );
  3830. // Add local anchors.
  3831. if ( mNotZero( pJoint->GetLocalAnchorA().LengthSquared() ) )
  3832. pJointNode->addField( jointLocalAnchorAName, pJoint->GetLocalAnchorA() );
  3833. if ( mNotZero( pJoint->GetLocalAnchorB().LengthSquared() ) )
  3834. pJointNode->addField( jointLocalAnchorBName, pJoint->GetLocalAnchorB() );
  3835. // Add scene object bodies.
  3836. if ( pSceneObjectA != NULL )
  3837. pJointNode->addNode( pSceneObjectA );
  3838. if ( pSceneObjectB != NULL )
  3839. pJointNode->addNode( pSceneObjectB );
  3840. }
  3841. break;
  3842. case e_ropeJoint:
  3843. {
  3844. // Set joint name.
  3845. pJointNode->setNodeName( jointRopeNodeName );
  3846. // Fetch joint.
  3847. const b2RopeJoint* pJoint = dynamic_cast<const b2RopeJoint*>( pBaseJoint );
  3848. // Sanity!
  3849. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid rope joint type returned." );
  3850. // Add max length.
  3851. if ( mNotZero( pJoint->GetMaxLength() ) )
  3852. pJointNode->addField( jointRopeMaxLengthName, pJoint->GetMaxLength() );
  3853. // Add local anchors.
  3854. if ( mNotZero( pJoint->GetLocalAnchorA().LengthSquared() ) )
  3855. pJointNode->addField( jointLocalAnchorAName, pJoint->GetLocalAnchorA() );
  3856. if ( mNotZero( pJoint->GetLocalAnchorB().LengthSquared() ) )
  3857. pJointNode->addField( jointLocalAnchorBName, pJoint->GetLocalAnchorB() );
  3858. // Add scene object bodies.
  3859. if ( pSceneObjectA != NULL )
  3860. pJointNode->addNode( pSceneObjectA );
  3861. if ( pSceneObjectB != NULL )
  3862. pJointNode->addNode( pSceneObjectB );
  3863. }
  3864. break;
  3865. case e_revoluteJoint:
  3866. {
  3867. // Set join name.
  3868. pJointNode->setNodeName( jointRevoluteNodeName );
  3869. // Fetch joint.
  3870. const b2RevoluteJoint* pJoint = dynamic_cast<const b2RevoluteJoint*>( pBaseJoint );
  3871. // Sanity!
  3872. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid revolute joint type returned." );
  3873. // Add limit.
  3874. if ( pJoint->IsLimitEnabled() )
  3875. {
  3876. // Add limits.
  3877. pJointNode->addField( jointRevoluteLimitLowerAngleName, mRadToDeg(pJoint->GetLowerLimit()) );
  3878. pJointNode->addField( jointRevoluteLimitUpperAngleName, mRadToDeg(pJoint->GetUpperLimit()) );
  3879. }
  3880. // Add motor.
  3881. if ( pJoint->IsMotorEnabled() )
  3882. {
  3883. // Add motor.
  3884. pJointNode->addField( jointRevoluteMotorSpeedName, mRadToDeg(pJoint->GetMotorSpeed()) );
  3885. pJointNode->addField( jointRevoluteMotorMaxTorqueName, pJoint->GetMaxMotorTorque() );
  3886. }
  3887. // Add local anchors.
  3888. if ( mNotZero( pJoint->GetLocalAnchorA().LengthSquared() ) )
  3889. pJointNode->addField( jointLocalAnchorAName, pJoint->GetLocalAnchorA() );
  3890. if ( mNotZero( pJoint->GetLocalAnchorB().LengthSquared() ) )
  3891. pJointNode->addField( jointLocalAnchorBName, pJoint->GetLocalAnchorB() );
  3892. // Add scene object bodies.
  3893. if ( pSceneObjectA != NULL )
  3894. pJointNode->addNode( pSceneObjectA );
  3895. if ( pSceneObjectB != NULL )
  3896. pJointNode->addNode( pSceneObjectB );
  3897. }
  3898. break;
  3899. case e_weldJoint:
  3900. {
  3901. // Set joint name.
  3902. pJointNode->setNodeName( jointWeldNodeName );
  3903. // Fetch joint.
  3904. const b2WeldJoint* pJoint = dynamic_cast<const b2WeldJoint*>( pBaseJoint );
  3905. // Sanity!
  3906. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid weld joint type returned." );
  3907. // Add frequency.
  3908. if ( mNotZero( pJoint->GetFrequency() ) )
  3909. pJointNode->addField( jointWeldFrequencyName, pJoint->GetFrequency() );
  3910. // Add damping ratio.
  3911. if ( mNotZero( pJoint->GetDampingRatio() ) )
  3912. pJointNode->addField( jointWeldDampingRatioName, pJoint->GetDampingRatio() );
  3913. // Add local anchors.
  3914. if ( mNotZero( pJoint->GetLocalAnchorA().LengthSquared() ) )
  3915. pJointNode->addField( jointLocalAnchorAName, pJoint->GetLocalAnchorA() );
  3916. if ( mNotZero( pJoint->GetLocalAnchorB().LengthSquared() ) )
  3917. pJointNode->addField( jointLocalAnchorBName, pJoint->GetLocalAnchorB() );
  3918. // Add scene object bodies.
  3919. if ( pSceneObjectA != NULL )
  3920. pJointNode->addNode( pSceneObjectA );
  3921. if ( pSceneObjectB != NULL )
  3922. pJointNode->addNode( pSceneObjectB );
  3923. }
  3924. break;
  3925. case e_wheelJoint:
  3926. {
  3927. // Set joint name.
  3928. pJointNode->setNodeName( jointWheelNodeName );
  3929. // Fetch joint.
  3930. b2WheelJoint* pJoint = dynamic_cast<b2WheelJoint*>( pBaseJoint );
  3931. // Sanity!
  3932. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid wheel joint type returned." );
  3933. // Add motor.
  3934. if ( pJoint->IsMotorEnabled() )
  3935. {
  3936. // Add motor.
  3937. pJointNode->addField( jointWheelMotorSpeedName, mRadToDeg(pJoint->GetMotorSpeed()) );
  3938. pJointNode->addField( jointWheelMotorMaxTorqueName, pJoint->GetMaxMotorTorque() );
  3939. }
  3940. // Add frequency.
  3941. if ( mNotZero( pJoint->GetSpringFrequencyHz() ) )
  3942. pJointNode->addField( jointWheelFrequencyName, pJoint->GetSpringFrequencyHz() );
  3943. // Add damping ratio.
  3944. if ( mNotZero( pJoint->GetSpringDampingRatio() ) )
  3945. pJointNode->addField( jointWheelDampingRatioName, pJoint->GetSpringDampingRatio() );
  3946. // Add world axis.
  3947. pJointNode->addField( jointWheelWorldAxisName, pJoint->GetBodyA()->GetWorldVector( pJoint->GetLocalAxisA() ) );
  3948. // Add local anchors.
  3949. pJointNode->addField( jointLocalAnchorAName, pJoint->GetLocalAnchorA() );
  3950. pJointNode->addField( jointLocalAnchorBName, pJoint->GetLocalAnchorB() );
  3951. // Add scene object bodies.
  3952. if ( pSceneObjectA != NULL )
  3953. pJointNode->addNode( pSceneObjectA );
  3954. if ( pSceneObjectB != NULL )
  3955. pJointNode->addNode( pSceneObjectB );
  3956. }
  3957. break;
  3958. case e_frictionJoint:
  3959. {
  3960. // Set joint name.
  3961. pJointNode->setNodeName( jointFrictionNodeName );
  3962. // Fetch joint.
  3963. const b2FrictionJoint* pJoint = dynamic_cast<const b2FrictionJoint*>( pBaseJoint );
  3964. // Add max force.
  3965. if ( mNotZero( pJoint->GetMaxForce() ) )
  3966. pJointNode->addField( jointFrictionMaxForceName, pJoint->GetMaxForce() );
  3967. // Add max torque.
  3968. if ( mNotZero( pJoint->GetMaxTorque() ) )
  3969. pJointNode->addField( jointFrictionMaxTorqueName, pJoint->GetMaxTorque() );
  3970. // Sanity!
  3971. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid friction joint type returned." );
  3972. // Add local anchors.
  3973. if ( mNotZero( pJoint->GetLocalAnchorA().LengthSquared() ) )
  3974. pJointNode->addField( jointLocalAnchorAName, pJoint->GetLocalAnchorA() );
  3975. if ( mNotZero( pJoint->GetLocalAnchorB().LengthSquared() ) )
  3976. pJointNode->addField( jointLocalAnchorBName, pJoint->GetLocalAnchorB() );
  3977. // Add scene object bodies.
  3978. if ( pSceneObjectA != NULL )
  3979. pJointNode->addNode( pSceneObjectA );
  3980. if ( pSceneObjectB != NULL )
  3981. pJointNode->addNode( pSceneObjectB );
  3982. }
  3983. break;
  3984. case e_prismaticJoint:
  3985. {
  3986. // Set joint name.
  3987. pJointNode->setNodeName( jointPrismaticNodeName );
  3988. // Fetch joint.
  3989. b2PrismaticJoint* pJoint = dynamic_cast<b2PrismaticJoint*>( pBaseJoint );
  3990. // Sanity!
  3991. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid prismatic joint type returned." );
  3992. // Add limit.
  3993. if ( pJoint->IsLimitEnabled() )
  3994. {
  3995. // Add limits.
  3996. pJointNode->addField( jointPrismaticLimitLowerTransName, pJoint->GetLowerLimit() );
  3997. pJointNode->addField( jointPrismaticLimitUpperTransName, pJoint->GetUpperLimit() );
  3998. }
  3999. // Add motor.
  4000. if ( pJoint->IsMotorEnabled() )
  4001. {
  4002. // Add motor.
  4003. pJointNode->addField( jointPrismaticMotorSpeedName, mRadToDeg(pJoint->GetMotorSpeed()) );
  4004. pJointNode->addField( jointPrismaticMotorMaxForceName, pJoint->GetMaxMotorForce() );
  4005. }
  4006. // Add world axis.
  4007. pJointNode->addField( jointPrismaticWorldAxisName, pJoint->GetBodyA()->GetWorldVector( pJoint->GetLocalAxisA() ) );
  4008. // Add local anchors.
  4009. pJointNode->addField( jointLocalAnchorAName, pJoint->GetLocalAnchorA() );
  4010. pJointNode->addField( jointLocalAnchorBName, pJoint->GetLocalAnchorB() );
  4011. // Add scene object bodies.
  4012. if ( pSceneObjectA != NULL )
  4013. pJointNode->addNode( pSceneObjectA );
  4014. if ( pSceneObjectB != NULL )
  4015. pJointNode->addNode( pSceneObjectB );
  4016. }
  4017. break;
  4018. case e_pulleyJoint:
  4019. {
  4020. // Set joint name.
  4021. pJointNode->setNodeName( jointPulleyNodeName );
  4022. // Fetch joint.
  4023. b2PulleyJoint* pJoint = dynamic_cast<b2PulleyJoint*>( pBaseJoint );
  4024. // Sanity!
  4025. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid pulley joint type returned." );
  4026. // Add lengths.
  4027. pJointNode->addField( jointPulleyLengthAName, pJoint->GetLengthA() );
  4028. pJointNode->addField( jointPulleyLengthBName, pJoint->GetLengthB() );
  4029. // Add ratio,
  4030. pJointNode->addField( jointPulleyRatioName, pJoint->GetRatio() );
  4031. // Add ground anchors.
  4032. pJointNode->addField( jointPulleyGroundAnchorAName, pJoint->GetGroundAnchorA() );
  4033. pJointNode->addField( jointPulleyGroundAnchorBName, pJoint->GetGroundAnchorB() );
  4034. // Add local anchors.
  4035. pJointNode->addField( jointLocalAnchorAName, pJoint->GetBodyA()->GetLocalPoint( pJoint->GetAnchorA() ) );
  4036. pJointNode->addField( jointLocalAnchorBName, pJoint->GetBodyB()->GetLocalPoint( pJoint->GetAnchorB() ) );
  4037. // Add scene object bodies.
  4038. if ( pSceneObjectA != NULL )
  4039. pJointNode->addNode( pSceneObjectA );
  4040. if ( pSceneObjectB != NULL )
  4041. pJointNode->addNode( pSceneObjectB );
  4042. }
  4043. break;
  4044. case e_mouseJoint:
  4045. {
  4046. // Set joint name.
  4047. pJointNode->setNodeName( jointTargetNodeName );
  4048. // Fetch joint.
  4049. const b2MouseJoint* pJoint = dynamic_cast<const b2MouseJoint*>( pBaseJoint );
  4050. // Sanity!
  4051. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid target joint type returned." );
  4052. // Add target.
  4053. pJointNode->addField( jointTargetWorldTargetName, pJoint->GetTarget() );
  4054. // Add max force.
  4055. pJointNode->addField( jointTargetMaxForceName, pJoint->GetMaxForce() );
  4056. // Add frequency
  4057. pJointNode->addField( jointTargetFrequencyName, pJoint->GetFrequency() );
  4058. // Add damping ratio.
  4059. pJointNode->addField( jointTargetDampingRatioName, pJoint->GetDampingRatio() );
  4060. // Add body.
  4061. // NOTE: This joint uses BODYB as the object, BODYA is the ground-body however for easy of use
  4062. // we'll refer to this as OBJECTA in the persisted format.
  4063. if ( pSceneObjectB != NULL )
  4064. pJointNode->addNode( pSceneObjectB );
  4065. }
  4066. break;
  4067. case e_motorJoint:
  4068. {
  4069. // Set joint name.
  4070. pJointNode->setNodeName( jointMotorNodeName );
  4071. // Fetch joint.
  4072. const b2MotorJoint* pJoint = dynamic_cast<const b2MotorJoint*>( pBaseJoint );
  4073. // Sanity!
  4074. AssertFatal( pJoint != NULL, "Scene::onTamlCustomWrite() - Invalid motor joint type returned." );
  4075. // Add linear offset.
  4076. if ( mNotZero( pJoint->GetLinearOffset().LengthSquared() ) )
  4077. pJointNode->addField( jointMotorLinearOffsetName, pJoint->GetLinearOffset() );
  4078. // Add angular offset.
  4079. if ( mNotZero( pJoint->GetAngularOffset() ) )
  4080. pJointNode->addField( jointMotorAngularOffsetName, mRadToDeg( pJoint->GetAngularOffset() ) );
  4081. // Add max force.
  4082. pJointNode->addField( jointMotorMaxForceName, pJoint->GetMaxForce() );
  4083. // Add max torque.
  4084. pJointNode->addField( jointMotorMaxTorqueName, pJoint->GetMaxTorque() );
  4085. // Add correction factor.
  4086. pJointNode->addField( jointMotorCorrectionFactorName, pJoint->GetCorrectionFactor() );
  4087. // Add scene object bodies.
  4088. if ( pSceneObjectA != NULL )
  4089. pJointNode->addNode( pSceneObjectA );
  4090. if ( pSceneObjectB != NULL )
  4091. pJointNode->addNode( pSceneObjectB );
  4092. }
  4093. break;
  4094. default:
  4095. // Sanity!
  4096. AssertFatal( false, "Scene::onTamlCustomWrite() - Unknown joint type detected." );
  4097. }
  4098. // Add collide connected flag.
  4099. if ( pBaseJoint->GetCollideConnected() )
  4100. pJointNode->addField( jointCollideConnectedName, pBaseJoint->GetCollideConnected() );
  4101. }
  4102. }
  4103. // Fetch controller count.
  4104. const S32 sceneControllerCount = getControllers() ? getControllers()->size() : 0;
  4105. // Do we have any scene controllers?
  4106. if ( sceneControllerCount > 0 )
  4107. {
  4108. // Yes, so add controller node.
  4109. TamlCustomNode* pControllerCustomNode = customNodes.addNode( controllerCustomNodeName );
  4110. // Fetch the scene controllers.
  4111. SimSet* pControllerSet = getControllers();
  4112. // Iterate scene controllers.
  4113. for( S32 i = 0; i < sceneControllerCount; i++ )
  4114. {
  4115. // Fetch the set object.
  4116. SimObject* pSetObject = pControllerSet->at(i);
  4117. // Skip if not a controller.
  4118. if ( !pSetObject->isType<SceneController*>() )
  4119. continue;
  4120. // Add controller node.
  4121. pControllerCustomNode->addNode( pSetObject );
  4122. }
  4123. }
  4124. // Fetch asset preload count.
  4125. const S32 assetPreloadCount = getAssetPreloadCount();
  4126. // Do we have any asset preloads?
  4127. if ( assetPreloadCount > 0 )
  4128. {
  4129. // Yes, so fetch asset Id type prefix.
  4130. StringTableEntry assetIdTypePrefix = ConsoleBaseType::getType( TypeAssetId )->getTypePrefix();
  4131. // Add asset preload node.
  4132. TamlCustomNode* pAssetPreloadCustomNode = customNodes.addNode( assetPreloadNodeName );
  4133. // Iterate asset preloads.
  4134. for( typeAssetPtrVector::const_iterator assetItr = mAssetPreloads.begin(); assetItr != mAssetPreloads.end(); ++assetItr )
  4135. {
  4136. // Add node.
  4137. TamlCustomNode* pAssetNode = pAssetPreloadCustomNode->addNode( assetNodeName );
  4138. char valueBuffer[1024];
  4139. dSprintf( valueBuffer, sizeof(valueBuffer), "%s%s", assetIdTypePrefix, (*assetItr)->getAssetId() );
  4140. // Add asset Id.
  4141. pAssetNode->addField( "Id", valueBuffer );
  4142. }
  4143. }
  4144. }
  4145. //-----------------------------------------------------------------------------
  4146. void Scene::onTamlCustomRead( const TamlCustomNodes& customNodes )
  4147. {
  4148. // Call parent.
  4149. Parent::onTamlCustomRead( customNodes );
  4150. }
  4151. //-----------------------------------------------------------------------------
  4152. U32 Scene::getGlobalSceneCount( void )
  4153. {
  4154. return sSceneCount;
  4155. }
  4156. //-----------------------------------------------------------------------------
  4157. SceneRenderRequest* Scene::createDefaultRenderRequest( SceneRenderQueue* pSceneRenderQueue, SceneObject* pSceneObject )
  4158. {
  4159. // Create a render request and populate it with the default details.
  4160. SceneRenderRequest* pSceneRenderRequest = pSceneRenderQueue->createRenderRequest()->set(
  4161. pSceneObject,
  4162. pSceneObject->getRenderPosition(),
  4163. pSceneObject->getSceneLayerDepth(),
  4164. pSceneObject->getSortPoint(),
  4165. pSceneObject->getSerialId(),
  4166. pSceneObject->getRenderGroup() );
  4167. // Prepare the blending for it.
  4168. pSceneRenderRequest->mBlendMode = pSceneObject->getBlendMode();
  4169. pSceneRenderRequest->mBlendColor = pSceneObject->getBlendColor();
  4170. pSceneRenderRequest->mSrcBlendFactor = pSceneObject->getSrcBlendFactor();
  4171. pSceneRenderRequest->mDstBlendFactor = pSceneObject->getDstBlendFactor();
  4172. pSceneRenderRequest->mAlphaTest = pSceneObject->getAlphaTest();
  4173. return pSceneRenderRequest;
  4174. }
  4175. //-----------------------------------------------------------------------------
  4176. SimObject* Scene::getTamlChild( const U32 childIndex ) const
  4177. {
  4178. // Sanity!
  4179. AssertFatal( childIndex < (U32)mSceneObjects.size(), "Scene::getTamlChild() - Child index is out of range." );
  4180. // For when the assert is not used.
  4181. if ( childIndex >= (U32)mSceneObjects.size() )
  4182. return NULL;
  4183. return mSceneObjects[ childIndex ];
  4184. }
  4185. //-----------------------------------------------------------------------------
  4186. void Scene::addTamlChild( SimObject* pSimObject )
  4187. {
  4188. // Sanity!
  4189. AssertFatal( pSimObject != NULL, "Scene::addTamlChild() - Cannot add a NULL child object." );
  4190. // Fetch as a scene object.
  4191. SceneObject* pSceneObject = dynamic_cast<SceneObject*>( pSimObject );
  4192. // Is it a scene object?
  4193. if ( pSceneObject == NULL )
  4194. {
  4195. // No, so warn.
  4196. Con::warnf( "Scene::addTamlChild() - Cannot add a child object that isn't a scene object." );
  4197. return;
  4198. }
  4199. // Add the scene object.
  4200. addToScene( pSceneObject );
  4201. }
  4202. //-----------------------------------------------------------------------------
  4203. static EnumTable::Enums DebugOptionsLookup[] =
  4204. {
  4205. { Scene::SCENE_DEBUG_METRICS, "metrics" },
  4206. { Scene::SCENE_DEBUG_FPS_METRICS, "fps" },
  4207. { Scene::SCENE_DEBUG_CONTROLLERS, "controllers" },
  4208. { Scene::SCENE_DEBUG_JOINTS, "joints" },
  4209. { Scene::SCENE_DEBUG_WIREFRAME_RENDER, "wireframe" },
  4210. { Scene::SCENE_DEBUG_AUDIO_SOURCES, "audio"},
  4211. ///
  4212. { Scene::SCENE_DEBUG_AABB, "aabb" },
  4213. { Scene::SCENE_DEBUG_OOBB, "oobb" },
  4214. { Scene::SCENE_DEBUG_SLEEP, "sleep" },
  4215. { Scene::SCENE_DEBUG_COLLISION_SHAPES, "collision" },
  4216. { Scene::SCENE_DEBUG_POSITION_AND_COM, "position" },
  4217. { Scene::SCENE_DEBUG_SORT_POINTS, "sort" },
  4218. };
  4219. //-----------------------------------------------------------------------------
  4220. Scene::DebugOption Scene::getDebugOptionEnum(const char* label)
  4221. {
  4222. // Search for Mnemonic.
  4223. for(U32 i = 0; i < (sizeof(DebugOptionsLookup) / sizeof(EnumTable::Enums)); i++)
  4224. if( dStricmp(DebugOptionsLookup[i].label, label) == 0)
  4225. return((Scene::DebugOption)DebugOptionsLookup[i].index);
  4226. // Warn.
  4227. Con::warnf( "Scene::getDebugOptionEnum() - Invalid debug option '%s'.", label );
  4228. return Scene::SCENE_DEBUG_INVALID;
  4229. }
  4230. //-----------------------------------------------------------------------------
  4231. const char* Scene::getDebugOptionDescription( Scene::DebugOption debugOption )
  4232. {
  4233. // Search for Mnemonic.
  4234. for (U32 i = 0; i < (sizeof(DebugOptionsLookup) / sizeof(EnumTable::Enums)); i++)
  4235. {
  4236. if( DebugOptionsLookup[i].index == debugOption )
  4237. return DebugOptionsLookup[i].label;
  4238. }
  4239. // Warn.
  4240. Con::warnf( "Scene::getDebugOptionDescription() - Invalid debug option." );
  4241. return StringTable->EmptyString;
  4242. }
  4243. //-----------------------------------------------------------------------------
  4244. static EnumTable::Enums jointTypeLookup[] =
  4245. {
  4246. { e_distanceJoint, "distance" },
  4247. { e_ropeJoint, "rope" },
  4248. { e_revoluteJoint, "revolute" },
  4249. { e_weldJoint, "weld" },
  4250. { e_wheelJoint, "wheel" },
  4251. { e_frictionJoint, "friction" },
  4252. { e_prismaticJoint, "prismatic" },
  4253. { e_pulleyJoint, "pulley" },
  4254. { e_mouseJoint, "target" },
  4255. { e_motorJoint, "motor" },
  4256. };
  4257. EnumTable jointTypeTable(sizeof(jointTypeLookup) / sizeof(EnumTable::Enums), &jointTypeLookup[0]);
  4258. //-----------------------------------------------------------------------------
  4259. const char* Scene::getJointTypeDescription( b2JointType jointType )
  4260. {
  4261. // Search for Mnemonic.
  4262. for (U32 i = 0; i < (sizeof(jointTypeLookup) / sizeof(EnumTable::Enums)); i++)
  4263. {
  4264. if( jointTypeLookup[i].index == jointType )
  4265. return jointTypeLookup[i].label;
  4266. }
  4267. // Warn.
  4268. Con::warnf( "Scene::getJointTypeDescription() - Invalid joint type." );
  4269. return StringTable->EmptyString;
  4270. }
  4271. //-----------------------------------------------------------------------------
  4272. b2JointType Scene::getJointTypeEnum(const char* label)
  4273. {
  4274. // Search for Mnemonic.
  4275. for (U32 i = 0; i < (sizeof(jointTypeLookup) / sizeof(EnumTable::Enums)); i++)
  4276. {
  4277. if( dStricmp(jointTypeLookup[i].label, label) == 0)
  4278. return (b2JointType)jointTypeLookup[i].index;
  4279. }
  4280. // Warn.
  4281. Con::warnf( "Scene::getJointTypeEnum() - Invalid joint of '%s'", label );
  4282. return e_unknownJoint;
  4283. }
  4284. //-----------------------------------------------------------------------------
  4285. static EnumTable::Enums pickModeLookup[] =
  4286. {
  4287. { Scene::PICK_ANY, "Any" },
  4288. { Scene::PICK_AABB, "AABB" },
  4289. { Scene::PICK_OOBB, "OOBB" },
  4290. { Scene::PICK_COLLISION, "Collision" },
  4291. };
  4292. //-----------------------------------------------------------------------------
  4293. Scene::PickMode Scene::getPickModeEnum(const char* label)
  4294. {
  4295. // Search for Mnemonic.
  4296. for(U32 i = 0; i < (sizeof(pickModeLookup) / sizeof(EnumTable::Enums)); i++)
  4297. if( dStricmp(pickModeLookup[i].label, label) == 0)
  4298. return((Scene::PickMode)pickModeLookup[i].index);
  4299. // Warn.
  4300. Con::warnf( "Scene::getPickModeEnum() - Invalid pick mode '%s'.", label );
  4301. return Scene::PICK_INVALID;
  4302. }
  4303. //-----------------------------------------------------------------------------
  4304. const char* Scene::getPickModeDescription( Scene::PickMode pickMode )
  4305. {
  4306. // Search for Mnemonic.
  4307. for (U32 i = 0; i < (sizeof(pickModeLookup) / sizeof(EnumTable::Enums)); i++)
  4308. {
  4309. if( pickModeLookup[i].index == pickMode )
  4310. return pickModeLookup[i].label;
  4311. }
  4312. // Warn.
  4313. Con::warnf( "Scene::getPickModeDescription() - Invalid pick mode.");
  4314. return StringTable->EmptyString;
  4315. }
  4316. //-----------------------------------------------------------------------------
  4317. static void WriteJointsCustomTamlScehema( const AbstractClassRep* pClassRep, TiXmlElement* pParentElement )
  4318. {
  4319. // Sanity!
  4320. AssertFatal( pClassRep != NULL, "Taml::WriteJointsCustomTamlScehema() - ClassRep cannot be NULL." );
  4321. AssertFatal( pParentElement != NULL, "Taml::WriteJointsCustomTamlScehema() - Parent Element cannot be NULL." );
  4322. char buffer[1024];
  4323. // Create joints node element.
  4324. TiXmlElement* pJointsNodeElement = new TiXmlElement( "xs:element" );
  4325. dSprintf( buffer, sizeof(buffer), "%s.%s", pClassRep->getClassName(), jointCustomNodeName );
  4326. pJointsNodeElement->SetAttribute( "name", buffer );
  4327. pJointsNodeElement->SetAttribute( "minOccurs", 0 );
  4328. pJointsNodeElement->SetAttribute( "maxOccurs", 1 );
  4329. pParentElement->LinkEndChild( pJointsNodeElement );
  4330. // Create complex type.
  4331. TiXmlElement* pJointsNodeComplexTypeElement = new TiXmlElement( "xs:complexType" );
  4332. pJointsNodeElement->LinkEndChild( pJointsNodeComplexTypeElement );
  4333. // Create choice element.
  4334. TiXmlElement* pJointsNodeChoiceElement = new TiXmlElement( "xs:choice" );
  4335. pJointsNodeChoiceElement->SetAttribute( "minOccurs", 0 );
  4336. pJointsNodeChoiceElement->SetAttribute( "maxOccurs", "unbounded" );
  4337. pJointsNodeComplexTypeElement->LinkEndChild( pJointsNodeChoiceElement );
  4338. // ********************************************************************************
  4339. // Create Distance Joint Element.
  4340. // ********************************************************************************
  4341. TiXmlElement* pDistanceJointElement = new TiXmlElement( "xs:element" );
  4342. pDistanceJointElement->SetAttribute( "name", jointDistanceNodeName );
  4343. pDistanceJointElement->SetAttribute( "minOccurs", 0 );
  4344. pDistanceJointElement->SetAttribute( "maxOccurs", 1 );
  4345. pJointsNodeChoiceElement->LinkEndChild( pDistanceJointElement );
  4346. // Create complex type Element.
  4347. TiXmlElement* pDistanceJointComplexTypeElement = new TiXmlElement( "xs:complexType" );
  4348. pDistanceJointElement->LinkEndChild( pDistanceJointComplexTypeElement );
  4349. // Create "Length" attribute.
  4350. TiXmlElement* pDistanceJointElementA = new TiXmlElement( "xs:attribute" );
  4351. pDistanceJointElementA->SetAttribute( "name", jointDistanceLengthName );
  4352. pDistanceJointComplexTypeElement->LinkEndChild( pDistanceJointElementA );
  4353. TiXmlElement* pDistanceJointElementB = new TiXmlElement( "xs:simpleType" );
  4354. pDistanceJointElementA->LinkEndChild( pDistanceJointElementB );
  4355. TiXmlElement* pDistanceJointElementC = new TiXmlElement( "xs:restriction" );
  4356. pDistanceJointElementC->SetAttribute( "base", "xs:float" );
  4357. pDistanceJointElementB->LinkEndChild( pDistanceJointElementC );
  4358. TiXmlElement* pDistanceJointElementD = new TiXmlElement( "xs:minInclusive" );
  4359. pDistanceJointElementD->SetAttribute( "value", "0" );
  4360. pDistanceJointElementC->LinkEndChild( pDistanceJointElementD );
  4361. // Create "Frequency" attribute.
  4362. pDistanceJointElementA = new TiXmlElement( "xs:attribute" );
  4363. pDistanceJointElementA->SetAttribute( "name", jointDistanceFrequencyName );
  4364. pDistanceJointComplexTypeElement->LinkEndChild( pDistanceJointElementA );
  4365. pDistanceJointElementB = new TiXmlElement( "xs:simpleType" );
  4366. pDistanceJointElementA->LinkEndChild( pDistanceJointElementB );
  4367. pDistanceJointElementC = new TiXmlElement( "xs:restriction" );
  4368. pDistanceJointElementC->SetAttribute( "base", "xs:float" );
  4369. pDistanceJointElementB->LinkEndChild( pDistanceJointElementC );
  4370. pDistanceJointElementD = new TiXmlElement( "xs:minInclusive" );
  4371. pDistanceJointElementD->SetAttribute( "value", "0" );
  4372. pDistanceJointElementC->LinkEndChild( pDistanceJointElementD );
  4373. // Create "Damping Ratio" attribute.
  4374. pDistanceJointElementA = new TiXmlElement( "xs:attribute" );
  4375. pDistanceJointElementA->SetAttribute( "name", jointDistanceDampingRatioName );
  4376. pDistanceJointComplexTypeElement->LinkEndChild( pDistanceJointElementA );
  4377. pDistanceJointElementB = new TiXmlElement( "xs:simpleType" );
  4378. pDistanceJointElementA->LinkEndChild( pDistanceJointElementB );
  4379. pDistanceJointElementC = new TiXmlElement( "xs:restriction" );
  4380. pDistanceJointElementC->SetAttribute( "base", "xs:float" );
  4381. pDistanceJointElementB->LinkEndChild( pDistanceJointElementC );
  4382. pDistanceJointElementD = new TiXmlElement( "xs:minInclusive" );
  4383. pDistanceJointElementD->SetAttribute( "value", "0" );
  4384. pDistanceJointElementC->LinkEndChild( pDistanceJointElementD );
  4385. }
  4386. //-----------------------------------------------------------------------------
  4387. static void WriteControllersCustomTamlScehema( const AbstractClassRep* pClassRep, TiXmlElement* pParentElement )
  4388. {
  4389. // Sanity!
  4390. AssertFatal( pClassRep != NULL, "Taml::WriteControllersCustomTamlScehema() - ClassRep cannot be NULL." );
  4391. AssertFatal( pParentElement != NULL, "Taml::WriteControllersCustomTamlScehema() - Parent Element cannot be NULL." );
  4392. char buffer[1024];
  4393. // Create controllers node element.
  4394. TiXmlElement* pControllersNodeElement = new TiXmlElement( "xs:element" );
  4395. dSprintf( buffer, sizeof(buffer), "%s.%s", pClassRep->getClassName(), controllerCustomNodeName );
  4396. pControllersNodeElement->SetAttribute( "name", buffer );
  4397. pControllersNodeElement->SetAttribute( "minOccurs", 0 );
  4398. pControllersNodeElement->SetAttribute( "maxOccurs", 1 );
  4399. pParentElement->LinkEndChild( pControllersNodeElement );
  4400. // Create complex type.
  4401. TiXmlElement* pControllersNodeComplexTypeElement = new TiXmlElement( "xs:complexType" );
  4402. pControllersNodeElement->LinkEndChild( pControllersNodeComplexTypeElement );
  4403. // Create choice element.
  4404. TiXmlElement* pControllersNodeChoiceElement = new TiXmlElement( "xs:choice" );
  4405. pControllersNodeChoiceElement->SetAttribute( "minOccurs", 0 );
  4406. pControllersNodeChoiceElement->SetAttribute( "maxOccurs", "unbounded" );
  4407. pControllersNodeComplexTypeElement->LinkEndChild( pControllersNodeChoiceElement );
  4408. // Fetch the scene controller type.
  4409. AbstractClassRep* pPickingSceneControllerType = AbstractClassRep::findClassRep( "PickingSceneController" );
  4410. AbstractClassRep* pGroupedSceneControllerType = AbstractClassRep::findClassRep( "GroupedSceneController" );
  4411. // Sanity!
  4412. AssertFatal( pPickingSceneControllerType != NULL, "Scene::WriteControllersCustomTamlScehema() - Cannot find the PickingSceneController type." );
  4413. AssertFatal( pGroupedSceneControllerType != NULL, "Scene::WriteControllersCustomTamlScehema() - Cannot find the GroupedSceneController type." );
  4414. // Add choice members.
  4415. for ( AbstractClassRep* pChoiceType = AbstractClassRep::getClassList(); pChoiceType != NULL; pChoiceType = pChoiceType->getNextClass() )
  4416. {
  4417. // Skip if not derived from either of the scene controllers.
  4418. if ( !pChoiceType->isClass( pPickingSceneControllerType ) && !pChoiceType->isClass( pGroupedSceneControllerType ) )
  4419. continue;
  4420. // Add choice member.
  4421. TiXmlElement* pChoiceMemberElement = new TiXmlElement( "xs:element" );
  4422. pChoiceMemberElement->SetAttribute( "name", pChoiceType->getClassName() );
  4423. dSprintf( buffer, sizeof(buffer), "%s_Type", pChoiceType->getClassName() );
  4424. pChoiceMemberElement->SetAttribute( "type", buffer );
  4425. pControllersNodeChoiceElement->LinkEndChild( pChoiceMemberElement );
  4426. }
  4427. }
  4428. //-----------------------------------------------------------------------------
  4429. static void WritePreloadsCustomTamlScehema( const AbstractClassRep* pClassRep, TiXmlElement* pParentElement )
  4430. {
  4431. // Sanity!
  4432. AssertFatal( pClassRep != NULL, "Taml::WritePreloadsCustomTamlScehema() - ClassRep cannot be NULL." );
  4433. AssertFatal( pParentElement != NULL, "Taml::WritePreloadsCustomTamlScehema() - Parent Element cannot be NULL." );
  4434. char buffer[1024];
  4435. // Create preloads node element.
  4436. TiXmlElement* pPreloadsNodeElement = new TiXmlElement( "xs:element" );
  4437. dSprintf( buffer, sizeof(buffer), "%s.%s", pClassRep->getClassName(), assetPreloadNodeName );
  4438. pPreloadsNodeElement->SetAttribute( "name", buffer );
  4439. pPreloadsNodeElement->SetAttribute( "minOccurs", 0 );
  4440. pPreloadsNodeElement->SetAttribute( "maxOccurs", 1 );
  4441. pParentElement->LinkEndChild( pPreloadsNodeElement );
  4442. // Create complex type.
  4443. TiXmlElement* pPreloadsNodeComplexTypeElement = new TiXmlElement( "xs:complexType" );
  4444. pPreloadsNodeElement->LinkEndChild( pPreloadsNodeComplexTypeElement );
  4445. // Create choice element.
  4446. TiXmlElement* pPreloadsNodeChoiceElement = new TiXmlElement( "xs:choice" );
  4447. pPreloadsNodeChoiceElement->SetAttribute( "minOccurs", 0 );
  4448. pPreloadsNodeChoiceElement->SetAttribute( "maxOccurs", "unbounded" );
  4449. pPreloadsNodeComplexTypeElement->LinkEndChild( pPreloadsNodeChoiceElement );
  4450. // Add choice member element.
  4451. TiXmlElement* pChoiceMemberElement = new TiXmlElement( "xs:element" );
  4452. pChoiceMemberElement->SetAttribute( "name", assetNodeName );
  4453. pPreloadsNodeChoiceElement->LinkEndChild( pChoiceMemberElement );
  4454. // Add choice member complex type element.
  4455. TiXmlElement* pChoiceMemberComplexTypeElement = new TiXmlElement( "xs:complexType" );
  4456. pChoiceMemberElement->LinkEndChild( pChoiceMemberComplexTypeElement );
  4457. // Add choice member attribute element.
  4458. TiXmlElement* pChoiceAttributeElement = new TiXmlElement( "xs:attribute" );
  4459. pChoiceAttributeElement->SetAttribute( "name", "Id" );
  4460. dSprintf( buffer, sizeof(buffer), "%s", "AssetId_ConsoleType" );
  4461. pChoiceAttributeElement->SetAttribute( "type", buffer );
  4462. pChoiceMemberComplexTypeElement->LinkEndChild( pChoiceAttributeElement );
  4463. }
  4464. //-----------------------------------------------------------------------------
  4465. static void WriteCustomTamlSchema( const AbstractClassRep* pClassRep, TiXmlElement* pParentElement )
  4466. {
  4467. // Sanity!
  4468. AssertFatal( pClassRep != NULL, "Taml::WriteCustomTamlSchema() - ClassRep cannot be NULL." );
  4469. AssertFatal( pParentElement != NULL, "Taml::WriteCustomTamlSchema() - Parent Element cannot be NULL." );
  4470. WriteJointsCustomTamlScehema( pClassRep, pParentElement );
  4471. WriteControllersCustomTamlScehema( pClassRep, pParentElement );
  4472. WritePreloadsCustomTamlScehema( pClassRep, pParentElement );
  4473. }
  4474. //------------------------------------------------------------------------------
  4475. IMPLEMENT_CONOBJECT_CHILDREN_SCHEMA(Scene, WriteCustomTamlSchema);