📄 ccameracontrol.cpp
字号:
/*
* ============================================================================
* Name : CCameraControl.cpp:
* Part of : Game
* Created : 2004-10-26 by Yi Wen Hu
* Implementation notes:
*
* Version :
* Copyright: Gameloft S.A.
*
* ============================================================================
*/
#include "CCameraControl.h"
#include "CScene.h"
#include "CPlayer.h"
#include "CBall.h"
#include "..\System\IMath.h"
#include "..\System\Sysdef.h"
#include "CTenpin.h"
#include "def.h"
#include "..\3d\render3d.h"
#include "..\System\engine.h"
#include "..\System\resfile.h"
#include ".\cid.h"
//add lane setting here
CCameraControl::CCameraControl(CScene* pScene)
{
m_pScene=pScene;
m_pCameraCombinations=NULL;
m_pCurStage=NULL;
m_iCmbsCount=0;
m_iCombIndex=0;
m_iStageIndex=0;
m_iTimer=0;
m_pStagesCount=NULL;
m_bFinished=true;
m_iCurCombIndex=0;
m_iCurStageIndex=0;
m_eye = Vector4s(0,-370,200,0);
m_lookat = Vector4s(0,100,0,0);
bReplay_NotRenderActor = false;
}
CCameraControl::~CCameraControl()
{
m_pScene=NULL;
m_pCurStage=NULL;
for(int i=0;i<m_iCmbsCount;i++)
delete [] m_pCameraCombinations[i];
delete [] m_pCameraCombinations;
delete [] m_pStagesCount;
}
/*
* =============================================================
* Name : bool CCameraControl::Load(CEngine *pEngine)
* Parameter : pEngine: point to CEngine
* Return : false: cannot find the file;
true: load success
* Implementation:
* read camera stage and combination from camera.cam
*
* =============================================================
*/
bool CCameraControl::Load(CEngine *pEngine)
{
char CAMERA_CONT_FILE[]="res\\camera.cam";
CResFile *pRes = pEngine->GetRes();
void *pFile;
int rest_size = pRes->LoadFileToStack(CAMERA_CONT_FILE,&pFile);
CBufReader pData;
if( pFile )
{
pData.CBufReader_init( pFile, rest_size);
}
else
return false;
// begin read data
// m_fileflag = pData.ReadChar();
m_iCmbsCount=pData.ReadInt();
m_pStagesCount=new int[m_iCmbsCount];
m_pCameraCombinations=new CCameraStage*[m_iCmbsCount];
int i,j,k;
for(i=0;i<m_iCmbsCount;i++)
{
m_pStagesCount[i]=pData.ReadInt();
m_pCameraCombinations[i]=new CCameraStage[m_pStagesCount[i]];
for(j=0;j<m_pStagesCount[i];j++)
{
CCameraStage* pCam;
pCam=&(m_pCameraCombinations[i][j]);
pCam->iControlType=pData.ReadInt();
pCam->iTotalTime=pData.ReadInt();
pCam->iPosRefer=pData.ReadInt();
pCam->iPosContStyle=pData.ReadInt();
pCam->iLookatRefer=pData.ReadInt();
pCam->iLookatContStyle=pData.ReadInt();
pCam->iStartRate=pData.ReadInt();
pCam->iEndRate=pData.ReadInt();
// DBGPRINTF("StartRate:%d EndRate:%d",pCam->iStartRate,pCam->iEndRate);
for(k=0;k<3;k++)
pCam->iStartPos[k]=pData.ReadInt();
for(k=0;k<3;k++)
pCam->iStartLookat[k]=pData.ReadInt();
for(k=0;k<2;k++)
pCam->iStartUp[k]=pData.ReadInt();
for(k=0;k<3;k++)
pCam->iEndPos[k]=pData.ReadInt();
for(k=0;k<3;k++)
pCam->iEndLookat[k]=pData.ReadInt();
for(k=0;k<2;k++)
pCam->iEndUp[k]=pData.ReadInt();
}
}
// finish read data
// Test();
pFile = NULL;
pEngine->GetMem()->StackFree(0);
return true;
}
/*
* =============================================================
* Name : bool CCameraControl::SetCamera(int id)
* Parameter : id: camera combination id of replay
* Return : false: invalid id; true: ok
* Implementation:
* Set current camera combination, it is called when
* replay.
*
* =============================================================
*/
bool CCameraControl::SetCamera(int id)
{
/*
if(m_bReplay==false)
return false;
*/
if(id<0 || id>=CCI_COUNT)
return false;
m_iCurCombIndex=id;
//Qiu Li, don't render actor for camera will move through actor 2005/1/14
if( m_bReplay )
{
if( id == CCI_CHASING || id == CCI_LOWBACKSIDE )
{
bReplay_NotRenderActor = true;
}
else
bReplay_NotRenderActor = false;
}
else
bReplay_NotRenderActor = false;
//Qiu Li
if(id==CCS_CAMERAVIEW)
{
// m_origin=m_viewMat;
m_origin.LookAt(Vector4s(0,0,150),Vector4s(0,100,0),Vector4s(0,0,100));
m_VerMat.LoadIdentity();
m_HorMat.LoadIdentity();
CompMatrix();
}
return true;
}
bool CCameraControl::NeedRemoveActor()
{
if( m_bReplay )
return bReplay_NotRenderActor;
else
return false;
}
/*
* =============================================================
* Name : bool CCameraControl::CallCamera(int id)
* Parameter : id: camera combination id
* Return : false: invalid combination id
* Implementation:
* Set camera combination id and current stage.
*
* =============================================================
*/
bool CCameraControl::CallCamera(int id)
// TIME: set all parameters, startrate=0, endrate=totaltime
// DISTANCE: set all parameters, startrate=current ball's y coord
// STATIC: set start value
// CONSTANT: do not need set any value
// MENTAL: similar with CONSTANT
{
// DBGPRINTF("CallCameraCombination=%d CmbsCount=%d \n",id,m_iCmbsCount);
if(id<0 || id >= m_iCmbsCount)return false;
// DBGPRINTF("BALL: %d %d %d\n",m_pScene->m_ball.GetPosition().x,
// m_pScene->m_ball.GetPosition().y,m_pScene->m_ball.GetPosition().z);
// DBGPRINTF("PLAYER: %d %d %d\n",m_pScene->m_player.GetPosition().x,
// m_pScene->m_player.GetPosition().y,m_pScene->m_player.GetPosition().z);
m_iCombIndex=id;
m_iStageIndex=0;
if( !m_bReplay || ( m_bReplay && m_iCurStageIndex != CCSS_THROW ))
m_iTimer=0;
m_bFinished=false;
m_pCurStage=&m_pCameraCombinations[m_iCombIndex][m_iStageIndex];
//replay, throw
if( m_bReplay && m_iCurStageIndex == CCSS_THROW && m_pCurStage->iControlType == CCSCT_TIME )
{
if( m_iTimer >= m_pCurStage->iTotalTime && m_iStageIndex < m_pStagesCount[m_iCombIndex]-1)
{
m_iStageIndex++;
m_pCurStage=&m_pCameraCombinations[m_iCombIndex][m_iStageIndex];
}
}
if(m_pCurStage->iControlType==CCSCT_DISTANCE)
if(-1==m_pCurStage->iStartRate)
m_pCurStage->iStartRate=m_pScene->m_ball.GetPosition().y;
return true;
}
bool CCameraControl::IsNeedRollback(int *y)
{
if( bNeedRollbackInReplay )
*y = iRollbackY;
return bNeedRollbackInReplay;
}
void CCameraControl::PreviousStageInReplay()
{
if(m_iStageIndex<=0)
return;
m_iStageIndex--;
m_pCurStage=&m_pCameraCombinations[m_iCombIndex][m_iStageIndex];
if(m_pCurStage->iControlType==CCSCT_DISTANCE)
if(-1==m_pCurStage->iStartRate)
m_pCurStage->iStartRate=m_pScene->m_ball.GetPosition().y;
bNeedRollbackInReplay = false;
return;
}
void CCameraControl::CheckCameraStage(void)
{
if(m_iStageIndex<m_pStagesCount[m_iCombIndex]-1)
{
if( m_pScene->m_ball.GetPosition().y >= m_pCurStage->iEndRate )
{
bNeedRollbackInReplay = true;
iRollbackY = m_pCurStage->iEndRate;
m_iStageIndex++;
m_pCurStage=&m_pCameraCombinations[m_iCombIndex][m_iStageIndex];
if(m_pCurStage->iControlType==CCSCT_DISTANCE)
if(-1==m_pCurStage->iStartRate)
m_pCurStage->iStartRate=m_pScene->m_ball.GetPosition().y;
}
}
}
/*
* =============================================================
* Name : void CCameraControl::NextStage()
* Parameter : none
* Implementation:
* Switch to next stage of the combination. Since process
* of THROW, FOUL_L, FOUL_R and INTRODUNTION are cut into three
* steps(combinations), get a random number and switch to next
* by calling CallCamera().
*
* =============================================================
*/
void CCameraControl::NextStage()
{
if(m_iStageIndex>=m_pStagesCount[m_iCombIndex]-1)
{
//change to next throw step
if( !m_bReplay && m_iCurStageIndex == CCSS_THROW )
{
int i;
switch( iThrowStep )
{
case 1:
if( m_iCombIndex < IDC_THROW_FWD_LOW_UP )
{
i = getRandomNumber(CC_TRW_STEP2_COUNT-1);
CallCamera(i+IDC_THROW_FWD_LF_2);
}
else if( m_iCombIndex < IDC_THROW_FWD_HIGH ) //low camera
{
i = getRandomNumber(TRW_STEP2_COMMON+TRW_STEP2_LOW-1);
CallCamera(i+IDC_THROW_FWD_LF_2);
}
else if( m_iCombIndex == IDC_THROW_FWD_HIGH ) //high camera
{
i = getRandomNumber(TRW_STEP2_COMMON+TRW_STEP2_HIGH-1);
if( i < TRW_STEP2_COMMON )
CallCamera(i+IDC_THROW_FWD_LF_2);
else{
i -= TRW_STEP2_COMMON;
CallCamera(i+IDC_THROW_FWD_LF_2+TRW_STEP2_COMMON+TRW_STEP2_LOW);
}
}
else
{
//error
SYS_ASSERT( m_iCombIndex <= IDC_THROW_FWD_HIGH);
}
iThrowStep = 2;
break;
case 2:
i = getRandomNumber(CC_TRW_STEP3_COUNT-1);
CallCamera(i+IDC_THROW_FWD_LF_3);
iThrowStep = 3;
break;
case 3:
default:
iThrowStep = 0;
m_bFinished=true;
m_iCombIndex=0;
m_iStageIndex=0;
break;
}
}
else if( m_iCurStageIndex == CCSS_FOUL_L || m_iCurStageIndex == CCSS_FOUL_R )
{
int i;
switch( iFoulStep )
{
case 1:
if( m_iCombIndex < IDC_THROW_FWD_LOW_UP )
{
i = getRandomNumber(CC_TRW_STEP2_COUNT-1);
CallCamera(i+IDC_THROW_FWD_LF_2);
}
else if( m_iCombIndex < IDC_THROW_FWD_HIGH ) //low camera
{
i = getRandomNumber(TRW_STEP2_COMMON+TRW_STEP2_LOW-1);
CallCamera(i+IDC_THROW_FWD_LF_2);
}
else if( m_iCombIndex == IDC_THROW_FWD_HIGH ) //high camera
{
i = getRandomNumber(TRW_STEP2_COMMON+TRW_STEP2_HIGH-1);
if( i < TRW_STEP2_COMMON )
CallCamera(i+IDC_THROW_FWD_LF_2);
else{
i -= TRW_STEP2_COMMON;
CallCamera(i+IDC_THROW_FWD_LF_2+TRW_STEP2_COMMON+TRW_STEP2_LOW);
}
}
else
{
//error
SYS_ASSERT( m_iCombIndex <= IDC_THROW_FWD_HIGH);
}
iFoulStep = 2;
break;
case 2:
if( m_iCurStageIndex == CCSS_FOUL_L )
CallCamera(IDC_THROW_L_FOUL);
else
CallCamera(IDC_THROW_R_FOUL);
iFoulStep = 3;
break;
case 3:
default:
iFoulStep = 0;
m_bFinished=true;
m_iCombIndex=0;
m_iStageIndex=0;
break;
}
}
else if( m_iCurStageIndex == CCSS_INTRODUCTION )
{
int i;
switch( iCameraViewStep )
{
case 1:
i = getRandomNumber(CAMERAVIEW_ROT-1);
CallCamera(IDC_CENTERROTATE_ROT1+i);
iCameraViewStep = 2;
break;
case 2:
i = getRandomNumber(CAMERAVIEW_SIDE-1);
CallCamera(IDC_CENTERROTATE_LF+i);
iCameraViewStep = 3;
break;
case 3:
default:
iCameraViewStep = 0;
m_bFinished=true;
m_iCombIndex=0;
m_iStageIndex=0;
break;
}
}
else{
m_bFinished=true;
m_iCombIndex=0;
m_iStageIndex=0;
}
return;
}
if( m_bReplay )
{
bNeedRollbackInReplay = true;
iRollbackY = m_pCurStage->iEndRate;
}
m_iStageIndex++;
m_pCurStage=&m_pCameraCombinations[m_iCombIndex][m_iStageIndex];
if(m_pCurStage->iControlType==CCSCT_DISTANCE)
if(-1==m_pCurStage->iStartRate)
m_pCurStage->iStartRate=m_pScene->m_ball.GetPosition().y;
m_iTimer=0;
}
/*
* =============================================================
* Name : void CCameraControl::UpdateCamera()
* Parameter : none
* Implementation:
* Update camera position and lookat
*
* =============================================================
*/
void CCameraControl::UpdateCamera(int replaytimer)
{
// TIME: interpolate by time
// DISTANCE: interpolate by ball's y coord
// STATIC: keep start value
// CONSTANT: do nothing, keep current camera
// MENTAL: do nothing
int curPos[3];
int curLookat[3];
int curUp[2];
int startRate,endRate,interRate;
int ref[3],ref2[3];
/*
DBGPRINTF("================================");
DBGPRINTF("CamControl,finished=%d comb=%d, stage=%d, curStage=%d\n",m_bFinished,m_iCombIndex,m_iStageIndex,m_pScene->m_curStage);
DBGPRINTF("CAMERA:%d %d %d, %d %d %d, %d %d %d\n",m_eye.x, m_eye.y, m_eye.z,
m_lookat.x, m_lookat.y, m_lookat.z, m_up.x, m_up.y, m_up.z);
DBGPRINTF("BALL:%d %d %d", m_pScene->m_ball.GetPosition().x, m_pScene->m_ball.GetPosition().y, m_pScene->m_ball.GetPosition().z);
*/
if(m_bFinished==true)
return;
if(m_pCurStage->iControlType==CCSCT_CONSTANT)// || m_pCurStage->iControlType==CCSCT_MENTAL)
return;
// get interpolate rate
switch(m_pCurStage->iControlType)
{
case CCSCT_TIME:
//replay, throw
if( m_bReplay && m_iCurStageIndex == CCSS_THROW )
{
m_iTimer = replaytimer;
if( m_iStageIndex > 0 )
{
CCameraStage* m_pPrevStage=&m_pCameraCombinations[m_iCombIndex][m_iStageIndex-1];
if( m_iTimer >= m_pPrevStage->iTotalTime )
m_iTimer -= m_pPrevStage->iTotalTime;
else
{
//switch to previous stage
m_iStageIndex--;
m_pCurStage=&m_pCameraCombinations[m_iCombIndex][m_iStageIndex];
}
}
else
{
if( m_iTimer >= m_pCurStage->iTotalTime && m_iStageIndex < m_pStagesCount[m_iCombIndex]-1 )
{
//switch to next stage
m_iTimer -= m_pCurStage->iTotalTime;
m_iStageIndex++;
m_pCurStage=&m_pCameraCombinations[m_iCombIndex][m_iStageIndex];
}
}
}
startRate=0;
endRate=m_pCurStage->iTotalTime-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -