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"
|
|
|
|
#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
|
|
|
|
extern INDEX cam_bRecord = FALSE;
|
|
|
|
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.0f;
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|