Camera.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "Game_local.h"
  23. /*
  24. ===============================================================================
  25. idCamera
  26. Base class for cameras
  27. ===============================================================================
  28. */
  29. ABSTRACT_DECLARATION( idEntity, idCamera )
  30. END_CLASS
  31. /*
  32. =====================
  33. idCamera::Spawn
  34. =====================
  35. */
  36. void idCamera::Spawn( void ) {
  37. }
  38. /*
  39. =====================
  40. idCamera::GetRenderView
  41. =====================
  42. */
  43. renderView_t *idCamera::GetRenderView() {
  44. renderView_t *rv = idEntity::GetRenderView();
  45. GetViewParms( rv );
  46. return rv;
  47. }
  48. /***********************************************************************
  49. idCameraView
  50. ***********************************************************************/
  51. const idEventDef EV_Camera_SetAttachments( "<getattachments>", NULL );
  52. CLASS_DECLARATION( idCamera, idCameraView )
  53. EVENT( EV_Activate, idCameraView::Event_Activate )
  54. EVENT( EV_Camera_SetAttachments, idCameraView::Event_SetAttachments )
  55. END_CLASS
  56. /*
  57. ===============
  58. idCameraView::idCameraView
  59. ================
  60. */
  61. idCameraView::idCameraView() {
  62. fov = 90.0f;
  63. attachedTo = NULL;
  64. attachedView = NULL;
  65. }
  66. /*
  67. ===============
  68. idCameraView::Save
  69. ================
  70. */
  71. void idCameraView::Save( idSaveGame *savefile ) const {
  72. savefile->WriteFloat( fov );
  73. savefile->WriteObject( attachedTo );
  74. savefile->WriteObject( attachedView );
  75. }
  76. /*
  77. ===============
  78. idCameraView::Restore
  79. ================
  80. */
  81. void idCameraView::Restore( idRestoreGame *savefile ) {
  82. savefile->ReadFloat( fov );
  83. savefile->ReadObject( reinterpret_cast<idClass *&>( attachedTo ) );
  84. savefile->ReadObject( reinterpret_cast<idClass *&>( attachedView ) );
  85. }
  86. /*
  87. ===============
  88. idCameraView::Event_SetAttachments
  89. ================
  90. */
  91. void idCameraView::Event_SetAttachments( ) {
  92. SetAttachment( &attachedTo, "attachedTo" );
  93. SetAttachment( &attachedView, "attachedView" );
  94. }
  95. /*
  96. ===============
  97. idCameraView::Event_Activate
  98. ================
  99. */
  100. void idCameraView::Event_Activate( idEntity *activator ) {
  101. if (spawnArgs.GetBool("trigger")) {
  102. if (gameLocal.GetCamera() != this) {
  103. if ( g_debugCinematic.GetBool() ) {
  104. gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() );
  105. }
  106. gameLocal.SetCamera(this);
  107. } else {
  108. if ( g_debugCinematic.GetBool() ) {
  109. gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
  110. }
  111. gameLocal.SetCamera(NULL);
  112. }
  113. }
  114. }
  115. /*
  116. =====================
  117. idCameraView::Stop
  118. =====================
  119. */
  120. void idCameraView::Stop( void ) {
  121. if ( g_debugCinematic.GetBool() ) {
  122. gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
  123. }
  124. gameLocal.SetCamera(NULL);
  125. ActivateTargets( gameLocal.GetLocalPlayer() );
  126. }
  127. /*
  128. =====================
  129. idCameraView::Spawn
  130. =====================
  131. */
  132. void idCameraView::SetAttachment( idEntity **e, const char *p ) {
  133. const char *cam = spawnArgs.GetString( p );
  134. if ( strlen ( cam ) ) {
  135. *e = gameLocal.FindEntity( cam );
  136. }
  137. }
  138. /*
  139. =====================
  140. idCameraView::Spawn
  141. =====================
  142. */
  143. void idCameraView::Spawn( void ) {
  144. // if no target specified use ourself
  145. const char *cam = spawnArgs.GetString("cameraTarget");
  146. if ( strlen ( cam ) == 0) {
  147. spawnArgs.Set("cameraTarget", spawnArgs.GetString("name"));
  148. }
  149. fov = spawnArgs.GetFloat("fov", "90");
  150. PostEventMS( &EV_Camera_SetAttachments, 0 );
  151. UpdateChangeableSpawnArgs(NULL);
  152. }
  153. /*
  154. =====================
  155. idCameraView::GetViewParms
  156. =====================
  157. */
  158. void idCameraView::GetViewParms( renderView_t *view ) {
  159. assert( view );
  160. if (view == NULL) {
  161. return;
  162. }
  163. idVec3 dir;
  164. idEntity *ent;
  165. if ( attachedTo ) {
  166. ent = attachedTo;
  167. } else {
  168. ent = this;
  169. }
  170. view->vieworg = ent->GetPhysics()->GetOrigin();
  171. if ( attachedView ) {
  172. dir = attachedView->GetPhysics()->GetOrigin() - view->vieworg;
  173. dir.Normalize();
  174. view->viewaxis = dir.ToMat3();
  175. } else {
  176. view->viewaxis = ent->GetPhysics()->GetAxis();
  177. }
  178. gameLocal.CalcFov( fov, view->fov_x, view->fov_y );
  179. }
  180. /*
  181. ===============================================================================
  182. idCameraAnim
  183. ===============================================================================
  184. */
  185. const idEventDef EV_Camera_Start( "start", NULL );
  186. const idEventDef EV_Camera_Stop( "stop", NULL );
  187. CLASS_DECLARATION( idCamera, idCameraAnim )
  188. EVENT( EV_Thread_SetCallback, idCameraAnim::Event_SetCallback )
  189. EVENT( EV_Camera_Stop, idCameraAnim::Event_Stop )
  190. EVENT( EV_Camera_Start, idCameraAnim::Event_Start )
  191. EVENT( EV_Activate, idCameraAnim::Event_Activate )
  192. END_CLASS
  193. /*
  194. =====================
  195. idCameraAnim::idCameraAnim
  196. =====================
  197. */
  198. idCameraAnim::idCameraAnim() {
  199. threadNum = 0;
  200. offset.Zero();
  201. frameRate = 0;
  202. cycle = 1;
  203. starttime = 0;
  204. activator = NULL;
  205. }
  206. /*
  207. =====================
  208. idCameraAnim::~idCameraAnim
  209. =====================
  210. */
  211. idCameraAnim::~idCameraAnim() {
  212. if ( gameLocal.GetCamera() == this ) {
  213. gameLocal.SetCamera( NULL );
  214. }
  215. }
  216. /*
  217. ===============
  218. idCameraAnim::Save
  219. ================
  220. */
  221. void idCameraAnim::Save( idSaveGame *savefile ) const {
  222. savefile->WriteInt( threadNum );
  223. savefile->WriteVec3( offset );
  224. savefile->WriteInt( frameRate );
  225. savefile->WriteInt( starttime );
  226. savefile->WriteInt( cycle );
  227. activator.Save( savefile );
  228. }
  229. /*
  230. ===============
  231. idCameraAnim::Restore
  232. ================
  233. */
  234. void idCameraAnim::Restore( idRestoreGame *savefile ) {
  235. savefile->ReadInt( threadNum );
  236. savefile->ReadVec3( offset );
  237. savefile->ReadInt( frameRate );
  238. savefile->ReadInt( starttime );
  239. savefile->ReadInt( cycle );
  240. activator.Restore( savefile );
  241. LoadAnim();
  242. }
  243. /*
  244. =====================
  245. idCameraAnim::Spawn
  246. =====================
  247. */
  248. void idCameraAnim::Spawn( void ) {
  249. if ( spawnArgs.GetVector( "old_origin", "0 0 0", offset ) ) {
  250. offset = GetPhysics()->GetOrigin() - offset;
  251. } else {
  252. offset.Zero();
  253. }
  254. // always think during cinematics
  255. cinematic = true;
  256. LoadAnim();
  257. }
  258. /*
  259. ================
  260. idCameraAnim::Load
  261. ================
  262. */
  263. void idCameraAnim::LoadAnim( void ) {
  264. int version;
  265. idLexer parser( LEXFL_ALLOWPATHNAMES | LEXFL_NOSTRINGESCAPECHARS | LEXFL_NOSTRINGCONCAT );
  266. idToken token;
  267. int numFrames;
  268. int numCuts;
  269. int i;
  270. idStr filename;
  271. const char *key;
  272. key = spawnArgs.GetString( "anim" );
  273. if ( !key ) {
  274. gameLocal.Error( "Missing 'anim' key on '%s'", name.c_str() );
  275. }
  276. filename = spawnArgs.GetString( va( "anim %s", key ) );
  277. if ( !filename.Length() ) {
  278. gameLocal.Error( "Missing 'anim %s' key on '%s'", key, name.c_str() );
  279. }
  280. filename.SetFileExtension( MD5_CAMERA_EXT );
  281. if ( !parser.LoadFile( filename ) ) {
  282. gameLocal.Error( "Unable to load '%s' on '%s'", filename.c_str(), name.c_str() );
  283. }
  284. cameraCuts.Clear();
  285. cameraCuts.SetGranularity( 1 );
  286. camera.Clear();
  287. camera.SetGranularity( 1 );
  288. parser.ExpectTokenString( MD5_VERSION_STRING );
  289. version = parser.ParseInt();
  290. if ( version != MD5_VERSION ) {
  291. parser.Error( "Invalid version %d. Should be version %d\n", version, MD5_VERSION );
  292. }
  293. // skip the commandline
  294. parser.ExpectTokenString( "commandline" );
  295. parser.ReadToken( &token );
  296. // parse num frames
  297. parser.ExpectTokenString( "numFrames" );
  298. numFrames = parser.ParseInt();
  299. if ( numFrames <= 0 ) {
  300. parser.Error( "Invalid number of frames: %d", numFrames );
  301. }
  302. // parse framerate
  303. parser.ExpectTokenString( "frameRate" );
  304. frameRate = parser.ParseInt();
  305. if ( frameRate <= 0 ) {
  306. parser.Error( "Invalid framerate: %d", frameRate );
  307. }
  308. // parse num cuts
  309. parser.ExpectTokenString( "numCuts" );
  310. numCuts = parser.ParseInt();
  311. if ( ( numCuts < 0 ) || ( numCuts > numFrames ) ) {
  312. parser.Error( "Invalid number of camera cuts: %d", numCuts );
  313. }
  314. // parse the camera cuts
  315. parser.ExpectTokenString( "cuts" );
  316. parser.ExpectTokenString( "{" );
  317. cameraCuts.SetNum( numCuts );
  318. for( i = 0; i < numCuts; i++ ) {
  319. cameraCuts[ i ] = parser.ParseInt();
  320. if ( ( cameraCuts[ i ] < 1 ) || ( cameraCuts[ i ] >= numFrames ) ) {
  321. parser.Error( "Invalid camera cut" );
  322. }
  323. }
  324. parser.ExpectTokenString( "}" );
  325. // parse the camera frames
  326. parser.ExpectTokenString( "camera" );
  327. parser.ExpectTokenString( "{" );
  328. camera.SetNum( numFrames );
  329. for( i = 0; i < numFrames; i++ ) {
  330. parser.Parse1DMatrix( 3, camera[ i ].t.ToFloatPtr() );
  331. parser.Parse1DMatrix( 3, camera[ i ].q.ToFloatPtr() );
  332. camera[ i ].fov = parser.ParseFloat();
  333. }
  334. parser.ExpectTokenString( "}" );
  335. #if 0
  336. if ( !gameLocal.GetLocalPlayer() ) {
  337. return;
  338. }
  339. idDebugGraph gGraph;
  340. idDebugGraph tGraph;
  341. idDebugGraph qGraph;
  342. idDebugGraph dtGraph;
  343. idDebugGraph dqGraph;
  344. gGraph.SetNumSamples( numFrames );
  345. tGraph.SetNumSamples( numFrames );
  346. qGraph.SetNumSamples( numFrames );
  347. dtGraph.SetNumSamples( numFrames );
  348. dqGraph.SetNumSamples( numFrames );
  349. gameLocal.Printf( "\n\ndelta vec:\n" );
  350. float diff_t, last_t, t;
  351. float diff_q, last_q, q;
  352. diff_t = last_t = 0.0f;
  353. diff_q = last_q = 0.0f;
  354. for( i = 1; i < numFrames; i++ ) {
  355. t = ( camera[ i ].t - camera[ i - 1 ].t ).Length();
  356. q = ( camera[ i ].q.ToQuat() - camera[ i - 1 ].q.ToQuat() ).Length();
  357. diff_t = t - last_t;
  358. diff_q = q - last_q;
  359. gGraph.AddValue( ( i % 10 ) == 0 );
  360. tGraph.AddValue( t );
  361. qGraph.AddValue( q );
  362. dtGraph.AddValue( diff_t );
  363. dqGraph.AddValue( diff_q );
  364. gameLocal.Printf( "%d: %.8f : %.8f, %.8f : %.8f\n", i, t, diff_t, q, diff_q );
  365. last_t = t;
  366. last_q = q;
  367. }
  368. gGraph.Draw( colorBlue, 300.0f );
  369. tGraph.Draw( colorOrange, 60.0f );
  370. dtGraph.Draw( colorYellow, 6000.0f );
  371. qGraph.Draw( colorGreen, 60.0f );
  372. dqGraph.Draw( colorCyan, 6000.0f );
  373. #endif
  374. }
  375. /*
  376. ===============
  377. idCameraAnim::Start
  378. ================
  379. */
  380. void idCameraAnim::Start( void ) {
  381. cycle = spawnArgs.GetInt( "cycle" );
  382. if ( !cycle ) {
  383. cycle = 1;
  384. }
  385. if ( g_debugCinematic.GetBool() ) {
  386. gameLocal.Printf( "%d: '%s' start\n", gameLocal.framenum, GetName() );
  387. }
  388. starttime = gameLocal.time;
  389. gameLocal.SetCamera( this );
  390. BecomeActive( TH_THINK );
  391. // if the player has already created the renderview for this frame, have him update it again so that the camera starts this frame
  392. if ( gameLocal.GetLocalPlayer()->GetRenderView()->time == gameLocal.time ) {
  393. gameLocal.GetLocalPlayer()->CalculateRenderView();
  394. }
  395. }
  396. /*
  397. =====================
  398. idCameraAnim::Stop
  399. =====================
  400. */
  401. void idCameraAnim::Stop( void ) {
  402. if ( gameLocal.GetCamera() == this ) {
  403. if ( g_debugCinematic.GetBool() ) {
  404. gameLocal.Printf( "%d: '%s' stop\n", gameLocal.framenum, GetName() );
  405. }
  406. BecomeInactive( TH_THINK );
  407. gameLocal.SetCamera( NULL );
  408. if ( threadNum ) {
  409. idThread::ObjectMoveDone( threadNum, this );
  410. threadNum = 0;
  411. }
  412. ActivateTargets( activator.GetEntity() );
  413. }
  414. }
  415. /*
  416. =====================
  417. idCameraAnim::Think
  418. =====================
  419. */
  420. void idCameraAnim::Think( void ) {
  421. int frame;
  422. int frameTime;
  423. if ( thinkFlags & TH_THINK ) {
  424. // check if we're done in the Think function when the cinematic is being skipped (idCameraAnim::GetViewParms isn't called when skipping cinematics).
  425. if ( !gameLocal.skipCinematic ) {
  426. return;
  427. }
  428. if ( camera.Num() < 2 ) {
  429. // 1 frame anims never end
  430. return;
  431. }
  432. if ( frameRate == USERCMD_HZ ) {
  433. frameTime = gameLocal.time - starttime;
  434. frame = frameTime / gameLocal.msec;
  435. } else {
  436. frameTime = ( gameLocal.time - starttime ) * frameRate;
  437. frame = frameTime / 1000;
  438. }
  439. if ( frame > camera.Num() + cameraCuts.Num() - 2 ) {
  440. if ( cycle > 0 ) {
  441. cycle--;
  442. }
  443. if ( cycle != 0 ) {
  444. // advance start time so that we loop
  445. starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate;
  446. } else {
  447. Stop();
  448. }
  449. }
  450. }
  451. }
  452. /*
  453. =====================
  454. idCameraAnim::GetViewParms
  455. =====================
  456. */
  457. void idCameraAnim::GetViewParms( renderView_t *view ) {
  458. int realFrame;
  459. int frame;
  460. int frameTime;
  461. float lerp;
  462. float invlerp;
  463. cameraFrame_t *camFrame;
  464. int i;
  465. int cut;
  466. idQuat q1, q2, q3;
  467. assert( view );
  468. if ( !view ) {
  469. return;
  470. }
  471. if ( camera.Num() == 0 ) {
  472. // we most likely are in the middle of a restore
  473. // FIXME: it would be better to fix it so this doesn't get called during a restore
  474. return;
  475. }
  476. if ( frameRate == USERCMD_HZ ) {
  477. frameTime = gameLocal.time - starttime;
  478. frame = frameTime / gameLocal.msec;
  479. lerp = 0.0f;
  480. } else {
  481. frameTime = ( gameLocal.time - starttime ) * frameRate;
  482. frame = frameTime / 1000;
  483. lerp = ( frameTime % 1000 ) * 0.001f;
  484. }
  485. // skip any frames where camera cuts occur
  486. realFrame = frame;
  487. cut = 0;
  488. for( i = 0; i < cameraCuts.Num(); i++ ) {
  489. if ( frame < cameraCuts[ i ] ) {
  490. break;
  491. }
  492. frame++;
  493. cut++;
  494. }
  495. if ( g_debugCinematic.GetBool() ) {
  496. int prevFrameTime = ( gameLocal.time - starttime - gameLocal.msec ) * frameRate;
  497. int prevFrame = prevFrameTime / 1000;
  498. int prevCut;
  499. prevCut = 0;
  500. for( i = 0; i < cameraCuts.Num(); i++ ) {
  501. if ( prevFrame < cameraCuts[ i ] ) {
  502. break;
  503. }
  504. prevFrame++;
  505. prevCut++;
  506. }
  507. if ( prevCut != cut ) {
  508. gameLocal.Printf( "%d: '%s' cut %d\n", gameLocal.framenum, GetName(), cut );
  509. }
  510. }
  511. // clamp to the first frame. also check if this is a one frame anim. one frame anims would end immediately,
  512. // but since they're mainly used for static cams anyway, just stay on it infinitely.
  513. if ( ( frame < 0 ) || ( camera.Num() < 2 ) ) {
  514. view->viewaxis = camera[ 0 ].q.ToQuat().ToMat3();
  515. view->vieworg = camera[ 0 ].t + offset;
  516. view->fov_x = camera[ 0 ].fov;
  517. } else if ( frame > camera.Num() - 2 ) {
  518. if ( cycle > 0 ) {
  519. cycle--;
  520. }
  521. if ( cycle != 0 ) {
  522. // advance start time so that we loop
  523. starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate;
  524. GetViewParms( view );
  525. return;
  526. }
  527. Stop();
  528. if ( gameLocal.GetCamera() != NULL ) {
  529. // we activated another camera when we stopped, so get it's viewparms instead
  530. gameLocal.GetCamera()->GetViewParms( view );
  531. return;
  532. } else {
  533. // just use our last frame
  534. camFrame = &camera[ camera.Num() - 1 ];
  535. view->viewaxis = camFrame->q.ToQuat().ToMat3();
  536. view->vieworg = camFrame->t + offset;
  537. view->fov_x = camFrame->fov;
  538. }
  539. } else if ( lerp == 0.0f ) {
  540. camFrame = &camera[ frame ];
  541. view->viewaxis = camFrame[ 0 ].q.ToMat3();
  542. view->vieworg = camFrame[ 0 ].t + offset;
  543. view->fov_x = camFrame[ 0 ].fov;
  544. } else {
  545. camFrame = &camera[ frame ];
  546. invlerp = 1.0f - lerp;
  547. q1 = camFrame[ 0 ].q.ToQuat();
  548. q2 = camFrame[ 1 ].q.ToQuat();
  549. q3.Slerp( q1, q2, lerp );
  550. view->viewaxis = q3.ToMat3();
  551. view->vieworg = camFrame[ 0 ].t * invlerp + camFrame[ 1 ].t * lerp + offset;
  552. view->fov_x = camFrame[ 0 ].fov * invlerp + camFrame[ 1 ].fov * lerp;
  553. }
  554. gameLocal.CalcFov( view->fov_x, view->fov_x, view->fov_y );
  555. // setup the pvs for this frame
  556. UpdatePVSAreas( view->vieworg );
  557. #if 0
  558. static int lastFrame = 0;
  559. static idVec3 lastFrameVec( 0.0f, 0.0f, 0.0f );
  560. if ( gameLocal.time != lastFrame ) {
  561. gameRenderWorld->DebugBounds( colorCyan, idBounds( view->vieworg ).Expand( 16.0f ), vec3_origin, gameLocal.msec );
  562. gameRenderWorld->DebugLine( colorRed, view->vieworg, view->vieworg + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false );
  563. gameRenderWorld->DebugLine( colorCyan, lastFrameVec, view->vieworg, 10000, false );
  564. gameRenderWorld->DebugLine( colorYellow, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 66.0f, 10000, false );
  565. gameRenderWorld->DebugLine( colorOrange, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 64.0f + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false );
  566. lastFrameVec = view->vieworg;
  567. lastFrame = gameLocal.time;
  568. }
  569. #endif
  570. if ( g_showcamerainfo.GetBool() ) {
  571. gameLocal.Printf( "^5Frame: ^7%d/%d\n\n\n", realFrame + 1, camera.Num() - cameraCuts.Num() );
  572. }
  573. }
  574. /*
  575. ===============
  576. idCameraAnim::Event_Activate
  577. ================
  578. */
  579. void idCameraAnim::Event_Activate( idEntity *_activator ) {
  580. activator = _activator;
  581. if ( thinkFlags & TH_THINK ) {
  582. Stop();
  583. } else {
  584. Start();
  585. }
  586. }
  587. /*
  588. ===============
  589. idCameraAnim::Event_Start
  590. ================
  591. */
  592. void idCameraAnim::Event_Start( void ) {
  593. Start();
  594. }
  595. /*
  596. ===============
  597. idCameraAnim::Event_Stop
  598. ================
  599. */
  600. void idCameraAnim::Event_Stop( void ) {
  601. Stop();
  602. }
  603. /*
  604. ================
  605. idCameraAnim::Event_SetCallback
  606. ================
  607. */
  608. void idCameraAnim::Event_SetCallback( void ) {
  609. if ( ( gameLocal.GetCamera() == this ) && !threadNum ) {
  610. threadNum = idThread::CurrentThreadNum();
  611. idThread::ReturnInt( true );
  612. } else {
  613. idThread::ReturnInt( false );
  614. }
  615. }