#include "stdafx.h" #include "SGameCameraWork.h" #include "SGame.h" #include "SGameCamera.h" #include "K3DCamera.h" #include #include #include #include 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; }