Files
Leviathan/Client/Game/game/Main/SGameCameraWork.cpp
T
2026-06-01 12:46:52 +02:00

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;
}