SceneWindow.cc 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968
  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. #include "graphics/dgl.h"
  23. #include "gui/guiTypes.h"
  24. #include "gui/guiCanvas.h"
  25. #include "console/console.h"
  26. #include "console/consoleTypes.h"
  27. #include "math/mMathFn.h"
  28. #include "2d/sceneobject/SceneObject.h"
  29. #include "2d/core/Utility.h"
  30. #include "2d/gui/SceneWindow.h"
  31. #ifndef _ASSET_MANAGER_H_
  32. #include "assets/assetManager.h"
  33. #endif
  34. // Script bindings.
  35. #include "SceneWindow_ScriptBinding.h"
  36. // Debug Profiling.
  37. #include "debug/profiler.h"
  38. //-----------------------------------------------------------------------------
  39. IMPLEMENT_CONOBJECT(SceneWindow);
  40. //-----------------------------------------------------------------------------
  41. static EnumTable::Enums interpolationModeLookup[] =
  42. {
  43. { SceneWindow::LINEAR, "LINEAR" },
  44. { SceneWindow::SIGMOID, "SIGMOID" },
  45. };
  46. static EnumTable interpolationModeTable(sizeof(interpolationModeLookup) / sizeof(EnumTable::Enums), &interpolationModeLookup[0]);
  47. //-----------------------------------------------------------------------------
  48. SceneWindow::CameraInterpolationMode SceneWindow::getInterpolationModeEnum(const char* label)
  49. {
  50. // Search for Mnemonic.
  51. for(U32 i = 0; i < (sizeof(interpolationModeLookup) / sizeof(EnumTable::Enums)); i++)
  52. if( dStricmp(interpolationModeLookup[i].label, label) == 0)
  53. return((CameraInterpolationMode)interpolationModeLookup[i].index);
  54. // Warn.
  55. Con::warnf( "SceneWindow::getInterpolationModeEnum() - Invalid interpolation mode '%s'.", label );
  56. return SceneWindow::INVALID_INTERPOLATION_MODE;
  57. }
  58. //-----------------------------------------------------------------------------
  59. SceneWindow::SceneWindow() : mpScene(NULL),
  60. mLockMouse(false),
  61. mWindowDirty(true),
  62. mRenderLayerMask(MASK_ALL),
  63. mRenderGroupMask(MASK_ALL),
  64. mCameraInterpolationMode(SIGMOID),
  65. mMaxQueueItems(64),
  66. mCameraTransitionTime(2.0f),
  67. mMovingCamera(false),
  68. mpMountedTo(NULL),
  69. mCameraMounted(false),
  70. mCameraShaking(false),
  71. mCameraShakeOffset(0.0f,0.0f),
  72. mViewLimitActive(false),
  73. mUseWindowInputEvents(true),
  74. mUseObjectInputEvents(false),
  75. mInputEventGroupMaskFilter(MASK_ALL),
  76. mInputEventLayerMaskFilter(MASK_ALL),
  77. mInputEventInvisibleFilter( true )
  78. {
  79. // Set Vector Associations.
  80. VECTOR_SET_ASSOCIATION( mCameraQueue );
  81. VECTOR_SET_ASSOCIATION( mInputEventQuery );
  82. VECTOR_SET_ASSOCIATION( mInputEventEntering );
  83. VECTOR_SET_ASSOCIATION( mInputEventLeaving );
  84. // Touch input event names.
  85. mInputEventDownName = StringTable->insert("onTouchDown");
  86. mInputEventUpName = StringTable->insert("onTouchUp");
  87. mInputEventMovedName = StringTable->insert("onTouchMoved");
  88. mInputEventDraggedName = StringTable->insert("onTouchDragged");
  89. mInputEventEnterName = StringTable->insert("onTouchEnter");
  90. mInputEventLeaveName = StringTable->insert("onTouchLeave");
  91. // Mouse input event names.
  92. mMouseEventRightMouseDownName = StringTable->insert("onRightMouseDown");
  93. mMouseEventRightMouseUpName = StringTable->insert("onRightMouseUp");
  94. mMouseEventRightMouseDraggedName= StringTable->insert("onRightMouseDragged");
  95. mMouseEventWheelUpName = StringTable->insert("onMouseWheelUp");
  96. mMouseEventWheelDownName = StringTable->insert("onMouseWheelDown");
  97. mMouseEventEnterName = StringTable->insert("onMouseEnter");
  98. mMouseEventLeaveName = StringTable->insert("onMouseLeave");
  99. // Turn-on Tick Processing.
  100. setProcessTicks( true );
  101. }
  102. //-----------------------------------------------------------------------------
  103. SceneWindow::~SceneWindow()
  104. {
  105. }
  106. //-----------------------------------------------------------------------------
  107. bool SceneWindow::onAdd()
  108. {
  109. if(!Parent::onAdd())
  110. return false;
  111. // Reset the camera position.
  112. setCameraPosition( Vector2::getZero() );
  113. // Reset the camera size.
  114. setCameraSize( Vector2( 100.0f, 75.0f ) );
  115. // Reset the camera zoom.
  116. setCameraZoom( 1.0f );
  117. // Zero Camera Time.
  118. zeroCameraTime();
  119. // Return Okay.
  120. return true;
  121. }
  122. //-----------------------------------------------------------------------------
  123. void SceneWindow::onRemove()
  124. {
  125. // Reset Scene.
  126. resetScene();
  127. // Call Parent.
  128. Parent::onRemove();
  129. }
  130. //-----------------------------------------------------------------------------
  131. void SceneWindow::initPersistFields()
  132. {
  133. // Call Parent.
  134. Parent::initPersistFields();
  135. // Add Fields.
  136. addField( "lockMouse", TypeBool, Offset(mLockMouse, SceneWindow) );
  137. addField( "UseWindowInputEvents", TypeBool, Offset(mUseWindowInputEvents, SceneWindow) );
  138. addField( "UseObjectInputEvents", TypeBool, Offset(mUseObjectInputEvents, SceneWindow) );
  139. }
  140. //-----------------------------------------------------------------------------
  141. void SceneWindow::setScene( Scene* pScene )
  142. {
  143. // Detach (if needed)
  144. resetScene();
  145. // Attach the Window.
  146. pScene->attachSceneWindow( this );
  147. // Set scene.
  148. mpScene = pScene;
  149. }
  150. //-----------------------------------------------------------------------------
  151. void SceneWindow::resetScene( void )
  152. {
  153. // Detach from scene (if attached).
  154. if ( getScene() )
  155. {
  156. getScene()->detachSceneWindow( this );
  157. }
  158. // Are we mounted to an object?
  159. if ( isCameraMounted() )
  160. {
  161. // Yes, so dismount object.
  162. dismount();
  163. }
  164. // Clear input event watched objects.
  165. mInputEventWatching.clear();
  166. // Reset scene.
  167. mpScene = NULL;
  168. }
  169. //-----------------------------------------------------------------------------
  170. void SceneWindow::setCameraPosition( const Vector2& position )
  171. {
  172. // Are we mounted to an object?
  173. if ( isCameraMounted() )
  174. {
  175. // Yes, so cannot use this command.
  176. Con::warnf("SceneWindow::setCameraPosition() - Cannot use this command when camera is mounted!");
  177. return;
  178. }
  179. // Stop Camera Move ( if any ).
  180. if ( mMovingCamera ) stopCameraMove();
  181. // Fetch the camera size.
  182. const Vector2 cameraSize = getCameraSize();
  183. // Set Camera Target.
  184. mCameraCurrent.mSourceArea = RectF( position.x - (cameraSize.x * 0.5f), position.y - (cameraSize.y * 0.5f), cameraSize.x, cameraSize.y );
  185. // Set Camera Target to Current.
  186. mCameraTarget = mCameraCurrent;
  187. }
  188. //-----------------------------------------------------------------------------
  189. void SceneWindow::setCameraSize( const Vector2& size )
  190. {
  191. // Stop Camera Move ( if any ).
  192. if ( mMovingCamera ) stopCameraMove();
  193. // Fetch the current position.
  194. const Vector2 position = getCameraPosition();
  195. // Set Camera Target.
  196. mCameraCurrent.mSourceArea = RectF( position.x - (size.x * 0.5f), position.y - (size.y * 0.5f), size.x, size.y );
  197. // Set Camera Target to Current.
  198. mCameraTarget = mCameraCurrent;
  199. }
  200. //-----------------------------------------------------------------------------
  201. void SceneWindow::setCameraArea( const RectF& cameraWindow )
  202. {
  203. // Are we mounted to an object?
  204. if ( isCameraMounted() )
  205. {
  206. // Yes, so cannot use this command.
  207. Con::warnf("SceneWindow::setCameraArea - Cannot use this command when camera is mounted!");
  208. return;
  209. }
  210. // Stop Camera Move ( if any ).
  211. if ( mMovingCamera ) stopCameraMove();
  212. // Set Camera Target.
  213. mCameraCurrent.mSourceArea = cameraWindow;
  214. mCameraCurrent.mCameraZoom = 1.0f;
  215. mCameraCurrent.mCameraAngle = 0.0f;
  216. // Set Camera Target to Current.
  217. mCameraTarget = mCameraCurrent;
  218. }
  219. //-----------------------------------------------------------------------------
  220. void SceneWindow::setCameraZoom( const F32 zoomFactor )
  221. {
  222. // Stop Camera Move ( if any ).
  223. if ( mMovingCamera ) stopCameraMove();
  224. // Set Camera Target.
  225. mCameraCurrent.mCameraZoom = getMax( zoomFactor, 0.000001f );
  226. // Set Camera Target to Current.
  227. mCameraTarget = mCameraCurrent;
  228. }
  229. //-----------------------------------------------------------------------------
  230. void SceneWindow::setCameraAngle( const F32 cameraAngle )
  231. {
  232. // Stop Camera Move ( if any ).
  233. if ( mMovingCamera ) stopCameraMove();
  234. // Set Camera Target.
  235. mCameraCurrent.mCameraAngle = mFmod( cameraAngle, b2_pi2 );
  236. // Set Camera Target to Current.
  237. mCameraTarget = mCameraCurrent;
  238. }
  239. //-----------------------------------------------------------------------------
  240. void SceneWindow::setTargetCameraPosition( const Vector2& position )
  241. {
  242. // Are we mounted to an object?
  243. if ( isCameraMounted() )
  244. {
  245. // Yes, so cannot use this command.
  246. Con::warnf("SceneWindow::setTargetCameraPosition - Cannot use this command when camera is mounted!");
  247. return;
  248. }
  249. // Stop Camera Move ( if any ).
  250. if ( mMovingCamera ) stopCameraMove();
  251. // Fetch the camera size.
  252. const Vector2 cameraSize = getTargetCameraSize();
  253. // Set Camera Target.
  254. mCameraTarget.mSourceArea = RectF( position.x - (cameraSize.x*0.5f), position.y - (cameraSize.y*0.5f), cameraSize.x, cameraSize.y );
  255. }
  256. //-----------------------------------------------------------------------------
  257. void SceneWindow::setTargetCameraSize( const Vector2& size )
  258. {
  259. // Stop Camera Move ( if any ).
  260. if ( mMovingCamera ) stopCameraMove();
  261. // Fetch the current position.
  262. const Vector2 position = getTargetCameraPosition();
  263. // Set Camera Target.
  264. mCameraTarget.mSourceArea = RectF( position.x - (size.x * 0.5f), position.y - (size.y * 0.5f), size.x, size.y );
  265. }
  266. //-----------------------------------------------------------------------------
  267. void SceneWindow::setTargetCameraArea( const RectF& cameraWindow )
  268. {
  269. // Are we mounted to an object?
  270. if ( isCameraMounted() )
  271. {
  272. // Yes, so cannot use this command.
  273. Con::warnf("SceneWindow::setTargetCameraArea - Cannot use this command when camera is mounted!");
  274. return;
  275. }
  276. // Stop Camera Move ( if any ).
  277. if ( mMovingCamera ) stopCameraMove();
  278. // Set Camera Target.
  279. mCameraTarget.mSourceArea = cameraWindow;
  280. }
  281. //-----------------------------------------------------------------------------
  282. void SceneWindow::setTargetCameraZoom( const F32 zoomFactor )
  283. {
  284. // Stop Camera Move ( if any ).
  285. if ( mMovingCamera ) stopCameraMove();
  286. // Set Camera Target.
  287. mCameraTarget.mCameraZoom = getMax( zoomFactor, 0.000001f );
  288. }
  289. //-----------------------------------------------------------------------------
  290. void SceneWindow::setTargetCameraAngle( const F32 cameraAngle )
  291. {
  292. // Stop Camera Move ( if any ).
  293. if ( mMovingCamera ) stopCameraMove();
  294. // Set Camera Target.
  295. mCameraTarget.mCameraAngle = mFmod( cameraAngle, b2_pi2 );
  296. }
  297. //-----------------------------------------------------------------------------
  298. void SceneWindow::setCameraInterpolationTime( const F32 interpolationTime )
  299. {
  300. // Set Interpolation Time.
  301. mCameraTransitionTime = interpolationTime;
  302. }
  303. //-----------------------------------------------------------------------------
  304. void SceneWindow::setCameraInterpolationMode( const CameraInterpolationMode interpolationMode )
  305. {
  306. // Set Interpolation Mode.
  307. mCameraInterpolationMode = interpolationMode;
  308. }
  309. //-----------------------------------------------------------------------------
  310. void SceneWindow::startCameraMove( const F32 interpolationTime )
  311. {
  312. // Are we mounted to an object and trying to move?
  313. if ( isCameraMounted() )
  314. {
  315. if ( ( mCameraCurrent.mSourceArea.point != mCameraTarget.mSourceArea.point ) ||
  316. ( mCameraCurrent.mSourceArea.extent != mCameraTarget.mSourceArea.extent ) )
  317. {
  318. // Yes, so cannot use this command.
  319. Con::warnf("SceneWindow::startCameraMove - Cannot use this command when camera is mounted!");
  320. return;
  321. }
  322. }
  323. // Stop move if we're at target already.
  324. if ( mCameraCurrent.mSourceArea.point == mCameraTarget.mSourceArea.point &&
  325. mCameraCurrent.mSourceArea.extent == mCameraTarget.mSourceArea.extent &&
  326. mIsEqual( mCameraCurrent.mCameraZoom, mCameraTarget.mCameraZoom ) &&
  327. mIsEqual( mCameraTarget.mCameraAngle, mCameraTarget.mCameraAngle ) )
  328. {
  329. // Reset Camera Move.
  330. mMovingCamera = false;
  331. // Return here.
  332. return;
  333. }
  334. else
  335. {
  336. // Stop Camera Move ( if any ).
  337. if ( mMovingCamera ) stopCameraMove();
  338. }
  339. // Set Camera Interpolation Time.
  340. setCameraInterpolationTime( interpolationTime );
  341. // Zero Camera Time.
  342. zeroCameraTime();
  343. // Set Source Camera.
  344. mCameraSource = mCameraCurrent;
  345. // Set Camera Move.
  346. mMovingCamera = true;
  347. // Complete camera move if interpolate time is zero.
  348. if ( mIsZero(mCameraTransitionTime) ) completeCameraMove();
  349. // Queue Current Camera.
  350. mCameraQueue.push_back( mCameraCurrent );
  351. // Clamp Queue Size.
  352. if ( mCameraQueue.size() > mMaxQueueItems ) mCameraQueue.pop_front();
  353. }
  354. //-----------------------------------------------------------------------------
  355. void SceneWindow::stopCameraMove( void )
  356. {
  357. // Quit if we're not moving.
  358. if ( !mMovingCamera ) return;
  359. // Reset Tick Camera Time.
  360. resetTickCameraTime();
  361. // Set target to Current.
  362. mCameraTarget = mCameraCurrent;
  363. // Reset Camera Move.
  364. mMovingCamera = false;
  365. }
  366. //-----------------------------------------------------------------------------
  367. void SceneWindow::completeCameraMove( void )
  368. {
  369. // Quit if we're not moving.
  370. if ( !mMovingCamera ) return;
  371. // Reset Tick Camera Time.
  372. resetTickCameraTime();
  373. // Move straight to target.
  374. mCameraCurrent = mCameraTarget;
  375. // Reset Camera Move.
  376. mMovingCamera = false;
  377. }
  378. //-----------------------------------------------------------------------------
  379. void SceneWindow::undoCameraMove( const F32 interpolationTime )
  380. {
  381. // Are we mounted to an object?
  382. if ( isCameraMounted() )
  383. {
  384. // Yes, so cannot use this command.
  385. Con::warnf("SceneWindow::undoCameraMove - Cannot use this command when camera is mounted!");
  386. return;
  387. }
  388. // Quit if we've got no queued targets.
  389. if ( mCameraQueue.size() == 0 ) return;
  390. // Stop Camera Move ( if any ).
  391. if ( mMovingCamera ) stopCameraMove();
  392. // Set Camera Interpolation Time.
  393. setCameraInterpolationTime( interpolationTime );
  394. // Zero Camera Time.
  395. zeroCameraTime();
  396. // Set Source Camera.
  397. mCameraSource = mCameraCurrent;
  398. // Set Camera Move.
  399. mMovingCamera = true;
  400. // Fetch Last Queued Camera Target.
  401. mCameraTarget = mCameraQueue.last();
  402. // Remove Last Target.
  403. mCameraQueue.pop_back();
  404. // Complete camera move if interpolate time is zero.
  405. if ( mIsZero(mCameraTransitionTime) ) completeCameraMove();
  406. }
  407. //-----------------------------------------------------------------------------
  408. void SceneWindow::updateCamera( void )
  409. {
  410. // Calculate Normalised Time.
  411. const F32 normCameraTime = mRenderCameraTime / mCameraTransitionTime;
  412. // Have we finished the interpolation?
  413. if ( mGreaterThanOrEqual(normCameraTime, 1.0f) )
  414. {
  415. // Yes, so complete camera move.
  416. completeCameraMove();
  417. // Finish here.
  418. return;
  419. }
  420. // Interpolate Camera Window/Zoom.
  421. mCameraCurrent.mSourceArea.point.x = interpolate( mCameraSource.mSourceArea.point.x, mCameraTarget.mSourceArea.point.x, normCameraTime );
  422. mCameraCurrent.mSourceArea.point.y = interpolate( mCameraSource.mSourceArea.point.y, mCameraTarget.mSourceArea.point.y, normCameraTime );
  423. mCameraCurrent.mSourceArea.extent.x = interpolate( mCameraSource.mSourceArea.extent.x, mCameraTarget.mSourceArea.extent.x, normCameraTime );
  424. mCameraCurrent.mSourceArea.extent.y = interpolate( mCameraSource.mSourceArea.extent.y, mCameraTarget.mSourceArea.extent.y, normCameraTime );
  425. mCameraCurrent.mCameraZoom = interpolate( mCameraSource.mCameraZoom, mCameraTarget.mCameraZoom, normCameraTime );
  426. mCameraCurrent.mCameraAngle = interpolate( mCameraSource.mCameraAngle, mCameraTarget.mCameraAngle, normCameraTime );
  427. }
  428. //-----------------------------------------------------------------------------
  429. F32 SceneWindow::interpolate( F32 from, F32 to, F32 delta )
  430. {
  431. // Linear.
  432. if ( mCameraInterpolationMode == LINEAR )
  433. return linearInterpolate( from, to, delta );
  434. // Sigmoid.
  435. else if ( mCameraInterpolationMode == SIGMOID )
  436. return sigmoidInterpolate( from, to, delta );
  437. // Hmmm...
  438. else
  439. return from;
  440. }
  441. //-----------------------------------------------------------------------------
  442. F32 SceneWindow::linearInterpolate( F32 from, F32 to, F32 delta )
  443. {
  444. // Clamp if we're over/under time.
  445. if ( delta <= 0.0f )
  446. return from;
  447. else if ( delta >= 1.0f )
  448. return to;
  449. // Calculate resultant interpolation.
  450. return ( from * ( 1.0f - delta ) ) + ( to * delta );
  451. }
  452. //-----------------------------------------------------------------------------
  453. F32 SceneWindow::sigmoidInterpolate( F32 from, F32 to, F32 delta )
  454. {
  455. // Range Expand/Clamp Delta to (-1 -> +1).
  456. delta = mClampF( (delta - 0.5f) * 2.0f, -1.0f, 1.0f );
  457. // Calculate interpolator value using sigmoid function.
  458. F32 sigmoid = mClampF ( 1.0f / (1.0f + mPow(2.718282f, -15.0f * delta)), 0.0f, 1.0f );
  459. // Calculate resultant interpolation.
  460. return ( from * ( 1.0f - sigmoid ) ) + ( to * sigmoid );
  461. }
  462. //-----------------------------------------------------------------------------
  463. void SceneWindow::startCameraShake( const F32 magnitude, const F32 time )
  464. {
  465. // Is the time zero?
  466. if ( mIsZero( time ) && mIsZero( magnitude ) )
  467. {
  468. // Yes, so simply stop the camera shaking.
  469. stopCameraShake();
  470. // Finish here.
  471. return;
  472. }
  473. // Set Current Shake.
  474. mCurrentShake = mFabs(magnitude);
  475. // Set Shake Life.
  476. mShakeLife = time;
  477. // Calculate Shake Ramp.
  478. mShakeRamp = mCurrentShake / mShakeLife;
  479. // Flag camera shaking.
  480. mCameraShaking = true;
  481. }
  482. //-----------------------------------------------------------------------------
  483. void SceneWindow::stopCameraShake( void )
  484. {
  485. // Flag camera not shaking.
  486. mCameraShaking = false;
  487. // Reset Shake Offset.
  488. mCameraShakeOffset.setZero();
  489. }
  490. //-----------------------------------------------------------------------------
  491. void SceneWindow::mount( SceneObject* pSceneObject, const Vector2& mountOffset, const F32 mountForce, const bool sendToMount, const bool mountAngle )
  492. {
  493. // Sanity!
  494. AssertFatal( pSceneObject != NULL, "Scene object cannot be NULL." );
  495. // Cannot mount if not in a scene.
  496. if ( !mpScene )
  497. {
  498. // Warn!
  499. Con::warnf("Cannot mount scene window (%d) to a scene object (%d) if scene window is not attached to a scene.", getId(), pSceneObject->getId() );
  500. return;
  501. }
  502. // Fetch objects' scene.
  503. const Scene* pScene = pSceneObject->getScene();
  504. // Scene object must be in a scene.
  505. if ( !pScene )
  506. {
  507. // Warn!
  508. Con::warnf("Cannot mount scene window (%d) to a scene object (%d) that is not in a scene.", getId(), pSceneObject->getId() );
  509. return;
  510. }
  511. // Scene object must be in same scene as the one the scene window is attached to.
  512. if ( pScene != mpScene )
  513. {
  514. // Warn!
  515. Con::warnf("Cannot mount scene window (%d) to a scene object (%d) that are not using the same scene.", getId(), pSceneObject->getId() );
  516. return;
  517. }
  518. // Are we mounted to an object?
  519. if ( isCameraMounted() )
  520. {
  521. // Yes, so dismount object.
  522. dismount();
  523. }
  524. else
  525. {
  526. // No, so stop any Camera Move.
  527. if ( mMovingCamera ) stopCameraMove();
  528. }
  529. // Set Mount Object Reference.
  530. mpMountedTo = pSceneObject;
  531. // Store Mount Offset.
  532. mMountOffset = mountOffset;
  533. // Set Mount Force.
  534. mMountForce = mountForce;
  535. // Set Mount Angle.
  536. mMountAngle = mountAngle;
  537. // Add Camera Mount Reference.
  538. pSceneObject->addCameraMountReference( this );
  539. // Flag Camera mounted.
  540. mCameraMounted = true;
  541. // Send directly to mount (if selected).
  542. if ( sendToMount )
  543. {
  544. // Fetch Mount Position.
  545. const Vector2& mountPos = mpMountedTo->getBody()->GetWorldPoint( mountOffset );
  546. // Calculate Window Half-Dimensions.
  547. const F32 halfWidth = mCameraCurrent.mSourceArea.len_x() * 0.5f;
  548. const F32 halfHeight = mCameraCurrent.mSourceArea.len_y() * 0.5f;
  549. // Set Current View to Object Position.
  550. mCameraCurrent.mSourceArea.point.set( mountPos.x - halfWidth, mountPos.y - halfHeight );
  551. }
  552. // Reset Tick Camera Position.
  553. resetTickCameraPosition();
  554. }
  555. //-----------------------------------------------------------------------------
  556. void SceneWindow::dismount( void )
  557. {
  558. // Nothing to do if we're not mounted!
  559. if (!isCameraMounted() )
  560. return;
  561. // Remove Camera Mount Reference.
  562. mpMountedTo->removeCameraMountReference();
  563. // Reset Camera Object Mount.
  564. mpMountedTo = NULL;
  565. // Flag Camera not mounted.
  566. mCameraMounted = false;
  567. // Reset Tick Camera Position.
  568. resetTickCameraPosition();
  569. }
  570. //-----------------------------------------------------------------------------
  571. void SceneWindow::setViewLimitOn( const Vector2& limitMin, const Vector2& limitMax )
  572. {
  573. // Activate View Limit.
  574. mViewLimitActive = true;
  575. // Set View Limit Min/Max.
  576. mViewLimitMin = limitMin;
  577. mViewLimitMax = limitMax;
  578. // Calculate Camera Area.
  579. mViewLimitArea = mViewLimitMax - mViewLimitMin;
  580. }
  581. //-----------------------------------------------------------------------------
  582. void SceneWindow::clampCameraViewLimit( void )
  583. {
  584. // Finish if the view-limit is not on or the camera is moving.
  585. if ( !mViewLimitActive || mMovingCamera )
  586. return;
  587. // Calculate Current Camera View.
  588. calculateCameraView( &mCameraCurrent );
  589. // Calculate the source and destination centres.
  590. const Point2F sourceCentre = mCameraCurrent.mSourceArea.centre();
  591. const Point2F destinationCentre = mCameraCurrent.mDestinationArea.centre();
  592. // Are the source and destination areas the same?
  593. if ( sourceCentre != destinationCentre )
  594. {
  595. // No, so adjust the source position to be at the same position as the destination i.e. don't change the source area.
  596. mCameraCurrent.mSourceArea.point += destinationCentre - sourceCentre;
  597. }
  598. }
  599. //-----------------------------------------------------------------------------
  600. void SceneWindow::setObjectInputEventFilter( const U32 groupMask, const U32 layerMask, const bool useInvisible )
  601. {
  602. // Set Object Mouse Event Filter.
  603. mInputEventGroupMaskFilter = groupMask;
  604. mInputEventLayerMaskFilter = layerMask;
  605. mInputEventInvisibleFilter = useInvisible;
  606. }
  607. //-----------------------------------------------------------------------------
  608. void SceneWindow::setObjectInputEventGroupFilter( const U32 groupMask )
  609. {
  610. mInputEventGroupMaskFilter = groupMask;
  611. // Clear existing watched input events.
  612. clearWatchedInputEvents();
  613. }
  614. //-----------------------------------------------------------------------------
  615. void SceneWindow::setObjectInputEventLayerFilter( const U32 layerMask )
  616. {
  617. mInputEventLayerMaskFilter = layerMask;
  618. // Clear existing watched input events.
  619. clearWatchedInputEvents();
  620. }
  621. //-----------------------------------------------------------------------------
  622. void SceneWindow::setObjectInputEventInvisibleFilter( const bool useInvisible )
  623. {
  624. mInputEventInvisibleFilter = useInvisible;
  625. // Clear existing watched input events.
  626. clearWatchedInputEvents();
  627. }
  628. //-----------------------------------------------------------------------------
  629. void SceneWindow::setMousePosition( const Vector2& mousePosition )
  630. {
  631. // Fetch Canvas.
  632. GuiCanvas* pCanvas = getRoot();
  633. // Canvas available?
  634. if ( pCanvas )
  635. {
  636. // Are we bound to a scene?
  637. if ( getScene() )
  638. {
  639. Vector2 windowMousePosition;
  640. // Yes, so convert window into scene coordinates...
  641. sceneToWindowPoint( mousePosition, windowMousePosition );
  642. // Copy into a compatible format for TGE.
  643. Point2I localWindowPosition( S32(windowMousePosition.x), S32(windowMousePosition.y) );
  644. // Set Cursor Position.
  645. pCanvas->setCursorPos( localToGlobalCoord(localWindowPosition) );
  646. }
  647. else
  648. {
  649. // No, so error.
  650. Con::warnf("SceneObject::setMousePosition() - No scene attached to window!");
  651. return;
  652. }
  653. }
  654. }
  655. //-----------------------------------------------------------------------------
  656. Vector2 SceneWindow::getMousePosition( void )
  657. {
  658. // Calculate Current Camera View.
  659. calculateCameraView( &mCameraCurrent );
  660. // Fetch Canvas.
  661. GuiCanvas* pCanvas = getRoot();
  662. // World Mouse Position.
  663. Vector2 worldMousePoint(0, 0);
  664. // Canvas available?
  665. if ( pCanvas )
  666. {
  667. // Yes, so fetch local GUI coordinates.
  668. const Vector2 localGuiPoint = globalToLocalCoord( pCanvas->getCursorPos() );
  669. // Are we bound to a scene?
  670. if ( getScene() )
  671. {
  672. // Yes, so convert window into scene coordinates...
  673. windowToScenePoint(localGuiPoint, worldMousePoint);
  674. }
  675. else
  676. {
  677. // No, so use window screen coordinates.
  678. worldMousePoint = localGuiPoint;
  679. }
  680. }
  681. #if 0
  682. else
  683. {
  684. // No, so warn
  685. Con::warnf("SceneWindow::getMousePosition() - Window not attached to canvas!" );
  686. }
  687. #endif
  688. // Return World Mouse Position.
  689. return worldMousePoint;
  690. }
  691. //-----------------------------------------------------------------------------
  692. void SceneWindow::windowToScenePoint( const Vector2& srcPoint, Vector2& dstPoint ) const
  693. {
  694. // Return Conversion.
  695. dstPoint.Set( (srcPoint.x * mCameraCurrent.mSceneWindowScale.x) + mCameraCurrent.mSceneMin.x, mCameraCurrent.mSceneMax.y - (srcPoint.y * mCameraCurrent.mSceneWindowScale.y) );
  696. }
  697. //-----------------------------------------------------------------------------
  698. void SceneWindow::sceneToWindowPoint( const Vector2& srcPoint, Vector2& dstPoint ) const
  699. {
  700. // Return Conversion.
  701. dstPoint.Set( (srcPoint.x - mCameraCurrent.mSceneMin.x) / mCameraCurrent.mSceneWindowScale.x, (mCameraCurrent.mSceneMax.y - srcPoint.y) / mCameraCurrent.mSceneWindowScale.y );
  702. }
  703. //-----------------------------------------------------------------------------
  704. void SceneWindow::dispatchInputEvent( StringTableEntry name, const GuiEvent& event )
  705. {
  706. // Debug Profiling.
  707. PROFILE_SCOPE(SceneWindow_DispatchInputEvent);
  708. // Dispatch input event to window if appropriate.
  709. if ( getUseWindowInputEvents() )
  710. sendWindowInputEvent( name, event );
  711. // Dispatch input event to scene objects if appropriate.
  712. if ( getUseObjectInputEvents() )
  713. sendObjectInputEvent( name, event );
  714. }
  715. //-----------------------------------------------------------------------------
  716. void SceneWindow::sendWindowInputEvent( StringTableEntry name, const GuiEvent& event )
  717. {
  718. // Debug Profiling.
  719. PROFILE_SCOPE(SceneWindow_SendWindowInputEvent);
  720. Vector2 worldMousePoint;
  721. // Calculate Current Camera View.
  722. calculateCameraView( &mCameraCurrent );
  723. // Convert to local gui coordinates.
  724. const Vector2 localGuiPoint = globalToLocalCoord(event.mousePoint);
  725. // Are we bound to a scene?
  726. if ( getScene() )
  727. {
  728. // Yes, so convert window into scene coordinates...
  729. windowToScenePoint(localGuiPoint, worldMousePoint);
  730. }
  731. else
  732. {
  733. // No, so use window screen coordinates.
  734. worldMousePoint = localGuiPoint;
  735. }
  736. // Argument Buffers.
  737. char argBuffer[3][64];
  738. // Format Event-Modifier Buffer.
  739. dSprintf(argBuffer[0], 64, "%d", event.eventID);
  740. // Format Mouse-Position Buffer.
  741. dSprintf(argBuffer[1], 64, "%g %g", worldMousePoint.x, worldMousePoint.y);
  742. // Format Mouse-Click Count Buffer.
  743. dSprintf(argBuffer[2], 64, "%d", event.mouseClickCount);
  744. // Call Scripts.
  745. Con::executef(this, 4, name, argBuffer[0], argBuffer[1], argBuffer[2]);
  746. }
  747. //-----------------------------------------------------------------------------
  748. void SceneWindow::sendObjectInputEvent( StringTableEntry name, const GuiEvent& event )
  749. {
  750. // Debug Profiling.
  751. PROFILE_SCOPE(SceneWindow_SendObjectInputEvent);
  752. // Finish if we're not bound to a scene?
  753. if ( !getScene() ) return;
  754. // Only process appropriate input events.
  755. if ( !( name == mInputEventDownName ||
  756. name == mInputEventUpName ||
  757. name == mInputEventMovedName ||
  758. name == mInputEventDraggedName ) )
  759. return;
  760. // Convert Event-Position into scene coordinates.
  761. Vector2 worldMousePoint;
  762. windowToScenePoint(Vector2(globalToLocalCoord(event.mousePoint)), worldMousePoint);
  763. // Fetch old pick count.
  764. const U32 oldPickCount = (U32)mInputEventWatching.size();
  765. // Fetch world query and clear results.
  766. WorldQuery* pWorldQuery = getScene()->getWorldQuery( true );
  767. // Set filter.
  768. WorldQueryFilter queryFilter( mInputEventLayerMaskFilter, mInputEventGroupMaskFilter, true, mInputEventInvisibleFilter, true, true );
  769. pWorldQuery->setQueryFilter( queryFilter );
  770. // Perform world query.
  771. const U32 newPickCount = pWorldQuery->anyQueryPoint( worldMousePoint );
  772. // Early-out if nothing to do.
  773. if ( newPickCount == 0 && oldPickCount == 0 )
  774. return;
  775. // Fetch results.
  776. mInputEventQuery = pWorldQuery->getQueryResults();
  777. pWorldQuery->clearQuery();
  778. // Determine "enter" events.
  779. for( U32 newIndex = 0; newIndex < newPickCount; ++newIndex )
  780. {
  781. // Fetch new scene object.
  782. SceneObject* pNewSceneObject = mInputEventQuery[newIndex].mpSceneObject;
  783. // Ignore object if it's not using input events.
  784. // NOTE:- We only check this for "enter" events in-case the option is
  785. // changed whilst it's currently picked. We want to guarantee
  786. // that any "enter" event is paired with a "leave" event.
  787. if ( !pNewSceneObject->getUseInputEvents() )
  788. continue;
  789. bool alreadyPresent = false;
  790. for ( U32 oldIndex = 0; oldIndex < oldPickCount; ++oldIndex )
  791. {
  792. // Skip if scene object is not present...
  793. if ( mInputEventWatching[oldIndex] != pNewSceneObject )
  794. continue;
  795. // Flag as already present.
  796. alreadyPresent = true;
  797. break;
  798. }
  799. // Add scene object as entering if not already present.
  800. if ( !alreadyPresent )
  801. mInputEventEntering.push_back( pNewSceneObject );
  802. }
  803. // Determine "leave" events.
  804. for ( U32 oldIndex = 0; oldIndex < oldPickCount; ++oldIndex )
  805. {
  806. // Fetch old scene object.
  807. SceneObject* pOldSceneObject = dynamic_cast<SceneObject*>( mInputEventWatching[oldIndex] );
  808. // Sanity!
  809. AssertFatal( pOldSceneObject != NULL, "Invalid object found in mouse-event pick vector." );
  810. bool stillPresent = false;
  811. for( U32 newIndex = 0; newIndex < newPickCount; ++newIndex )
  812. {
  813. // Skip if scene object is not present.
  814. if ( mInputEventQuery[newIndex].mpSceneObject != pOldSceneObject )
  815. continue;
  816. // Flag as still present.
  817. stillPresent = true;
  818. break;
  819. }
  820. // Add scene object as leaving if not still present.
  821. if ( !stillPresent )
  822. mInputEventLeaving.push_back( pOldSceneObject );
  823. }
  824. for ( U32 index = 0; index < (U32)mInputEventQuery.size(); ++index )
  825. {
  826. // Fetch scene object.
  827. SceneObject* pSceneObject = mInputEventQuery[index].mpSceneObject;
  828. // Ignore object if it's not using input events.
  829. if ( !pSceneObject->getUseInputEvents() )
  830. continue;
  831. // Emit event.
  832. pSceneObject->onInputEvent( name, event, worldMousePoint );
  833. }
  834. // Process "leave" events.
  835. for ( U32 index = 0; index < (U32)mInputEventLeaving.size(); ++index )
  836. {
  837. // Fetch scene object.
  838. SceneObject* pSceneObject = mInputEventLeaving[index];
  839. // Emit event.
  840. pSceneObject->onInputEvent( mInputEventLeaveName, event, worldMousePoint );
  841. // Remove scene object.
  842. mInputEventWatching.removeObject( pSceneObject );
  843. }
  844. // Process "enter" events.
  845. for ( U32 index = 0; index < (U32)mInputEventEntering.size(); ++index )
  846. {
  847. // Fetch scene object.
  848. SceneObject* pSceneObject = mInputEventEntering[index];
  849. // Emit event.
  850. pSceneObject->onInputEvent( mInputEventEnterName, event, worldMousePoint );
  851. // Process "moved" or "dragged" events.
  852. if ( name == mInputEventMovedName || name == mInputEventDraggedName )
  853. pSceneObject->onInputEvent( name, event, worldMousePoint );
  854. // Add scene object.
  855. mInputEventWatching.addObject( pSceneObject );
  856. }
  857. // Clear input event vectors.
  858. mInputEventQuery.clear();
  859. mInputEventEntering.clear();
  860. mInputEventLeaving.clear();
  861. }
  862. //-----------------------------------------------------------------------------
  863. void SceneWindow::onMouseDown( const GuiEvent& event )
  864. {
  865. // Lock Mouse (if necessary).
  866. if(mLockMouse)
  867. mouseLock();
  868. // Dispatch input event.
  869. dispatchInputEvent( mInputEventDownName, event);
  870. }
  871. //-----------------------------------------------------------------------------
  872. void SceneWindow::onMouseUp( const GuiEvent& event )
  873. {
  874. // Lock Mouse (if necessary).
  875. if(mLockMouse)
  876. mouseUnlock();
  877. // Dispatch input event.
  878. dispatchInputEvent(mInputEventUpName, event);
  879. }
  880. //-----------------------------------------------------------------------------
  881. void SceneWindow::onMouseMove( const GuiEvent& event )
  882. {
  883. // Dispatch input event.
  884. dispatchInputEvent(mInputEventMovedName, event);
  885. }
  886. //-----------------------------------------------------------------------------
  887. void SceneWindow::onMouseDragged( const GuiEvent& event )
  888. {
  889. // Dispatch input event.
  890. dispatchInputEvent(mInputEventDraggedName, event);
  891. }
  892. //-----------------------------------------------------------------------------
  893. void SceneWindow::onMouseEnter( const GuiEvent& event )
  894. {
  895. // Dispatch input event.
  896. dispatchInputEvent(mMouseEventEnterName, event);
  897. }
  898. //-----------------------------------------------------------------------------
  899. void SceneWindow::onMouseLeave( const GuiEvent& event )
  900. {
  901. // Dispatch input event.
  902. dispatchInputEvent(mMouseEventLeaveName, event);
  903. }
  904. //-----------------------------------------------------------------------------
  905. void SceneWindow::onRightMouseDown( const GuiEvent& event )
  906. {
  907. // Lock Mouse (if necessary).
  908. if(mLockMouse)
  909. mouseLock();
  910. // Dispatch input event.
  911. dispatchInputEvent(mMouseEventRightMouseDownName, event);
  912. }
  913. //-----------------------------------------------------------------------------
  914. void SceneWindow::onRightMouseUp( const GuiEvent& event )
  915. {
  916. // Lock Mouse (if necessary).
  917. if(mLockMouse)
  918. mouseUnlock();
  919. // Dispatch input event.
  920. dispatchInputEvent(mMouseEventRightMouseUpName, event);
  921. }
  922. //-----------------------------------------------------------------------------
  923. void SceneWindow::onRightMouseDragged( const GuiEvent& event )
  924. {
  925. // Dispatch input event.
  926. dispatchInputEvent(mMouseEventRightMouseDraggedName, event);
  927. }
  928. //-----------------------------------------------------------------------------
  929. bool SceneWindow::onMouseWheelUp( const GuiEvent& event )
  930. {
  931. // Call Parent.
  932. Parent::onMouseWheelUp( event );
  933. // Dispatch input event.
  934. dispatchInputEvent(mMouseEventWheelUpName, event);
  935. // Return Success.
  936. return true;
  937. }
  938. //-----------------------------------------------------------------------------
  939. bool SceneWindow::onMouseWheelDown( const GuiEvent& event )
  940. {
  941. // Call Parent.
  942. Parent::onMouseWheelDown( event );
  943. // Dispatch input event.
  944. dispatchInputEvent(mMouseEventWheelDownName, event);
  945. // Return Success.
  946. return true;
  947. }
  948. //-----------------------------------------------------------------------------
  949. void SceneWindow::calculateCameraMount( const F32 elapsedTime )
  950. {
  951. // Debug Profiling.
  952. PROFILE_SCOPE(SceneWindow_CalculateCameraMount);
  953. // Fetch Mount Position.
  954. const Vector2& mountPos = mpMountedTo->getBody()->GetWorldPoint( mMountOffset );
  955. // Set Pre-Tick Position.
  956. mPreTickPosition = mPostTickPosition;
  957. // Set Current Camera Position.
  958. mCameraCurrent.mSourceArea.point = mPreTickPosition;
  959. // Calculate Window Half-Dimensions.
  960. const F32 halfWidth = mCameraCurrent.mSourceArea.len_x() * 0.5f;
  961. const F32 halfHeight = mCameraCurrent.mSourceArea.len_y() * 0.5f;
  962. // Calculate Target Position.
  963. const Point2F targetPos = Point2F( mountPos.x - halfWidth, mountPos.y - halfHeight );
  964. // Mount the angle?
  965. if ( mMountAngle )
  966. mCameraCurrent.mCameraAngle = -mpMountedTo->getAngle();
  967. // Rigid Mount?
  968. if ( mIsZero( mMountForce ) )
  969. {
  970. // Yes, so easy post-tick position.
  971. mPostTickPosition = targetPos;
  972. return;
  973. }
  974. // Calculate Time/Force Product.
  975. const F32 timeForce = elapsedTime * mMountForce;
  976. // Will we exceed our step?
  977. if ( timeForce > 1.0f )
  978. {
  979. // Yes, so clamp at step.
  980. mPostTickPosition = targetPos;
  981. return;
  982. }
  983. else
  984. {
  985. // No, so calculate Direction to move.
  986. const Point2F direction = (targetPos - mPreTickPosition) * timeForce;
  987. // Calculate post-tick position.
  988. mPostTickPosition = mPreTickPosition + direction;
  989. return;
  990. }
  991. }
  992. //-----------------------------------------------------------------------------
  993. void SceneWindow::calculateCameraView( CameraView* pCameraView )
  994. {
  995. // Debug Profiling.
  996. PROFILE_SCOPE(SceneWindow_CalculateCameraView);
  997. // Calculate Zoom Reciprocal.
  998. const F32 zoomRecip = pCameraView->mCameraZoom > 0.0f ? 1.0f / pCameraView->mCameraZoom : pCameraView->mCameraZoom;
  999. // Calculate Zoom X/Y Factors.
  1000. const F32 zoomFactorX = (pCameraView->mSourceArea.len_x() - (pCameraView->mSourceArea.len_x() * zoomRecip))/2;
  1001. const F32 zoomFactorY = (pCameraView->mSourceArea.len_y() - (pCameraView->mSourceArea.len_y() * zoomRecip))/2;
  1002. // Fetch Camera View.
  1003. pCameraView->mDestinationArea = pCameraView->mSourceArea;
  1004. // Inset Window by Zoom Factor (if it's big enough to do so).
  1005. if ( pCameraView->mDestinationArea.extent.x > (zoomFactorX*2.0f) &&
  1006. pCameraView->mDestinationArea.extent.y > (zoomFactorY*2.0f) )
  1007. {
  1008. pCameraView->mDestinationArea.inset( zoomFactorX, zoomFactorY );
  1009. }
  1010. // Ensure we've got a valid window.
  1011. if ( !pCameraView->mDestinationArea.isValidRect() )
  1012. // Make it real!
  1013. pCameraView->mDestinationArea.extent = Point2F(1,1);
  1014. // Calculate Scene Min/Max.
  1015. pCameraView->mSceneMin.x = pCameraView->mDestinationArea.point.x;
  1016. pCameraView->mSceneMin.y = pCameraView->mDestinationArea.point.y;
  1017. pCameraView->mSceneMax.x = pCameraView->mDestinationArea.point.x + pCameraView->mDestinationArea.len_x();
  1018. pCameraView->mSceneMax.y = pCameraView->mDestinationArea.point.y + pCameraView->mDestinationArea.len_y();
  1019. // Is View Limit Active?
  1020. if ( mViewLimitActive )
  1021. {
  1022. // Yes, so is the limit area X less than the current view X?
  1023. if ( mViewLimitArea.x < pCameraView->mDestinationArea.len_x() )
  1024. {
  1025. // Yes, so calculate center of view.
  1026. const F32 viewCenterX = mViewLimitMin.x + ( mViewLimitArea.x * 0.5f );
  1027. // Half Camera Width.
  1028. const F32 halfCameraX = pCameraView->mDestinationArea.len_x() * 0.5f;
  1029. // Calculate Min/Max X.
  1030. pCameraView->mSceneMin.x = viewCenterX - halfCameraX;
  1031. pCameraView->mSceneMax.x = viewCenterX + halfCameraX;
  1032. }
  1033. else
  1034. {
  1035. // No, so calculate window min overlap.
  1036. const F32 windowMinOverlapX = getMax(0.0f, mViewLimitMin.x - pCameraView->mSceneMin.x);
  1037. // Calculate window max overlap.
  1038. const F32 windowMaxOverlapX = getMin(0.0f, mViewLimitMax.x - pCameraView->mSceneMax.x);
  1039. // Adjust Window.
  1040. pCameraView->mSceneMin.x += windowMinOverlapX + windowMaxOverlapX;
  1041. pCameraView->mSceneMax.x += windowMinOverlapX + windowMaxOverlapX;
  1042. }
  1043. // Is the limit area Y less than the current view Y?
  1044. if ( mViewLimitArea.y < pCameraView->mDestinationArea.len_y() )
  1045. {
  1046. // Yes, so calculate center of view.
  1047. const F32 viewCenterY = mViewLimitMin.y + ( mViewLimitArea.y * 0.5f );
  1048. // Half Camera Height.
  1049. const F32 halfCameraY = pCameraView->mDestinationArea.len_y() * 0.5f;
  1050. // Calculate Min/Max Y.
  1051. pCameraView->mSceneMin.y = viewCenterY - halfCameraY;
  1052. pCameraView->mSceneMax.y = viewCenterY + halfCameraY;
  1053. }
  1054. else
  1055. {
  1056. // No, so calculate window min overlap.
  1057. const F32 windowMinOverlapY = getMax(0.0f, mViewLimitMin.y - pCameraView->mSceneMin.y);
  1058. // Calculate window max overlap.
  1059. const F32 windowMaxOverlapY = getMin(0.0f, mViewLimitMax.y - pCameraView->mSceneMax.y);
  1060. // Adjust Window.
  1061. pCameraView->mSceneMin.y += windowMinOverlapY + windowMaxOverlapY;
  1062. pCameraView->mSceneMax.y += windowMinOverlapY + windowMaxOverlapY;
  1063. }
  1064. // Recalculate destination area.
  1065. pCameraView->mDestinationArea.point = pCameraView->mSceneMin;
  1066. pCameraView->mDestinationArea.extent = pCameraView->mSceneMax - pCameraView->mSceneMin;
  1067. // Inset Window by Zoom Factor (if it's big enough to do so).
  1068. if ( pCameraView->mDestinationArea.extent.x > (zoomFactorX*2.0f) &&
  1069. pCameraView->mDestinationArea.extent.y > (zoomFactorY*2.0f) )
  1070. {
  1071. pCameraView->mDestinationArea.inset( zoomFactorX, zoomFactorY );
  1072. }
  1073. }
  1074. // Calculate Scene Window Scale.
  1075. pCameraView->mSceneWindowScale.x = (pCameraView->mSceneMax.x - pCameraView->mSceneMin.x) / mBounds.len_x();
  1076. pCameraView->mSceneWindowScale.y = (pCameraView->mSceneMax.y - pCameraView->mSceneMin.y) / mBounds.len_y();
  1077. }
  1078. //-----------------------------------------------------------------------------
  1079. void SceneWindow::resize(const Point2I &newPosition, const Point2I &newExtent)
  1080. {
  1081. // Resize Parent.
  1082. Parent::resize( newPosition, newExtent);
  1083. // Argument Buffer.
  1084. char argBuffer[64];
  1085. // Format Buffer.
  1086. dSprintf( argBuffer, 64, "%d %d %d %d", newPosition.x, newPosition.y, newExtent.x, newExtent.y );
  1087. // Resize Callback.
  1088. Con::executef( this, 2, "onExtentChange", argBuffer );
  1089. }
  1090. //-----------------------------------------------------------------------------
  1091. void SceneWindow::processTick( void )
  1092. {
  1093. // Debug Profiling.
  1094. PROFILE_SCOPE(SceneWindow_ProcessTick);
  1095. // Are we moving the camera.
  1096. if ( mMovingCamera )
  1097. {
  1098. // Yes, so add Elapsed Time (scaled appropriately).
  1099. mCurrentCameraTime += Tickable::smTickSec;
  1100. // Update Tick Camera Time.
  1101. updateTickCameraTime();
  1102. // Update Camera.
  1103. updateCamera();
  1104. }
  1105. // Is the Camera Shaking?
  1106. if ( mCameraShaking )
  1107. {
  1108. // Reduce Shake Life.
  1109. mShakeLife -= Tickable::smTickSec;
  1110. // Is the Shake still active?
  1111. if ( mShakeLife > 0.0f )
  1112. {
  1113. // Calculate Current Shake.
  1114. mCurrentShake -= mShakeRamp * Tickable::smTickSec;
  1115. // Clamp Shake.
  1116. mCurrentShake = getMax(mCurrentShake, 0.0f);
  1117. // Calculate the Screen Shake-Ratio.
  1118. const Point2F shakeRatio( mCameraCurrent.mDestinationArea.len_x() / F32(mBounds.len_x()), mCameraCurrent.mDestinationArea.len_y() / F32(mBounds.len_y()) );
  1119. // Calculate the Camera Shake Magnitude based upon the Screen Shake-Ratio.
  1120. const F32 shakeMagnitudeX = mCurrentShake * shakeRatio.x * 0.5f;
  1121. const F32 shakeMagnitudeY = mCurrentShake * shakeRatio.y * 0.5f;
  1122. // Choose a random Shake.
  1123. mCameraShakeOffset.Set( CoreMath::mGetRandomF( -shakeMagnitudeX, shakeMagnitudeX ), CoreMath::mGetRandomF( -shakeMagnitudeY, shakeMagnitudeY ) );
  1124. }
  1125. else
  1126. {
  1127. // No, so stop shake.
  1128. stopCameraShake();
  1129. }
  1130. }
  1131. }
  1132. //-----------------------------------------------------------------------------
  1133. void SceneWindow::interpolateTick( F32 timeDelta )
  1134. {
  1135. // Are we moving the camera.
  1136. if ( mMovingCamera )
  1137. {
  1138. // Calculate Render Tick Position.
  1139. mRenderCameraTime = (mPreCameraTime * timeDelta) + ((1.0f-timeDelta) * mPostCameraTime);
  1140. // Update Camera.
  1141. updateCamera();
  1142. }
  1143. }
  1144. //-----------------------------------------------------------------------------
  1145. void SceneWindow::interpolateCameraMount( const F32 timeDelta )
  1146. {
  1147. // Camera Mounted?
  1148. if ( !isCameraMounted() ) return;
  1149. // Calculate position.
  1150. mCameraCurrent.mSourceArea.point = (mPreTickPosition * timeDelta) + ((1.0f-timeDelta) * mPostTickPosition);
  1151. }
  1152. //-----------------------------------------------------------------------------
  1153. void SceneWindow::zeroCameraTime( void )
  1154. {
  1155. // Reset Camera Time.
  1156. mRenderCameraTime = mPreCameraTime = mPostCameraTime = mCurrentCameraTime = 0.0f;
  1157. }
  1158. //-----------------------------------------------------------------------------
  1159. void SceneWindow::resetTickCameraTime( void )
  1160. {
  1161. // Reset Camera Time.
  1162. mRenderCameraTime = mPreCameraTime = mPostCameraTime = mCurrentCameraTime;
  1163. }
  1164. //-----------------------------------------------------------------------------
  1165. void SceneWindow::updateTickCameraTime( void )
  1166. {
  1167. // Store Pre Camera Time.
  1168. mPreCameraTime = mPostCameraTime;
  1169. // Store Current Camera Time.
  1170. mPostCameraTime = mCurrentCameraTime;
  1171. // Render Camera Time is at Pre-Tick Time.
  1172. mRenderCameraTime = mPreCameraTime;
  1173. }
  1174. //-----------------------------------------------------------------------------
  1175. void SceneWindow::resetTickCameraPosition( void )
  1176. {
  1177. mPreTickPosition = mPostTickPosition = mCameraCurrent.mSourceArea.point;
  1178. }
  1179. //-----------------------------------------------------------------------------
  1180. void SceneWindow::onRender( Point2I offset, const RectI& updateRect )
  1181. {
  1182. // Debug Profiling.
  1183. PROFILE_SCOPE(SceneWindow_onRender);
  1184. // Fetch scene.
  1185. Scene* pScene = getScene();
  1186. // Cannot render without scene!
  1187. if ( !pScene )
  1188. return;
  1189. // Calculate current camera View ( if needed ).
  1190. calculateCameraView( &mCameraCurrent );
  1191. // Fetch current camera.
  1192. const Point2F& sceneWindowScale = mCameraCurrent.mSceneWindowScale;
  1193. Point2F sceneMin = mCameraCurrent.mSceneMin;
  1194. Point2F sceneMax = mCameraCurrent.mSceneMax;
  1195. // Fetch bounds.
  1196. const RectI& bounds = getBounds();
  1197. const Point2I globalTopLeft( updateRect.point.x, updateRect.point.y );
  1198. const Point2I globalBottomRight( updateRect.point.x + updateRect.extent.x, updateRect.point.y + updateRect.extent.y );
  1199. const Point2I localTopLeft = globalToLocalCoord( globalTopLeft );
  1200. const Point2I localBottomRight = globalToLocalCoord( globalBottomRight );
  1201. // Clip top?
  1202. if ( localTopLeft.y > 0 )
  1203. {
  1204. sceneMax.y -= localTopLeft.y * sceneWindowScale.y;
  1205. }
  1206. // Clip left?
  1207. if ( localTopLeft.x > 0 )
  1208. {
  1209. sceneMin.x += localTopLeft.x * sceneWindowScale.x;
  1210. }
  1211. // Clip bottom?
  1212. if ( localBottomRight.y < bounds.extent.y )
  1213. {
  1214. sceneMin.y += (bounds.extent.y - localBottomRight.y ) * sceneWindowScale.y;
  1215. }
  1216. // Clip right?
  1217. if ( localBottomRight.x < bounds.extent.x )
  1218. {
  1219. sceneMax.x -= (bounds.extent.x - localBottomRight.x ) * sceneWindowScale.x;
  1220. }
  1221. // Add camera shake offset if active.
  1222. if ( mCameraShaking )
  1223. {
  1224. sceneMin += mCameraShakeOffset;
  1225. sceneMax += mCameraShakeOffset;
  1226. }
  1227. // Setup new logical coordinate system.
  1228. glMatrixMode(GL_PROJECTION);
  1229. glPushMatrix();
  1230. glLoadIdentity();
  1231. // Set orthographic projection.
  1232. glOrtho( sceneMin.x, sceneMax.x, sceneMin.y, sceneMax.y, 0.0f, MAX_LAYERS_SUPPORTED );
  1233. // Set ModelView.
  1234. glMatrixMode(GL_MODELVIEW);
  1235. glPushMatrix();
  1236. glLoadIdentity();
  1237. // Disable Alpha Test by default
  1238. glDisable( GL_ALPHA_TEST );
  1239. glDisable( GL_DEPTH_TEST );
  1240. // Get Debug Stats.
  1241. DebugStats& debugStats = pScene->getDebugStats();
  1242. // Create a scene render state.
  1243. SceneRenderState sceneRenderState(
  1244. mCameraCurrent.mDestinationArea,
  1245. mCameraCurrent.mDestinationArea.centre(),
  1246. mCameraCurrent.mCameraAngle,
  1247. mRenderLayerMask,
  1248. mRenderGroupMask,
  1249. Vector2( mCameraCurrent.mSceneWindowScale ),
  1250. &debugStats );
  1251. // Render View.
  1252. pScene->sceneRender( &sceneRenderState );
  1253. // Restore Matrices.
  1254. glMatrixMode(GL_MODELVIEW);
  1255. glPopMatrix();
  1256. glMatrixMode(GL_PROJECTION);
  1257. glPopMatrix();
  1258. glMatrixMode(GL_MODELVIEW);
  1259. // Render the metrics.
  1260. renderMetricsOverlay( offset, updateRect );
  1261. // Render Children.
  1262. renderChildControls( offset, updateRect );
  1263. // Update Window.
  1264. setUpdate();
  1265. }
  1266. //------------------------------------------------------------------------------
  1267. void SceneWindow::renderMetricsOverlay( Point2I offset, const RectI& updateRect )
  1268. {
  1269. // Debug Profiling.
  1270. PROFILE_SCOPE(SceneWindow_RenderMetricsOverlay);
  1271. // Fetch scene.
  1272. Scene* pScene = getScene();
  1273. #if 0
  1274. // Force on debug rendering.
  1275. pScene->setDebugOn( 0xFFFFFFFF );
  1276. #endif
  1277. // Fetch full metrics mode.
  1278. const bool fullMetrics = pScene->getDebugMask() & Scene::SCENE_DEBUG_METRICS;
  1279. const bool fpsMetrics = pScene->getDebugMask() & Scene::SCENE_DEBUG_FPS_METRICS;
  1280. // Finish if should not or cannot render.
  1281. if ( ( !fullMetrics && !fpsMetrics ) ||
  1282. mProfile == NULL ||
  1283. mProfile->mFont.isNull() )
  1284. return;
  1285. // Fetch the font.
  1286. Resource<GFont>& font = mProfile->mFont;
  1287. // Blending for banner background.
  1288. glEnable ( GL_BLEND );
  1289. glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA );
  1290. // Set banner background colour.
  1291. const ColorI& fillColor = mProfile->mFillColor;
  1292. const F32 colorScale = 1.0f / 255.0f;
  1293. glColor4f( fillColor.red * colorScale, fillColor.green * colorScale, fillColor.blue * colorScale, fillColor.alpha * colorScale );
  1294. // Fetch debug scene object.
  1295. SceneObject* pDebugSceneObject = pScene->getDebugSceneObject();
  1296. // Get Debug Stats.
  1297. DebugStats& debugStats = pScene->getDebugStats();
  1298. // Set metrics offset
  1299. const S32 metricsOffset = (S32)font->getStrWidth( "WWWWWWWWWWWW" );
  1300. // Set Banner Height.
  1301. F32 bannerLineHeight = fullMetrics ? 17.0f : 1.0f;
  1302. // Add an extra line if we're monitoring a scene object.
  1303. if ( pDebugSceneObject != NULL )
  1304. bannerLineHeight += 5.0f;
  1305. U32 bannerHeight = (U32)((bannerLineHeight * (F32)font->getHeight()));
  1306. // Calculate Debug Banner Offset.
  1307. Point2I bannerOffset = updateRect.point + Point2I(8,8);
  1308. // Draw Banner Background.
  1309. glBegin(GL_TRIANGLE_STRIP);
  1310. glVertex2i( updateRect.point.x, updateRect.point.y );
  1311. glVertex2i( updateRect.point.x + updateRect.extent.x, updateRect.point.y );
  1312. glVertex2i( updateRect.point.x, updateRect.point.y + bannerHeight + 16);
  1313. glVertex2i( updateRect.point.x + updateRect.extent.x, updateRect.point.y + bannerHeight + 16);
  1314. glEnd();
  1315. // Disable Banner Blending.
  1316. glDisable ( GL_BLEND );
  1317. // Set Debug Text Colour.
  1318. dglSetBitmapModulation( mProfile->mFontColor );
  1319. // ****************************************************************
  1320. // Draw Banner Text.
  1321. // ****************************************************************
  1322. F32 linePositionY = 0.25f;
  1323. F32 linePositionOffsetY = font->getHeight() * 1.25f;
  1324. if ( fullMetrics )
  1325. {
  1326. // Rendering.
  1327. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Render", NULL );
  1328. dSprintf( mDebugText, sizeof( mDebugText ), "- FPS=%4.1f<%4.1f/%4.1f>, Frames=%u, Picked=%d<%d>, RenderRequests=%d<%d>, RenderFallbacks=%d<%d>",
  1329. debugStats.fps, debugStats.minFPS, debugStats.maxFPS,
  1330. debugStats.frameCount,
  1331. debugStats.renderPicked, debugStats.maxRenderPicked,
  1332. debugStats.renderRequests, debugStats.maxRenderRequests,
  1333. debugStats.renderFallbacks, debugStats.maxRenderFallbacks );
  1334. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1335. linePositionY += linePositionOffsetY;
  1336. // Scene.
  1337. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Scene", NULL );
  1338. dSprintf( mDebugText, sizeof( mDebugText ), "- Count=%d, Index=%d, Time=%0.1fs, Objects=%d<%d>(Global=%d), Enabled=%d<%d>, Visible=%d<%d>, Awake=%d<%d>, Controllers=%d",
  1339. Scene::getGlobalSceneCount(), pScene->getSceneIndex(),
  1340. pScene->getSceneTime(),
  1341. debugStats.objectsCount, debugStats.maxObjectsCount, SceneObject::getGlobalSceneObjectCount(),
  1342. debugStats.objectsEnabled, debugStats.maxObjectsEnabled,
  1343. debugStats.objectsVisible, debugStats.maxObjectsVisible,
  1344. debugStats.objectsAwake, debugStats.maxObjectsAwake,
  1345. pScene->getControllers() == NULL ? 0 : pScene->getControllers()->size() );
  1346. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1347. linePositionY += linePositionOffsetY;
  1348. // Camera Window #1.
  1349. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Camera", NULL );
  1350. Vector2 cameraPosition = getCameraPosition();
  1351. dSprintf( mDebugText, sizeof( mDebugText ), "- Pos=(%0.1f,%0.1f), Size=(%0.1f,%0.1f), Zoom=%0.1f, Angle=%0.1f, Lower=(%0.1f,%0.1f), Upper=(%0.1f,%0.1f)",
  1352. cameraPosition.x,
  1353. cameraPosition.y,
  1354. mCameraCurrent.mSourceArea.extent.x,
  1355. mCameraCurrent.mSourceArea.extent.y,
  1356. mCameraCurrent.mCameraZoom,
  1357. mRadToDeg(mCameraCurrent.mCameraAngle),
  1358. mCameraCurrent.mSourceArea.point.x,
  1359. mCameraCurrent.mSourceArea.point.y,
  1360. mCameraCurrent.mSourceArea.point.x + mCameraCurrent.mSourceArea.extent.x,
  1361. mCameraCurrent.mSourceArea.point.y + mCameraCurrent.mSourceArea.extent.y );
  1362. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1363. linePositionY += linePositionOffsetY;
  1364. // Camera Window #2.
  1365. Point2I windowExtent = getExtent();
  1366. Vector2 windowScale = getCameraWindowScale();
  1367. dSprintf( mDebugText, sizeof( mDebugText ), "- Window=(%d,%d), WorldScale=(%0.3f,%0.3f), RenderScale=(%0.3f,%0.3f)",
  1368. windowExtent.x, windowExtent.y,
  1369. windowScale.x, windowScale.y,
  1370. 1.0f / windowScale.x, 1.0f / windowScale.y);
  1371. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1372. linePositionY += linePositionOffsetY;
  1373. // Batching #1.
  1374. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Batching", NULL );
  1375. dSprintf( mDebugText, sizeof( mDebugText ), "- %sTris=%d<%d>, MaxTriDraw=%d, MaxVerts=%d, Single=%d<%d>, Mult=%d<%d>, Sorted=%d<%d>",
  1376. pScene->getBatchingEnabled() ? "" : "(OFF) ",
  1377. debugStats.batchTrianglesSubmitted, debugStats.maxBatchTrianglesSubmitted,
  1378. debugStats.batchMaxTriangleDrawn,
  1379. debugStats.batchMaxVertexBuffer,
  1380. debugStats.batchDrawCallsStrictSingle, debugStats.maxBatchDrawCallsStrictSingle,
  1381. debugStats.batchDrawCallsStrictMultiple, debugStats.maxBatchDrawCallsStrictMultiple,
  1382. debugStats.batchDrawCallsSorted, debugStats.maxBatchDrawCallsSorted
  1383. );
  1384. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1385. linePositionY += linePositionOffsetY;
  1386. // Batching #2.
  1387. dSprintf( mDebugText, sizeof( mDebugText ), "- Flush=%d<%d>, BlendFlush=%d<%d>, ColorFlush=%d<%d>, AlphaFlush=%d<%d>, TexFlush=%d<%d>",
  1388. debugStats.batchFlushes, debugStats.maxBatchFlushes,
  1389. debugStats.batchBlendStateFlush, debugStats.maxBatchBlendStateFlush,
  1390. debugStats.batchColorStateFlush, debugStats.maxBatchColorStateFlush,
  1391. debugStats.batchAlphaStateFlush, debugStats.maxBatchAlphaStateFlush,
  1392. debugStats.batchTextureChangeFlush, debugStats.maxBatchTextureChangeFlushes
  1393. );
  1394. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1395. linePositionY += linePositionOffsetY;
  1396. // Batching #3.
  1397. dSprintf( mDebugText, sizeof( mDebugText ), "- IsolatedFlush=%d<%d>, FullFlush=%d<%d>, LayerFlush=%d<%d>, NoBatchFlush=%d<%d>, AnonFlush=%d<%d>",
  1398. debugStats.batchIsolatedFlush, debugStats.maxBatchIsolatedFlush,
  1399. debugStats.batchBufferFullFlush, debugStats.maxBatchBufferFullFlush,
  1400. debugStats.batchLayerFlush, debugStats.maxBatchLayerFlush,
  1401. debugStats.batchNoBatchFlush, debugStats.maxBatchNoBatchFlush,
  1402. debugStats.batchAnonymousFlush, debugStats.maxBatchAnonymousFlush
  1403. );
  1404. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1405. linePositionY += linePositionOffsetY;
  1406. // Textures.
  1407. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Textures", NULL );
  1408. dSprintf( mDebugText, sizeof( mDebugText ), "- TextureCount=%d, TextureSize=%d, TextureWaste=%d, BitmapSize=%d",
  1409. TextureManager::getTextureResidentCount(),
  1410. TextureManager::getTextureResidentSize(),
  1411. TextureManager::getTextureResidentWasteSize(),
  1412. TextureManager::getBitmapResidentSize()
  1413. );
  1414. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1415. linePositionY += linePositionOffsetY;
  1416. // Physics.
  1417. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Physics", NULL );
  1418. dSprintf( mDebugText, sizeof( mDebugText ), "- Bodies=%d<%d>, Joints=%d<%d>, Contacts=%d<%d>, Proxies=%d<%d>",
  1419. debugStats.bodyCount, debugStats.maxBodyCount,
  1420. debugStats.jointCount, debugStats.maxJointCount,
  1421. debugStats.contactCount, debugStats.maxContactCount,
  1422. debugStats.proxyCount, debugStats.maxProxyCount );
  1423. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1424. linePositionY += linePositionOffsetY;
  1425. const b2Profile& worldProfile = debugStats.worldProfile;
  1426. const b2Profile& maxWorldProfile = debugStats.maxWorldProfile;
  1427. // Physics timings #1.
  1428. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Timings", NULL );
  1429. dSprintf( mDebugText, sizeof( mDebugText ), "- Step=%0.0f<%0.0f>, Collide=%0.0f<%0.0f>, BroadPhase=%0.0f<%0.0f>",
  1430. worldProfile.step, maxWorldProfile.step,
  1431. worldProfile.collide, maxWorldProfile.collide,
  1432. worldProfile.broadphase, maxWorldProfile.broadphase );
  1433. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1434. linePositionY += linePositionOffsetY;
  1435. // Physics timings #2.
  1436. dSprintf( mDebugText, sizeof( mDebugText ), "- Solve=%0.0f<%0.0f>, SolveInit=%0.0f<%0.0f>, SolveVel=%0.0f<%0.0f>, SolvePos=%0.0f<%0.0f>, SolveTOI=%0.0f<%0.0f>",
  1437. worldProfile.solve, maxWorldProfile.solve,
  1438. worldProfile.solveInit, maxWorldProfile.solveInit,
  1439. worldProfile.solveVelocity, maxWorldProfile.solveVelocity,
  1440. worldProfile.solvePosition, maxWorldProfile.solvePosition,
  1441. worldProfile.solveTOI, maxWorldProfile.solveTOI );
  1442. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1443. linePositionY += linePositionOffsetY;
  1444. // Physics spatial tree.
  1445. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Partition", NULL );
  1446. const b2World* pWorld = pScene->getWorld();
  1447. const S32 treeBalance = pWorld->GetTreeBalance();
  1448. const S32 treeHeight = pWorld->GetTreeHeight();
  1449. const F32 treeQuality = pWorld->GetTreeQuality();
  1450. dSprintf( mDebugText, sizeof( mDebugText ), "- Balance=%d, Height=%d, Quality=%0.2f",
  1451. treeBalance,
  1452. treeHeight,
  1453. treeQuality );
  1454. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1455. linePositionY += linePositionOffsetY;
  1456. // Particles.
  1457. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Particles", NULL );
  1458. dSprintf( mDebugText, sizeof( mDebugText ), "- Allocated=%d, Used=%d<%d>, Free=%d",
  1459. debugStats.particlesAlloc,
  1460. debugStats.particlesUsed, debugStats.maxParticlesUsed,
  1461. debugStats.particlesFree );
  1462. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1463. linePositionY += linePositionOffsetY;
  1464. // Asset Manager.
  1465. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Assets", NULL );
  1466. dSprintf( mDebugText, sizeof( mDebugText ), "- AcquiredRefs=%d, Declared=%d, Referenced=%d, LoadedInternal=%d<%d>, LoadedExternal=%d<%d>, LoadedPrivate=%d<%d>",
  1467. AssetDatabase.getAcquiredReferenceCount(),
  1468. AssetDatabase.getDeclaredAssetCount(),
  1469. AssetDatabase.getReferencedAssetCount(),
  1470. AssetDatabase.getLoadedInternalAssetCount(), AssetDatabase.getMaxLoadedInternalAssetCount(),
  1471. AssetDatabase.getLoadedExternalAssetCount(), AssetDatabase.getMaxLoadedExternalAssetCount(),
  1472. AssetDatabase.getLoadedPrivateAssetCount(), AssetDatabase.getMaxLoadedPrivateAssetCount() );
  1473. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1474. linePositionY += linePositionOffsetY;
  1475. }
  1476. else if ( fpsMetrics )
  1477. {
  1478. // Rendering.
  1479. dSprintf( mDebugText, sizeof( mDebugText ), "FPS=%4.1f<%4.1f/%4.1f>",
  1480. debugStats.fps, debugStats.minFPS, debugStats.maxFPS );
  1481. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), mDebugText, NULL );
  1482. linePositionY += linePositionOffsetY;
  1483. }
  1484. // Monitored scene object.
  1485. if ( pDebugSceneObject != NULL )
  1486. {
  1487. // SceneObject #1.
  1488. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "SceneObject", NULL );
  1489. const b2Vec2 position = pDebugSceneObject->getRenderPosition();
  1490. const F32 angle = mRadToDeg( pDebugSceneObject->getRenderAngle() );
  1491. const Vector2 size = pDebugSceneObject->getSize();
  1492. const U32 sceneLayer = pDebugSceneObject->getSceneLayer();
  1493. const U32 sceneGroup = pDebugSceneObject->getSceneGroup();
  1494. const U32 serialId = pDebugSceneObject->getSerialId();
  1495. StringTableEntry renderGroup = pDebugSceneObject->getRenderGroup();
  1496. dSprintf( mDebugText, sizeof( mDebugText ), "- Id=%d, Pos=(%0.3f,%0.3f), Angle=%0.3f, Size=(%0.3f,%0.3f), Layer=%d, Group=%d, SerialId=%d, RenderGroup='%s'",
  1497. pDebugSceneObject->getId(),
  1498. position.x, position.y,
  1499. angle,
  1500. size.x, size.y,
  1501. sceneLayer,
  1502. sceneGroup,
  1503. serialId,
  1504. renderGroup
  1505. );
  1506. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1507. linePositionY += linePositionOffsetY;
  1508. // SceneObject #2.
  1509. const char* pBodyType = SceneObject::getBodyTypeDescription(pDebugSceneObject->getBodyType());
  1510. const bool enabled = pDebugSceneObject->isEnabled();
  1511. const bool active = pDebugSceneObject->getActive();
  1512. const bool visible = pDebugSceneObject->getVisible();
  1513. const bool isBullet = pDebugSceneObject->getBullet();
  1514. const bool awake = pDebugSceneObject->getAwake();
  1515. const bool sleepingAllowed = pDebugSceneObject->getSleepingAllowed();
  1516. dSprintf( mDebugText, sizeof( mDebugText ), "- Body=%s, Enabled=%d, Active=%d, Visible=%d, Bullet=%d, Awake=%d, CanSleep=%d",
  1517. pBodyType,
  1518. enabled,
  1519. active,
  1520. visible,
  1521. isBullet,
  1522. awake,
  1523. sleepingAllowed
  1524. );
  1525. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1526. linePositionY += linePositionOffsetY;
  1527. // SceneObject #3.
  1528. const Vector2 linearVelocity = pDebugSceneObject->getLinearVelocity();
  1529. const F32 angularVelocity = pDebugSceneObject->getAngularVelocity();
  1530. const F32 linearDamping = pDebugSceneObject->getLinearDamping();
  1531. const F32 angularDamping = pDebugSceneObject->getAngularDamping();
  1532. const Vector2 localCenter = pDebugSceneObject->getLocalCenter();
  1533. dSprintf( mDebugText, sizeof( mDebugText ), "- LinVel=(%0.3f,%0.3f), AngVel=%0.3f, LinDamp=%0.3f, AngDamp=%0.3f, Com=(%0.3f,%0.3f)",
  1534. linearVelocity.x, linearVelocity.y,
  1535. angularVelocity,
  1536. linearDamping,
  1537. angularDamping,
  1538. localCenter.x, localCenter.y
  1539. );
  1540. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1541. linePositionY += linePositionOffsetY;
  1542. // SceneObject #4.
  1543. const bool collisionSuppress = pDebugSceneObject->getCollisionSuppress();
  1544. const U32 collisionLayerMask = pDebugSceneObject->getCollisionLayerMask();
  1545. const U32 collisionGroupMask = pDebugSceneObject->getCollisionGroupMask();
  1546. const U32 collisionShapeCount = pDebugSceneObject->getCollisionShapeCount();
  1547. dSprintf( mDebugText, sizeof( mDebugText ), "- Shapes=%d, ColSuppress=%d, ColLayer=%0.8x, ColGroup=%0.8x",
  1548. collisionShapeCount,
  1549. collisionSuppress,
  1550. collisionLayerMask,
  1551. collisionGroupMask
  1552. );
  1553. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1554. }
  1555. // Clear Bitmap Modulation.
  1556. dglClearBitmapModulation();
  1557. }