Serious-Engine/Sources/GameMP/Camera.cpp

235 lines
7.3 KiB
C++
Raw Permalink Normal View History

2016-03-12 01:20:51 +01:00
/* Copyright (c) 2002-2012 Croteam Ltd.
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License as published by
the Free Software Foundation
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
2016-03-11 14:57:17 +01:00
#include "StdAfx.h"
2016-03-11 14:57:17 +01:00
#include "Camera.h"
class CCameraPos {
public:
TIME cp_tmTick;
FLOAT cp_fSpeed;
FLOAT3D cp_vPos;
ANGLE3D cp_aRot;
ANGLE cp_aFOV;
};
BOOL _bCameraOn=FALSE;
CTFileStream _strScript;
BOOL _bInitialized;
FLOAT _fStartTime;
CCameraPos _cp0;
CCameraPos _cp1;
CCameraPos _cp;
// camera control
INDEX cam_bRecord = FALSE;
2016-03-11 14:57:17 +01:00
static INDEX cam_bMoveForward = FALSE;
static INDEX cam_bMoveBackward = FALSE;
static INDEX cam_bMoveLeft = FALSE;
static INDEX cam_bMoveRight = FALSE;
static INDEX cam_bMoveUp = FALSE;
static INDEX cam_bMoveDown = FALSE;
static INDEX cam_bTurnBankingLeft = FALSE;
static INDEX cam_bTurnBankingRight = FALSE;
static INDEX cam_bZoomIn = FALSE;
static INDEX cam_bZoomOut = FALSE;
static INDEX cam_bZoomDefault = FALSE;
static INDEX cam_bResetToPlayer = FALSE;
static INDEX cam_bSnapshot = FALSE;
static INDEX cam_fSpeed = 1;
2016-03-11 14:57:17 +01:00
// camera functions
void CAM_Init(void)
{
_pShell->DeclareSymbol("user INDEX cam_bRecord;", &cam_bRecord);
_pShell->DeclareSymbol("user INDEX cam_bMoveForward;", &cam_bMoveForward);
_pShell->DeclareSymbol("user INDEX cam_bMoveBackward;", &cam_bMoveBackward);
_pShell->DeclareSymbol("user INDEX cam_bMoveLeft;", &cam_bMoveLeft);
_pShell->DeclareSymbol("user INDEX cam_bMoveRight;", &cam_bMoveRight);
_pShell->DeclareSymbol("user INDEX cam_bMoveUp;", &cam_bMoveUp);
_pShell->DeclareSymbol("user INDEX cam_bMoveDown;", &cam_bMoveDown);
_pShell->DeclareSymbol("user INDEX cam_bTurnBankingLeft;", &cam_bTurnBankingLeft);
_pShell->DeclareSymbol("user INDEX cam_bTurnBankingRight;", &cam_bTurnBankingRight);
_pShell->DeclareSymbol("user INDEX cam_bZoomIn;", &cam_bZoomIn);
_pShell->DeclareSymbol("user INDEX cam_bZoomOut;", &cam_bZoomOut);
_pShell->DeclareSymbol("user INDEX cam_bZoomDefault;", &cam_bZoomDefault);
_pShell->DeclareSymbol("user INDEX cam_bSnapshot;", &cam_bSnapshot);
_pShell->DeclareSymbol("user INDEX cam_bResetToPlayer;", &cam_bResetToPlayer);
_pShell->DeclareSymbol("user INDEX cam_fSpeed;", &cam_fSpeed);
}
BOOL CAM_IsOn(void)
{
return _bCameraOn;
}
void ReadPos(CCameraPos &cp)
{
try {
CTString strLine;
_strScript.GetLine_t(strLine);
strLine.ScanF("%g: %g: %g %g %g:%g %g %g:%g",
&cp.cp_tmTick,
&cp.cp_fSpeed,
&cp.cp_vPos(1), &cp.cp_vPos(2), &cp.cp_vPos(3),
&cp.cp_aRot(1), &cp.cp_aRot(2), &cp.cp_aRot(3),
&cp.cp_aFOV);
} catch (char *strError) {
CPrintF("Camera: %s\n", strError);
}
}
void WritePos(CCameraPos &cp)
{
try {
CTString strLine;
strLine.PrintF("%g: %g: %g %g %g:%g %g %g:%g",
_pTimer->GetLerpedCurrentTick()-_fStartTime,
1.0f,
cp.cp_vPos(1), cp.cp_vPos(2), cp.cp_vPos(3),
cp.cp_aRot(1), cp.cp_aRot(2), cp.cp_aRot(3),
cp.cp_aFOV);
_strScript.PutLine_t(strLine);
} catch (char *strError) {
CPrintF("Camera: %s\n", strError);
}
}
void SetSpeed(FLOAT fSpeed)
{
CTString str;
str.PrintF("dem_fRealTimeFactor = %g;", fSpeed);
_pShell->Execute(str);
}
void CAM_Start(const CTFileName &fnmDemo)
{
_bCameraOn = FALSE;
CTFileName fnmScript = fnmDemo.NoExt()+".ini";
if( cam_bRecord) {
try {
_strScript.Create_t(fnmScript);
} catch(char *strError) {
CPrintF("Camera: %s\n", strError);
return;
};
_cp.cp_vPos = FLOAT3D(0,0,0);
_cp.cp_aRot = ANGLE3D(0,0,0);
_cp.cp_aFOV = 90.0f;
_cp.cp_fSpeed = 1;
_cp.cp_tmTick = 0.0f;
} else {
try {
_strScript.Open_t(fnmScript);
} catch(char *strError) {
(void)strError;
return;
};
}
_bCameraOn = TRUE;
_bInitialized = FALSE;
}
void CAM_Stop(void)
{
if (_bCameraOn) {
_strScript.Close();
}
_bCameraOn = FALSE;
}
void CAM_Render(CEntity *pen, CDrawPort *pdp)
{
if( cam_bRecord) {
if (!_bInitialized) {
_bInitialized = TRUE;
SetSpeed(1.0f);
_fStartTime = _pTimer->CurrentTick();
}
FLOATmatrix3D m;
MakeRotationMatrixFast(m, _cp.cp_aRot);
FLOAT3D vX, vY, vZ;
vX(1) = m(1,1); vX(2) = m(2,1); vX(3) = m(3,1);
vY(1) = m(1,2); vY(2) = m(2,2); vY(3) = m(3,2);
vZ(1) = m(1,3); vZ(2) = m(2,3); vZ(3) = m(3,3);
_cp.cp_aRot(1)-=_pInput->GetAxisValue(MOUSE_X_AXIS)*0.5f;
_cp.cp_aRot(2)-=_pInput->GetAxisValue(MOUSE_Y_AXIS)*0.5f;
if( cam_bMoveForward) { _cp.cp_vPos -= vZ *cam_fSpeed; };
if( cam_bMoveBackward) { _cp.cp_vPos += vZ *cam_fSpeed; };
if( cam_bMoveLeft) { _cp.cp_vPos -= vX *cam_fSpeed; };
if( cam_bMoveRight) { _cp.cp_vPos += vX *cam_fSpeed; };
if( cam_bMoveUp) { _cp.cp_vPos += vY *cam_fSpeed; };
if( cam_bMoveDown) { _cp.cp_vPos -= vY *cam_fSpeed; };
if( cam_bTurnBankingLeft) { _cp.cp_aRot(3) += 10.0f; };
if( cam_bTurnBankingRight) { _cp.cp_aRot(3) -= 10.0f; };
if( cam_bZoomIn) { _cp.cp_aFOV -= 1.0f; };
if( cam_bZoomOut) { _cp.cp_aFOV += 1.0f; };
if( cam_bZoomDefault) { _cp.cp_aFOV = 90.0f; };
Clamp( _cp.cp_aFOV, 10.0f, 150.0f);
if( cam_bResetToPlayer) {
_cp.cp_vPos = pen->GetPlacement().pl_PositionVector;
_cp.cp_aRot = pen->GetPlacement().pl_OrientationAngle;
}
if( cam_bSnapshot) {
cam_bSnapshot = FALSE;
WritePos(_cp);
}
} else {
if (!_bInitialized) {
_bInitialized = TRUE;
ReadPos(_cp0);
ReadPos(_cp1);
SetSpeed(_cp0.cp_fSpeed);
_fStartTime = _pTimer->CurrentTick();
}
TIME tmNow = _pTimer->GetLerpedCurrentTick()-_fStartTime;
if (tmNow>_cp1.cp_tmTick) {
_cp0 = _cp1;
ReadPos(_cp1);
SetSpeed(_cp0.cp_fSpeed);
}
FLOAT fRatio = (tmNow-_cp0.cp_tmTick)/(_cp1.cp_tmTick-_cp0.cp_tmTick);
_cp.cp_vPos = Lerp(_cp0.cp_vPos, _cp1.cp_vPos, fRatio);
_cp.cp_aRot = Lerp(_cp0.cp_aRot, _cp1.cp_aRot, fRatio);
_cp.cp_aFOV = Lerp(_cp0.cp_aFOV, _cp1.cp_aFOV, fRatio);
}
CPlacement3D plCamera;
plCamera.pl_PositionVector = _cp.cp_vPos;
plCamera.pl_OrientationAngle = _cp.cp_aRot;
// init projection parameters
CPerspectiveProjection3D prPerspectiveProjection;
prPerspectiveProjection.FOVL() = _cp.cp_aFOV;
prPerspectiveProjection.ScreenBBoxL() = FLOATaabbox2D(
FLOAT2D(0.0f, 0.0f), FLOAT2D((float)pdp->GetWidth(), (float)pdp->GetHeight())
);
prPerspectiveProjection.AspectRatioL() = 1.0f;
prPerspectiveProjection.FrontClipDistanceL() = 0.3f;
CAnyProjection3D prProjection;
prProjection = prPerspectiveProjection;
// set up viewer position
prProjection->ViewerPlacementL() = plCamera;
// render the view
RenderView(*pen->en_pwoWorld, *(CEntity*)NULL, prProjection, *pdp);
}