⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccameracontrol.cpp

📁 一个3D的保龄球的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:


/*
* ============================================================================
*  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 + -