SceneWindow.cc 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966
  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>",
  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. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1346. linePositionY += linePositionOffsetY;
  1347. // Camera Window #1.
  1348. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Camera", NULL );
  1349. Vector2 cameraPosition = getCameraPosition();
  1350. 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)",
  1351. cameraPosition.x,
  1352. cameraPosition.y,
  1353. mCameraCurrent.mSourceArea.extent.x,
  1354. mCameraCurrent.mSourceArea.extent.y,
  1355. mCameraCurrent.mCameraZoom,
  1356. mRadToDeg(mCameraCurrent.mCameraAngle),
  1357. mCameraCurrent.mSourceArea.point.x,
  1358. mCameraCurrent.mSourceArea.point.y,
  1359. mCameraCurrent.mSourceArea.point.x + mCameraCurrent.mSourceArea.extent.x,
  1360. mCameraCurrent.mSourceArea.point.y + mCameraCurrent.mSourceArea.extent.y );
  1361. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1362. linePositionY += linePositionOffsetY;
  1363. // Camera Window #2.
  1364. Point2I windowExtent = getExtent();
  1365. Vector2 windowScale = getCameraWindowScale();
  1366. dSprintf( mDebugText, sizeof( mDebugText ), "- Window=(%d,%d), WorldScale=(%0.3f,%0.3f), RenderScale=(%0.3f,%0.3f)",
  1367. windowExtent.x, windowExtent.y,
  1368. windowScale.x, windowScale.y,
  1369. 1.0f / windowScale.x, 1.0f / windowScale.y);
  1370. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1371. linePositionY += linePositionOffsetY;
  1372. // Batching #1.
  1373. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Batching", NULL );
  1374. dSprintf( mDebugText, sizeof( mDebugText ), "- %sTris=%d<%d>, MaxTriDraw=%d, MaxVerts=%d, Single=%d<%d>, Mult=%d<%d>, Sorted=%d<%d>",
  1375. pScene->getBatchingEnabled() ? "" : "(OFF) ",
  1376. debugStats.batchTrianglesSubmitted, debugStats.maxBatchTrianglesSubmitted,
  1377. debugStats.batchMaxTriangleDrawn,
  1378. debugStats.batchMaxVertexBuffer,
  1379. debugStats.batchDrawCallsStrictSingle, debugStats.maxBatchDrawCallsStrictSingle,
  1380. debugStats.batchDrawCallsStrictMultiple, debugStats.maxBatchDrawCallsStrictMultiple,
  1381. debugStats.batchDrawCallsSorted, debugStats.maxBatchDrawCallsSorted
  1382. );
  1383. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1384. linePositionY += linePositionOffsetY;
  1385. // Batching #2.
  1386. dSprintf( mDebugText, sizeof( mDebugText ), "- Flush=%d<%d>, BlendFlush=%d<%d>, ColorFlush=%d<%d>, AlphaFlush=%d<%d>, TexFlush=%d<%d>",
  1387. debugStats.batchFlushes, debugStats.maxBatchFlushes,
  1388. debugStats.batchBlendStateFlush, debugStats.maxBatchBlendStateFlush,
  1389. debugStats.batchColorStateFlush, debugStats.maxBatchColorStateFlush,
  1390. debugStats.batchAlphaStateFlush, debugStats.maxBatchAlphaStateFlush,
  1391. debugStats.batchTextureChangeFlush, debugStats.maxBatchTextureChangeFlushes
  1392. );
  1393. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1394. linePositionY += linePositionOffsetY;
  1395. // Batching #3.
  1396. dSprintf( mDebugText, sizeof( mDebugText ), "- IsolatedFlush=%d<%d>, FullFlush=%d<%d>, LayerFlush=%d<%d>, NoBatchFlush=%d<%d>, AnonFlush=%d<%d>",
  1397. debugStats.batchIsolatedFlush, debugStats.maxBatchIsolatedFlush,
  1398. debugStats.batchBufferFullFlush, debugStats.maxBatchBufferFullFlush,
  1399. debugStats.batchLayerFlush, debugStats.maxBatchLayerFlush,
  1400. debugStats.batchNoBatchFlush, debugStats.maxBatchNoBatchFlush,
  1401. debugStats.batchAnonymousFlush, debugStats.maxBatchAnonymousFlush
  1402. );
  1403. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1404. linePositionY += linePositionOffsetY;
  1405. // Textures.
  1406. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Textures", NULL );
  1407. dSprintf( mDebugText, sizeof( mDebugText ), "- TextureCount=%d, TextureSize=%d, TextureWaste=%d, BitmapSize=%d",
  1408. TextureManager::getTextureResidentCount(),
  1409. TextureManager::getTextureResidentSize(),
  1410. TextureManager::getTextureResidentWasteSize(),
  1411. TextureManager::getBitmapResidentSize()
  1412. );
  1413. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1414. linePositionY += linePositionOffsetY;
  1415. // Physics.
  1416. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Physics", NULL );
  1417. dSprintf( mDebugText, sizeof( mDebugText ), "- Bodies=%d<%d>, Joints=%d<%d>, Contacts=%d<%d>, Proxies=%d<%d>",
  1418. debugStats.bodyCount, debugStats.maxBodyCount,
  1419. debugStats.jointCount, debugStats.maxJointCount,
  1420. debugStats.contactCount, debugStats.maxContactCount,
  1421. debugStats.proxyCount, debugStats.maxProxyCount );
  1422. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1423. linePositionY += linePositionOffsetY;
  1424. const b2Profile& worldProfile = debugStats.worldProfile;
  1425. const b2Profile& maxWorldProfile = debugStats.maxWorldProfile;
  1426. // Physics timings #1.
  1427. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Timings", NULL );
  1428. dSprintf( mDebugText, sizeof( mDebugText ), "- Step=%0.0f<%0.0f>, Collide=%0.0f<%0.0f>, BroadPhase=%0.0f<%0.0f>",
  1429. worldProfile.step, maxWorldProfile.step,
  1430. worldProfile.collide, maxWorldProfile.collide,
  1431. worldProfile.broadphase, maxWorldProfile.broadphase );
  1432. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1433. linePositionY += linePositionOffsetY;
  1434. // Physics timings #2.
  1435. 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>",
  1436. worldProfile.solve, maxWorldProfile.solve,
  1437. worldProfile.solveInit, maxWorldProfile.solveInit,
  1438. worldProfile.solveVelocity, maxWorldProfile.solveVelocity,
  1439. worldProfile.solvePosition, maxWorldProfile.solvePosition,
  1440. worldProfile.solveTOI, maxWorldProfile.solveTOI );
  1441. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1442. linePositionY += linePositionOffsetY;
  1443. // Physics spatial tree.
  1444. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Partition", NULL );
  1445. const b2World* pWorld = pScene->getWorld();
  1446. const S32 treeBalance = pWorld->GetTreeBalance();
  1447. const S32 treeHeight = pWorld->GetTreeHeight();
  1448. const F32 treeQuality = pWorld->GetTreeQuality();
  1449. dSprintf( mDebugText, sizeof( mDebugText ), "- Balance=%d, Height=%d, Quality=%0.2f",
  1450. treeBalance,
  1451. treeHeight,
  1452. treeQuality );
  1453. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1454. linePositionY += linePositionOffsetY;
  1455. // Particles.
  1456. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Particles", NULL );
  1457. dSprintf( mDebugText, sizeof( mDebugText ), "- Allocated=%d, Used=%d<%d>, Free=%d",
  1458. debugStats.particlesAlloc,
  1459. debugStats.particlesUsed, debugStats.maxParticlesUsed,
  1460. debugStats.particlesFree );
  1461. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1462. linePositionY += linePositionOffsetY;
  1463. // Asset Manager.
  1464. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "Assets", NULL );
  1465. dSprintf( mDebugText, sizeof( mDebugText ), "- Declared=%d, Referenced=%d, LoadedInternal=%d<%d>, LoadedExternal=%d<%d>, LoadedPrivate=%d<%d>",
  1466. AssetDatabase.getDeclaredAssetCount(),
  1467. AssetDatabase.getReferencedAssetCount(),
  1468. AssetDatabase.getLoadedInternalAssetCount(), AssetDatabase.getMaxLoadedInternalAssetCount(),
  1469. AssetDatabase.getLoadedExternalAssetCount(), AssetDatabase.getMaxLoadedExternalAssetCount(),
  1470. AssetDatabase.getLoadedPrivateAssetCount(), AssetDatabase.getMaxLoadedPrivateAssetCount());
  1471. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1472. linePositionY += linePositionOffsetY;
  1473. }
  1474. else if ( fpsMetrics )
  1475. {
  1476. // Rendering.
  1477. dSprintf( mDebugText, sizeof( mDebugText ), "FPS=%4.1f<%4.1f/%4.1f>",
  1478. debugStats.fps, debugStats.minFPS, debugStats.maxFPS );
  1479. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), mDebugText, NULL );
  1480. linePositionY += linePositionOffsetY;
  1481. }
  1482. // Monitored scene object.
  1483. if ( pDebugSceneObject != NULL )
  1484. {
  1485. // SceneObject #1.
  1486. dglDrawText( font, bannerOffset + Point2I(0,(S32)linePositionY), "SceneObject", NULL );
  1487. const b2Vec2 position = pDebugSceneObject->getRenderPosition();
  1488. const F32 angle = mRadToDeg( pDebugSceneObject->getRenderAngle() );
  1489. const Vector2 size = pDebugSceneObject->getSize();
  1490. const U32 sceneLayer = pDebugSceneObject->getSceneLayer();
  1491. const U32 sceneGroup = pDebugSceneObject->getSceneGroup();
  1492. const U32 serialId = pDebugSceneObject->getSerialId();
  1493. StringTableEntry renderGroup = pDebugSceneObject->getRenderGroup();
  1494. 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'",
  1495. pDebugSceneObject->getId(),
  1496. position.x, position.y,
  1497. angle,
  1498. size.x, size.y,
  1499. sceneLayer,
  1500. sceneGroup,
  1501. serialId,
  1502. renderGroup
  1503. );
  1504. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1505. linePositionY += linePositionOffsetY;
  1506. // SceneObject #2.
  1507. const char* pBodyType = SceneObject::getBodyTypeDescription(pDebugSceneObject->getBodyType());
  1508. const bool enabled = pDebugSceneObject->isEnabled();
  1509. const bool active = pDebugSceneObject->getActive();
  1510. const bool visible = pDebugSceneObject->getVisible();
  1511. const bool isBullet = pDebugSceneObject->getBullet();
  1512. const bool awake = pDebugSceneObject->getAwake();
  1513. const bool sleepingAllowed = pDebugSceneObject->getSleepingAllowed();
  1514. dSprintf( mDebugText, sizeof( mDebugText ), "- Body=%s, Enabled=%d, Active=%d, Visible=%d, Bullet=%d, Awake=%d, CanSleep=%d",
  1515. pBodyType,
  1516. enabled,
  1517. active,
  1518. visible,
  1519. isBullet,
  1520. awake,
  1521. sleepingAllowed
  1522. );
  1523. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1524. linePositionY += linePositionOffsetY;
  1525. // SceneObject #3.
  1526. const Vector2 linearVelocity = pDebugSceneObject->getLinearVelocity();
  1527. const F32 angularVelocity = pDebugSceneObject->getAngularVelocity();
  1528. const F32 linearDamping = pDebugSceneObject->getLinearDamping();
  1529. const F32 angularDamping = pDebugSceneObject->getAngularDamping();
  1530. const Vector2 localCenter = pDebugSceneObject->getLocalCenter();
  1531. dSprintf( mDebugText, sizeof( mDebugText ), "- LinVel=(%0.3f,%0.3f), AngVel=%0.3f, LinDamp=%0.3f, AngDamp=%0.3f, Com=(%0.3f,%0.3f)",
  1532. linearVelocity.x, linearVelocity.y,
  1533. angularVelocity,
  1534. linearDamping,
  1535. angularDamping,
  1536. localCenter.x, localCenter.y
  1537. );
  1538. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1539. linePositionY += linePositionOffsetY;
  1540. // SceneObject #4.
  1541. const bool collisionSuppress = pDebugSceneObject->getCollisionSuppress();
  1542. const U32 collisionLayerMask = pDebugSceneObject->getCollisionLayerMask();
  1543. const U32 collisionGroupMask = pDebugSceneObject->getCollisionGroupMask();
  1544. const U32 collisionShapeCount = pDebugSceneObject->getCollisionShapeCount();
  1545. dSprintf( mDebugText, sizeof( mDebugText ), "- Shapes=%d, ColSuppress=%d, ColLayer=%0.8x, ColGroup=%0.8x",
  1546. collisionShapeCount,
  1547. collisionSuppress,
  1548. collisionLayerMask,
  1549. collisionGroupMask
  1550. );
  1551. dglDrawText( font, bannerOffset + Point2I(metricsOffset,(S32)linePositionY), mDebugText, NULL );
  1552. }
  1553. // Clear Bitmap Modulation.
  1554. dglClearBitmapModulation();
  1555. }