243 lines
7.0 KiB
C++
243 lines
7.0 KiB
C++
#include "stdafx.h"
|
|
#include "SGameCameraWork.h"
|
|
|
|
#include "SGame.h"
|
|
#include "SGameCamera.h"
|
|
#include "K3DCamera.h"
|
|
|
|
#include <kfile/KStream.h>
|
|
#include <kfile/KFiler.h>
|
|
#include <kfile/KFileManager.h>
|
|
#include <toolkit/XStringUtil.h>
|
|
|
|
SGameCameraWork::SGameCameraWork( SGame* pGame, SGameCamera* pGameCamera ) : m_pGame( pGame )
|
|
, m_pGameCamera( pGameCamera )
|
|
, m_nCurrentFrame( 0 )
|
|
, m_bEnd( false )
|
|
, m_dwStartTime( 0 )
|
|
, m_bStop( false )
|
|
, m_vCurCameraPos( 0.0f, 0.0f, 0.0 )
|
|
, m_vCurTargetPos( 0.0f, 0.0f, 0.0 )
|
|
, m_fCamRotation( 0.0f )
|
|
, m_fTarRotation( 0.0f )
|
|
{
|
|
m_pBackUpCamera = new K3DCamera;
|
|
*m_pBackUpCamera = *m_pGameCamera->GetCamera();
|
|
|
|
m_pFrame = NULL;
|
|
m_nFrameSize = 0;
|
|
|
|
m_vCurCameraPos = m_pGameCamera->GetCameraPosition();
|
|
m_vCurTargetPos = m_pGameCamera->GetCameraTargetPosition();
|
|
}
|
|
|
|
SGameCameraWork::~SGameCameraWork()
|
|
{
|
|
SAFE_DELETE( m_pBackUpCamera );
|
|
|
|
VEC_FRAME_INFO::iterator iter = m_vFrameInfo.begin();
|
|
for( ; iter != m_vFrameInfo.end(); )
|
|
{
|
|
SAFE_DELETE( (*iter) );
|
|
iter = m_vFrameInfo.erase( iter );
|
|
}
|
|
|
|
SAFE_DELETE_ARRAY( m_pFrame );
|
|
}
|
|
|
|
void SGameCameraWork::LoadCameraWork( const char* szCameraWorkFileName, int nPosX, int nPosY, float fMapLen )
|
|
{
|
|
m_pGameCamera->SetCameraWork( this );
|
|
*m_pBackUpCamera = *m_pGameCamera->GetCamera();
|
|
|
|
KStream* pStream = KFileManager::Instance().CreateStreamFromResource( szCameraWorkFileName );
|
|
if( pStream == NULL )
|
|
{
|
|
Stop();
|
|
SAFE_DELETE( pStream );
|
|
return;
|
|
}
|
|
|
|
NFM_CAMERA_WORK_HEADER_V1 header;
|
|
::ZeroMemory( &header, sizeof(header) );
|
|
pStream->Read( &header, sizeof(header) );
|
|
|
|
if( header.camerawork <= 0 || header.dwVersion != c_dwNFMCameraWorkVer )
|
|
{
|
|
Stop();
|
|
SAFE_DELETE( pStream );
|
|
return;
|
|
}
|
|
|
|
int nFrameSize = 0;
|
|
for( int nSize = 0; nSize < header.camerawork; ++nSize ) //현재 카메라는 1개만 지원
|
|
{
|
|
pStream->Read( &nFrameSize, sizeof( nFrameSize ) );
|
|
|
|
int nStringSize = 0;
|
|
pStream->Read( &nStringSize, sizeof( nStringSize ) );
|
|
if( nStringSize > 1 )
|
|
{
|
|
char* szCameraName = new char[nStringSize];
|
|
pStream->Read( szCameraName, nStringSize );
|
|
SAFE_DELETE_ARRAY(szCameraName);
|
|
}
|
|
|
|
for( int nSize = 0; nSize < nFrameSize; ++nSize )
|
|
{
|
|
NFM_CAMERA_WORK_STRUCT_V1* pFrameInfo = new NFM_CAMERA_WORK_STRUCT_V1;
|
|
pStream->Read( pFrameInfo, sizeof( *pFrameInfo ) );
|
|
|
|
/* pFrameInfo->px += (int)( (float)nPosX * fMapLen );
|
|
pFrameInfo->py += (int)( (float)nPosY * fMapLen );
|
|
|
|
pFrameInfo->tx += (int)( (float)nPosX * fMapLen );
|
|
pFrameInfo->ty += (int)( (float)nPosY * fMapLen );*/
|
|
|
|
m_vFrameInfo.push_back( pFrameInfo );
|
|
}
|
|
}
|
|
|
|
m_nFrameSize = m_vFrameInfo.size();
|
|
if( m_nFrameSize <= 0 )
|
|
{
|
|
Stop();
|
|
SAFE_DELETE( pStream );
|
|
return;
|
|
}
|
|
|
|
SAFE_DELETE_ARRAY( m_pFrame );
|
|
m_pFrame = new Frame[m_nFrameSize];
|
|
|
|
DWORD dwTime = 0;
|
|
VEC_FRAME_INFO::iterator iter = m_vFrameInfo.begin();
|
|
for( int nNum = 0; iter != m_vFrameInfo.end(); ++iter, ++nNum )
|
|
{
|
|
if( nNum != m_nFrameSize - 1 )
|
|
dwTime += (*iter)->m_dwSpeed;
|
|
|
|
m_pFrame[nNum].nFrameNum = nNum;
|
|
m_pFrame[nNum].dwFrameTime = dwTime;
|
|
m_pFrame[nNum].pCameraWorkInfo = (*iter);
|
|
}
|
|
|
|
SAFE_DELETE( pStream );
|
|
}
|
|
|
|
int SGameCameraWork::GetNumberOfFrame( DWORD dwTime )
|
|
{
|
|
for( size_t nNum = 0; nNum < m_nFrameSize; ++nNum )
|
|
{
|
|
if( m_pFrame[nNum].dwFrameTime > dwTime )
|
|
return m_pFrame[nNum].nFrameNum;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
Frame* SGameCameraWork::GetFrameByNumberOfFrame( int nNumOfFrame )
|
|
{
|
|
if( nNumOfFrame >= (int)m_nFrameSize ) return NULL;
|
|
|
|
return &m_pFrame[nNumOfFrame];
|
|
}
|
|
|
|
int SGameCameraWork::GetLastFrame()
|
|
{
|
|
return m_nFrameSize - 1;
|
|
}
|
|
|
|
void SGameCameraWork::Process( DWORD dwTime )
|
|
{
|
|
if( m_vFrameInfo.empty() )
|
|
{
|
|
Stop();
|
|
return;
|
|
}
|
|
|
|
if( m_dwStartTime == 0 ) m_dwStartTime = dwTime;
|
|
|
|
DWORD dwCurTime = dwTime - m_dwStartTime;
|
|
|
|
int nFrame = GetNumberOfFrame( dwCurTime );
|
|
if( nFrame == -1 )
|
|
{
|
|
Stop();
|
|
}
|
|
|
|
if( !IsStop() )
|
|
{
|
|
Frame* pCurrentFrame = GetFrameByNumberOfFrame( nFrame );
|
|
Frame* pNextFrame = GetFrameByNumberOfFrame( nFrame + 1 );
|
|
|
|
if( pCurrentFrame == NULL ) return;
|
|
|
|
FRAME_INFO* pCurrentFrameInfo = pCurrentFrame->pCameraWorkInfo;
|
|
|
|
float fTime = 1.0f - (float)(pCurrentFrame->dwFrameTime - dwCurTime) / pCurrentFrameInfo->m_dwSpeed;
|
|
|
|
m_vCurCameraPos = K3DVector( pCurrentFrameInfo->px, pCurrentFrameInfo->py, pCurrentFrameInfo->pz );
|
|
m_vCurTargetPos = K3DVector( pCurrentFrameInfo->tx, pCurrentFrameInfo->ty, pCurrentFrameInfo->tz );
|
|
|
|
m_fCamRotation = pCurrentFrameInfo->m_fCameraRotation;
|
|
m_fTarRotation = pCurrentFrameInfo->m_fTargetRotation;
|
|
|
|
if( pNextFrame )
|
|
{
|
|
K3DVector vCurPos( pCurrentFrameInfo->px, pCurrentFrameInfo->py, pCurrentFrameInfo->pz );
|
|
K3DVector vNextPos( pCurrentFrameInfo->tx, pCurrentFrameInfo->ty, pCurrentFrameInfo->tz );
|
|
|
|
FRAME_INFO* pNextFrameInfo = pNextFrame->pCameraWorkInfo;
|
|
|
|
vCurPos = K3DVector( pCurrentFrameInfo->otx, pCurrentFrameInfo->oty, pCurrentFrameInfo->tz );
|
|
if( pCurrentFrameInfo->m_fTargetRotation != 0.0f )
|
|
{
|
|
vNextPos = K3DVector( pCurrentFrameInfo->opx, pCurrentFrameInfo->opy, pCurrentFrameInfo->pz );
|
|
CalcRotation( vCurPos, vCurPos, vNextPos, pCurrentFrameInfo->m_fTargetRotation );
|
|
}
|
|
|
|
vNextPos = K3DVector( pNextFrameInfo->otx, pNextFrameInfo->oty, pNextFrameInfo->tz );
|
|
K3DVectorLerp( m_vCurTargetPos, vCurPos, vNextPos, fTime );
|
|
|
|
vCurPos = K3DVector( pCurrentFrameInfo->opx, pCurrentFrameInfo->opy, pCurrentFrameInfo->pz );
|
|
if( pCurrentFrameInfo->m_fCameraRotation != 0.0f )
|
|
{
|
|
vNextPos = K3DVector( pCurrentFrameInfo->otx, pCurrentFrameInfo->oty, pCurrentFrameInfo->tz );
|
|
CalcRotation( vCurPos, vCurPos, vNextPos, pCurrentFrameInfo->m_fCameraRotation );
|
|
}
|
|
|
|
vNextPos = K3DVector( pNextFrameInfo->opx, pNextFrameInfo->opy, pNextFrameInfo->pz );
|
|
K3DVectorLerp( m_vCurCameraPos, vCurPos, vNextPos, fTime );
|
|
|
|
|
|
m_fCamRotation = K3DFloatLerp( 0.0f, pNextFrameInfo->m_fCameraRotation, fTime );
|
|
m_fTarRotation = K3DFloatLerp( 0.0f, pNextFrameInfo->m_fTargetRotation, fTime );
|
|
}
|
|
}
|
|
|
|
K3DCamera* pCamera = m_pGameCamera->GetCamera();
|
|
*pCamera = *m_pBackUpCamera;
|
|
|
|
K3DVector vTempTar = m_vCurTargetPos, vTempCam = m_vCurCameraPos;
|
|
|
|
CalcRotation( vTempCam, m_vCurCameraPos, m_vCurTargetPos, m_fCamRotation );
|
|
CalcRotation( vTempTar, m_vCurTargetPos, m_vCurCameraPos, m_fTarRotation );
|
|
|
|
pCamera->SetTargetPos( vTempTar.x, vTempTar.y, vTempTar.z );
|
|
pCamera->SetCamPos( vTempCam.x, vTempCam.y, vTempCam.z );
|
|
}
|
|
|
|
void SGameCameraWork::CalcRotation( K3DVector& vOut, K3DVector& vPos, K3DVector& vTarget, float fRotation )
|
|
{
|
|
//타겟은 카메라 중심으로 회전, 카메라는 타겟 중심으로 회전
|
|
K3DMatrix matTrans, matRotation;
|
|
K3DVector vCenter = vPos - vTarget;
|
|
K3DMatrixTranslation( matTrans, vTarget.x, vTarget.y, vTarget.z );
|
|
K3DMatrixRotationZ( matRotation, (fRotation * (K3D_PI * 2.0f)) / 360.0f );
|
|
matRotation = matRotation * matTrans;
|
|
K3DVectorTransform( vOut, vCenter, matRotation );
|
|
}
|
|
|
|
void SGameCameraWork::Stop()
|
|
{
|
|
m_bStop = true;
|
|
} |