Camera.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. #include "stdafx.h"
  13. #include "Camera.h"
  14. class CCameraPos {
  15. public:
  16. TIME cp_tmTick;
  17. FLOAT cp_fSpeed;
  18. FLOAT3D cp_vPos;
  19. ANGLE3D cp_aRot;
  20. ANGLE cp_aFOV;
  21. };
  22. BOOL _bCameraOn=FALSE;
  23. CTFileStream _strScript;
  24. BOOL _bInitialized;
  25. FLOAT _fStartTime;
  26. CCameraPos _cp0;
  27. CCameraPos _cp1;
  28. CCameraPos _cp;
  29. // camera control
  30. extern INDEX cam_bRecord = FALSE;
  31. static INDEX cam_bMoveForward = FALSE;
  32. static INDEX cam_bMoveBackward = FALSE;
  33. static INDEX cam_bMoveLeft = FALSE;
  34. static INDEX cam_bMoveRight = FALSE;
  35. static INDEX cam_bMoveUp = FALSE;
  36. static INDEX cam_bMoveDown = FALSE;
  37. static INDEX cam_bTurnBankingLeft = FALSE;
  38. static INDEX cam_bTurnBankingRight = FALSE;
  39. static INDEX cam_bZoomIn = FALSE;
  40. static INDEX cam_bZoomOut = FALSE;
  41. static INDEX cam_bZoomDefault = FALSE;
  42. static INDEX cam_bResetToPlayer = FALSE;
  43. static INDEX cam_bSnapshot = FALSE;
  44. static INDEX cam_fSpeed = 1.0f;
  45. // camera functions
  46. void CAM_Init(void)
  47. {
  48. _pShell->DeclareSymbol("user INDEX cam_bRecord;", &cam_bRecord);
  49. _pShell->DeclareSymbol("user INDEX cam_bMoveForward;", &cam_bMoveForward);
  50. _pShell->DeclareSymbol("user INDEX cam_bMoveBackward;", &cam_bMoveBackward);
  51. _pShell->DeclareSymbol("user INDEX cam_bMoveLeft;", &cam_bMoveLeft);
  52. _pShell->DeclareSymbol("user INDEX cam_bMoveRight;", &cam_bMoveRight);
  53. _pShell->DeclareSymbol("user INDEX cam_bMoveUp;", &cam_bMoveUp);
  54. _pShell->DeclareSymbol("user INDEX cam_bMoveDown;", &cam_bMoveDown);
  55. _pShell->DeclareSymbol("user INDEX cam_bTurnBankingLeft;", &cam_bTurnBankingLeft);
  56. _pShell->DeclareSymbol("user INDEX cam_bTurnBankingRight;", &cam_bTurnBankingRight);
  57. _pShell->DeclareSymbol("user INDEX cam_bZoomIn;", &cam_bZoomIn);
  58. _pShell->DeclareSymbol("user INDEX cam_bZoomOut;", &cam_bZoomOut);
  59. _pShell->DeclareSymbol("user INDEX cam_bZoomDefault;", &cam_bZoomDefault);
  60. _pShell->DeclareSymbol("user INDEX cam_bSnapshot;", &cam_bSnapshot);
  61. _pShell->DeclareSymbol("user INDEX cam_bResetToPlayer;", &cam_bResetToPlayer);
  62. _pShell->DeclareSymbol("user INDEX cam_fSpeed;", &cam_fSpeed);
  63. }
  64. BOOL CAM_IsOn(void)
  65. {
  66. return _bCameraOn;
  67. }
  68. void ReadPos(CCameraPos &cp)
  69. {
  70. try {
  71. CTString strLine;
  72. _strScript.GetLine_t(strLine);
  73. strLine.ScanF("%g: %g: %g %g %g:%g %g %g:%g",
  74. &cp.cp_tmTick,
  75. &cp.cp_fSpeed,
  76. &cp.cp_vPos(1), &cp.cp_vPos(2), &cp.cp_vPos(3),
  77. &cp.cp_aRot(1), &cp.cp_aRot(2), &cp.cp_aRot(3),
  78. &cp.cp_aFOV);
  79. } catch (char *strError) {
  80. CPrintF("Camera: %s\n", strError);
  81. }
  82. }
  83. void WritePos(CCameraPos &cp)
  84. {
  85. try {
  86. CTString strLine;
  87. strLine.PrintF("%g: %g: %g %g %g:%g %g %g:%g",
  88. _pTimer->GetLerpedCurrentTick()-_fStartTime,
  89. 1.0f,
  90. cp.cp_vPos(1), cp.cp_vPos(2), cp.cp_vPos(3),
  91. cp.cp_aRot(1), cp.cp_aRot(2), cp.cp_aRot(3),
  92. cp.cp_aFOV);
  93. _strScript.PutLine_t(strLine);
  94. } catch (char *strError) {
  95. CPrintF("Camera: %s\n", strError);
  96. }
  97. }
  98. void SetSpeed(FLOAT fSpeed)
  99. {
  100. CTString str;
  101. str.PrintF("dem_fRealTimeFactor = %g;", fSpeed);
  102. _pShell->Execute(str);
  103. }
  104. void CAM_Start(const CTFileName &fnmDemo)
  105. {
  106. _bCameraOn = FALSE;
  107. CTFileName fnmScript = fnmDemo.NoExt()+".ini";
  108. if( cam_bRecord) {
  109. try {
  110. _strScript.Create_t(fnmScript);
  111. } catch(char *strError) {
  112. CPrintF("Camera: %s\n", strError);
  113. return;
  114. };
  115. _cp.cp_vPos = FLOAT3D(0,0,0);
  116. _cp.cp_aRot = ANGLE3D(0,0,0);
  117. _cp.cp_aFOV = 90.0f;
  118. _cp.cp_fSpeed = 1;
  119. _cp.cp_tmTick = 0.0f;
  120. } else {
  121. try {
  122. _strScript.Open_t(fnmScript);
  123. } catch(char *strError) {
  124. (void)strError;
  125. return;
  126. };
  127. }
  128. _bCameraOn = TRUE;
  129. _bInitialized = FALSE;
  130. }
  131. void CAM_Stop(void)
  132. {
  133. if (_bCameraOn) {
  134. _strScript.Close();
  135. }
  136. _bCameraOn = FALSE;
  137. }
  138. void CAM_Render(CEntity *pen, CDrawPort *pdp)
  139. {
  140. if( cam_bRecord) {
  141. if (!_bInitialized) {
  142. _bInitialized = TRUE;
  143. SetSpeed(1.0f);
  144. _fStartTime = _pTimer->CurrentTick();
  145. }
  146. FLOATmatrix3D m;
  147. MakeRotationMatrixFast(m, _cp.cp_aRot);
  148. FLOAT3D vX, vY, vZ;
  149. vX(1) = m(1,1); vX(2) = m(2,1); vX(3) = m(3,1);
  150. vY(1) = m(1,2); vY(2) = m(2,2); vY(3) = m(3,2);
  151. vZ(1) = m(1,3); vZ(2) = m(2,3); vZ(3) = m(3,3);
  152. _cp.cp_aRot(1)-=_pInput->GetAxisValue(MOUSE_X_AXIS)*0.5f;
  153. _cp.cp_aRot(2)-=_pInput->GetAxisValue(MOUSE_Y_AXIS)*0.5f;
  154. if( cam_bMoveForward) { _cp.cp_vPos -= vZ *cam_fSpeed; };
  155. if( cam_bMoveBackward) { _cp.cp_vPos += vZ *cam_fSpeed; };
  156. if( cam_bMoveLeft) { _cp.cp_vPos -= vX *cam_fSpeed; };
  157. if( cam_bMoveRight) { _cp.cp_vPos += vX *cam_fSpeed; };
  158. if( cam_bMoveUp) { _cp.cp_vPos += vY *cam_fSpeed; };
  159. if( cam_bMoveDown) { _cp.cp_vPos -= vY *cam_fSpeed; };
  160. if( cam_bTurnBankingLeft) { _cp.cp_aRot(3) += 10.0f; };
  161. if( cam_bTurnBankingRight) { _cp.cp_aRot(3) -= 10.0f; };
  162. if( cam_bZoomIn) { _cp.cp_aFOV -= 1.0f; };
  163. if( cam_bZoomOut) { _cp.cp_aFOV += 1.0f; };
  164. if( cam_bZoomDefault) { _cp.cp_aFOV = 90.0f; };
  165. Clamp( _cp.cp_aFOV, 10.0f, 150.0f);
  166. if( cam_bResetToPlayer) {
  167. _cp.cp_vPos = pen->GetPlacement().pl_PositionVector;
  168. _cp.cp_aRot = pen->GetPlacement().pl_OrientationAngle;
  169. }
  170. if( cam_bSnapshot) {
  171. cam_bSnapshot = FALSE;
  172. WritePos(_cp);
  173. }
  174. } else {
  175. if (!_bInitialized) {
  176. _bInitialized = TRUE;
  177. ReadPos(_cp0);
  178. ReadPos(_cp1);
  179. SetSpeed(_cp0.cp_fSpeed);
  180. _fStartTime = _pTimer->CurrentTick();
  181. }
  182. TIME tmNow = _pTimer->GetLerpedCurrentTick()-_fStartTime;
  183. if (tmNow>_cp1.cp_tmTick) {
  184. _cp0 = _cp1;
  185. ReadPos(_cp1);
  186. SetSpeed(_cp0.cp_fSpeed);
  187. }
  188. FLOAT fRatio = (tmNow-_cp0.cp_tmTick)/(_cp1.cp_tmTick-_cp0.cp_tmTick);
  189. _cp.cp_vPos = Lerp(_cp0.cp_vPos, _cp1.cp_vPos, fRatio);
  190. _cp.cp_aRot = Lerp(_cp0.cp_aRot, _cp1.cp_aRot, fRatio);
  191. _cp.cp_aFOV = Lerp(_cp0.cp_aFOV, _cp1.cp_aFOV, fRatio);
  192. }
  193. CPlacement3D plCamera;
  194. plCamera.pl_PositionVector = _cp.cp_vPos;
  195. plCamera.pl_OrientationAngle = _cp.cp_aRot;
  196. // init projection parameters
  197. CPerspectiveProjection3D prPerspectiveProjection;
  198. prPerspectiveProjection.FOVL() = _cp.cp_aFOV;
  199. prPerspectiveProjection.ScreenBBoxL() = FLOATaabbox2D(
  200. FLOAT2D(0.0f, 0.0f), FLOAT2D((float)pdp->GetWidth(), (float)pdp->GetHeight())
  201. );
  202. prPerspectiveProjection.AspectRatioL() = 1.0f;
  203. prPerspectiveProjection.FrontClipDistanceL() = 0.3f;
  204. CAnyProjection3D prProjection;
  205. prProjection = prPerspectiveProjection;
  206. // set up viewer position
  207. prProjection->ViewerPlacementL() = plCamera;
  208. // render the view
  209. RenderView(*pen->en_pwoWorld, *(CEntity*)NULL, prProjection, *pdp);
  210. }