Camera.cpp 19 KB

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