#include "StdAfx.h" #include "ActionObject.h" #include "GlobalValue.h" #include "ActionElement.h" #include "resource.h" #include "ModifyLengthDlg.h" #include "RenderBase.h" #include "VelocityFunc.h" CActionObject::CActionObject() : m_vVelocity( 0.f, 0.f, 0.f ) , m_vResistance( 0.f, 0.f, 0.f ) { SetType( CActionBase::OBJECT ); m_LocalTime = m_AniTime = 0; m_nLoopCount = 0; m_fCurFrame = 0.f; m_bStop = true; m_bPause = false; m_nAniIndex = -1; m_fPrevFrame = 0.f; m_nTotalFrame = 1; m_fMoveYDistancePerSec = 0.0f; m_fLeftMoveYDistance = 0.0f; m_fOriginalYPos = 0.0f; // #56216. m_bRotate = false; m_fSpeed = 0.0f; m_vAxisPos.x = 0.0f; m_vAxisPos.y = 0.0f; m_vAxisPos.z = 0.0f; //EtMatrixIdentity( &m_AxisRotation ); } CActionObject::~CActionObject() { SAFE_RELEASE_SPTR( m_ObjectHandle ); } void CActionObject::InitPropertyInfo() { SAFE_DELETE_PVEC( m_pVecPropertyList ); PropertyGridBaseDefine Default[] = { { "Common", "Path", CUnionValueProperty::String, "Àüü °æ·Î", FALSE }, { "Common", "Skin Name", CUnionValueProperty::String, "½ºÅ² ÆÄÀÏ À̸§", FALSE }, { "Common", "Animation Name", CUnionValueProperty::String_FileOpen, "¿¡´Ï¸ÞÀÌ¼Ç ÆÄÀÏ À̸§|Eternity Animation File (*.ani)|*.ani", TRUE }, { "Common", "Action Name", CUnionValueProperty::String, "¾×¼Ç ÆÄÀÏ À̸§", FALSE }, { "Environment", "Environment Texture", CUnionValueProperty::String_FileOpen, "Texture File|All Texture Files|*.dds;*.jpg;*.tga;*.bmp", TRUE }, { "Infomation", "Ani Count", CUnionValueProperty::Integer, "¿¡´Ï¸ÞÀÌ¼Ç °¹¼ö", FALSE }, { "Infomation", "SubMesh Count", CUnionValueProperty::Integer, "¼­ºê¸Þ½¬ °¹¼ö", FALSE }, { "Infomation", "Polygon Count", CUnionValueProperty::Integer, "Æú¸®°ï °¹¼ö", FALSE }, NULL, }; AddPropertyInfo( Default ); } void CActionObject::Process( LOCAL_TIME LocalTime ) { // if( m_LocalTime == LocalTime ) return; float fDelta = ( LocalTime - m_LocalTime ) * 0.001f; m_LocalTime = LocalTime; if( m_bStop ) { m_AniTime = LocalTime; } float fFps = (float)CGlobalValue::GetInstance().GetFPS(); if( m_bPause == true ) { m_AniTime = LocalTime - (LOCAL_TIME)( ( m_fCurFrame / fFps ) * 1000.f ); } float fTemp = ( ( LocalTime - m_AniTime ) / 1000.f ) * fFps; float fTemp2 = fTemp; float fAniLength = (float)m_nTotalFrame;//(float)m_ObjectHandle->GetAniLength( m_nAniIndex ) - 1.f; float fFrame = fTemp2 - (float)( ((int)fTemp / (int)fAniLength) * fAniLength ); //float fFrame = fTemp2 - ( (fTemp / fAniLength) * (float)fAniLength ); // ·çÇÁ ´Ù µ¹¾ÒÀ¸¸é ¸¶Áö¸· ÇÁ·¹ÀÓ À¯Áö if( m_nLoopCount - ( (int)( fTemp / fAniLength ) ) < 1 ) { m_bStop = true; m_fCurFrame = fAniLength; m_fPrevFrame = fAniLength; // #56216. m_matExWorld.Identity(); SetRotate( false ); } else if( m_bStop == false ) { if( fFrame != m_fCurFrame ) { m_fPrevFrame = m_fCurFrame; m_fCurFrame = fFrame; } if( m_fPrevFrame == m_nTotalFrame ) { m_fPrevFrame = 0.f; } // ÇÁ·¹ÀÓÀÇ ³¡. #56216. if( (int)(::ceil( fFrame )) >= m_nTotalFrame ) { m_matExWorld.Identity(); SetRotate( false ); } } if( m_ObjectHandle ) { //// #56216. if( m_bRotate ) RotateObject( fDelta ); m_ObjectHandle->SetCalcPositionFlag( CALC_POSITION_X | CALC_POSITION_Y | CALC_POSITION_Z ); m_ObjectHandle->Update( m_matExWorld ); if( m_nAniIndex != -1 ) { m_ObjectHandle->SetAniFrame( m_nAniIndex, m_fCurFrame ); } if( !m_bPause && !m_bStop ) { if( (int)m_fPrevFrame != (int)m_fCurFrame ) { m_ObjectHandle->SetObjectAlpha( 1.f ); m_ObjectHandle->RestoreCustomParam( -1, -1 ); } } } ProcessVelocity( LocalTime, fDelta ); CActionBase::Process( LocalTime ); } bool CActionObject::LoadSkin( const char *pFileName ) { if( m_szSkinName == pFileName ) return true; m_szSkinName = pFileName; SAFE_RELEASE_SPTR( m_ObjectHandle ); if( m_szAniName.IsEmpty() ) { // m_ObjectHandle = EternityEngine::CreateStaticObject( m_szSkinName ); m_ObjectHandle = EternityEngine::CreateAniObject( m_szSkinName, NULL ); } else { m_ObjectHandle = EternityEngine::CreateAniObject( m_szSkinName, m_szAniName ); SAFE_DELETE_VEC( m_szVecAniNameList ); if( m_ObjectHandle ) { for( int i=0; iGetAniCount(); i++ ) { m_szVecAniNameList.push_back( m_ObjectHandle->GetAniName( i ) ); } } } if( m_ObjectHandle ) m_ObjectHandle->EnableCull( false ); return true; } bool CActionObject::LoadAni( const char *pFileName ) { if( m_szAniName == pFileName ) return true; m_szAniName = pFileName; if( m_szSkinName.IsEmpty() || !m_ObjectHandle ) return false; SAFE_RELEASE_SPTR( m_ObjectHandle ); m_ObjectHandle = EternityEngine::CreateAniObject( m_szSkinName, m_szAniName ); if( m_ObjectHandle ) m_ObjectHandle->EnableCull( false ); SAFE_DELETE_VEC( m_szVecAniNameList ); for( int i=0; iGetAniCount(); i++ ) { m_szVecAniNameList.push_back( m_ObjectHandle->GetAniName( i ) ); } return true; } #ifdef _CHECK_WALKFRONT bool CActionObject::LoadAction( const char *pFileName, bool bCheckOnly ) #else bool CActionObject::LoadAction( const char *pFileName ) #endif { if( m_szActName == pFileName ) return true; m_szActName = pFileName; FILE *fp; fopen_s( &fp, m_szActName, "rb" ); if( fp == NULL ) return false; ActionHeader Header; fread( &Header, sizeof(ActionHeader), 1, fp ); CModifyLengthDlg::s_nType = 1; CModifyLengthDlg::s_bYesAll = false; for( int i=0; iSetParent( this ); AddChild( pElement ); #ifdef _CHECK_WALKFRONT if (bCheckOnly) { if (pElement->ImportForCheck(fp,Header.nVersion) == false) { RemoveChild(pElement); fclose(fp); return false; } } else { if( pElement->ImportObject( fp , Header.nVersion ) == false ) { RemoveChild( pElement ); fclose(fp); return false; } } #else if( pElement->ImportObject( fp ) == false ) { RemoveChild( pElement ); // SAFE_DELETEA( pElement ); fclose(fp); return false; } #endif pElement->Activate(); } fclose(fp); return true; } bool CActionObject::SaveAction() { if( m_szActName.IsEmpty() ) { if( m_szSkinName.IsEmpty() ) return true; m_szActName.Format( "%s%s.act", m_szPath, GetName() ); } #ifdef _CHECK_WALKFRONT std::vector checkFolderArray; checkFolderArray.push_back("Monster"); if (CheckActionExist(checkFolderArray, "Walk_Front") == eERROR_NOACTION) { if (MessageBox(0, "°æ°í!! Walk_Front ¾×¼ÇÀÌ ºüÁ®ÀÖ½À´Ï´Ù.\n\n¿òÁ÷ÀÌ´Â ¸ó½ºÅÍÀÇ °æ¿ì Walk_Front ¾×¼ÇÀÌ ¾øÀ¸¸é ¾î´À¼ø°£ ÇൿÀÌ ¸ØÃç¹ö¸± ¼ö ÀÖ½À´Ï´Ù.\n\nÁ¤¸» ÀúÀåÇϽðڽÀ´Ï±î?", "°æ°í", MB_YESNO) == IDNO) return true; } #endif FILE *fp; fopen_s( &fp, m_szActName, "wb" ); if( fp == NULL ) return false; ActionHeader Header; sprintf_s( Header.szHeaderString, "Eternity Action File" ); Header.nVersion = 1; Header.nActionCount = (int)m_pVecChild.size(); fwrite( &Header, sizeof(ActionHeader), 1, fp ); if( CActionBase::ExportObject( fp, Header.nActionCount ) == false ) { fclose(fp); return false; } fclose(fp); return true; } #ifdef _CHECK_WALKFRONT CActionObject::eCheckWalkFrontResult CActionObject::CheckActionExistWithLoadFile(const std::string& fileName, const std::string& checkActionName) { LoadAction(fileName.c_str(), true); if (IsActionExist(checkActionName)) return eOK_EXISTACTION; return eERROR_NOACTION; } CActionObject::eCheckWalkFrontResult CActionObject::CheckActionExist(const std::vector& checkPathArray, const std::string& checkActionName) const { std::string pathWrapper(m_szPath); bool bCheck = false; std::vector::const_iterator pathIter = checkPathArray.begin(); for (; pathIter != checkPathArray.end(); ++pathIter) { const std::string& checkPathName = *pathIter; if (pathWrapper.find(checkPathName.c_str()) != std::string::npos) { bCheck = true; break; } } if (bCheck) { if (IsActionExist(checkActionName)) return eOK_EXISTACTION; } else { return eOK_NONEED; } return eERROR_NOACTION; } bool CActionObject::IsActionExist(const std::string& checkActionName) const { std::vector::const_iterator iter = m_pVecChild.begin(); for (; iter != m_pVecChild.end(); ++iter) { CActionBase* pCurAction = (*iter); if (pCurAction) { std::string actionNameWrapper(pCurAction->GetName()); if (actionNameWrapper.compare(checkActionName.c_str()) == 0) return true; } } return false; } #endif // _CHECK_WALKFRONT void CActionObject::SetPath( CString szStr ) { m_szPath = szStr; } void CActionObject::OnSetPropertyValue( DWORD dwIndex, CUnionValueProperty *pVariable ) { switch( dwIndex ) { case 0: pVariable->SetVariable( m_szPath.GetBuffer() ); break; case 1: if( m_szSkinName.IsEmpty() ) pVariable->SetVariable( "Not Found" ); else { char szTemp[512] = { 0, }; _GetFileName( szTemp, _countof(szTemp), m_szSkinName ); sprintf_s( szTemp, "%s.skn", szTemp ); pVariable->SetVariable( szTemp ); } break; case 2: if( m_szAniName.IsEmpty() ) pVariable->SetVariable( "Not Found" ); if( !m_szAniName.IsEmpty() ) { char szTemp[512] = { 0, }; _GetFileName( szTemp, _countof(szTemp), m_szAniName ); sprintf_s( szTemp, "%s.ani", szTemp ); pVariable->SetVariable( szTemp ); } break; case 3: if( m_szActName.IsEmpty() ) pVariable->SetVariable( "Not Found" ); else { char szTemp[512] = { 0, }; _GetFileName( szTemp, _countof(szTemp), m_szActName ); sprintf_s( szTemp, "%s.act", szTemp ); pVariable->SetVariable( szTemp ); } break; case 4: if( CRenderBase::GetInstance().GetEnvironmentTexture() == NULL || strlen( CRenderBase::GetInstance().GetEnvironmentTexture() ) == 0 ) pVariable->SetVariable( "Not Found" ); else { pVariable->SetVariable( (char*)CRenderBase::GetInstance().GetEnvironmentTexture() ); } break; case 5: { int nCount = 0; if( m_ObjectHandle && m_ObjectHandle->GetAniHandle() ) { nCount = m_ObjectHandle->GetAniCount(); } pVariable->SetVariable( nCount ); } break; case 6: { int nCount = 0; if( m_ObjectHandle ) { nCount = m_ObjectHandle->GetSubMeshCount(); } pVariable->SetVariable( nCount ); } break; case 7: { int nCount = 0; if( m_ObjectHandle ) { for( int i=0; iGetSubMeshCount(); i++ ) { nCount += m_ObjectHandle->GetSubMesh(i)->GetVertexCount(); } } pVariable->SetVariable( nCount ); } break; } } void CActionObject::OnChangePropertyValue( DWORD dwIndex, CUnionValueProperty *pVariable ) { switch( dwIndex ) { case 2: { if( LoadAni( pVariable->GetVariableString() ) == true ) { char szTemp[512] = { 0, }; _GetFileName( szTemp, _countof(szTemp), m_szAniName ); sprintf_s( szTemp, "%s.ani", szTemp ); pVariable->SetVariable( szTemp ); } else { pVariable->SetVariable( "Not Found" ); } } break; case 4: { CRenderBase::GetInstance().SetEnvironmentTexture( pVariable->GetVariableString() ); } break; } } int CActionObject::GetAniCount() { if( !m_ObjectHandle ) return 0; if( !m_ObjectHandle->GetAniHandle() ) return 0; return m_ObjectHandle->GetAniCount(); } CString CActionObject::GetAniName( int nAniIndex ) { if( nAniIndex < 0 || nAniIndex >= (int)m_szVecAniNameList.size() ) return CString(""); return m_szVecAniNameList[nAniIndex]; } int CActionObject::GetAniLength( CString szAniName ) { for( DWORD i=0; iGetAniLength(i); } assert(0); return 0; } int CActionObject::GetAniIndex( CString szAniName ) { for( DWORD i=0; iGetAniCount() == 0 ) return false; if( GetAniIndex( szAniName ) == -1 ) return false; */ return true; } void CActionObject::SetPlay( CString szAniName ) { // if( szAniName.IsEmpty() ) return; if( !IsCanPlay( szAniName ) ) return; Play( szAniName, 1, 0.f ); Resume(); Stop(); SetCurFrame( 0.f ); } void CActionObject::Play( CString szAniName, int nLoopCount, float fFrame ) { // #56216. EtMatrixIdentity( (EtMatrix *)(&m_matExWorld) ); if( !szAniName.IsEmpty() ) { m_nAniIndex = GetAniIndex( szAniName ); } else { m_nAniIndex = -1; } m_AniTime = m_LocalTime; m_nLoopCount = nLoopCount; if( fFrame != 0.f ) { m_AniTime -= (LOCAL_TIME)( ( fFrame / (float)CGlobalValue::GetInstance().GetFPS() ) * 1000.f ); } else m_fPrevFrame = 0.f; m_bStop = false; } void CActionObject::Stop() { m_bStop = true; SetRotate( false ); // #56216. } void CActionObject::Pause() { m_bPause = true; SetRotate( false ); // #56216. } void CActionObject::Resume() { m_bPause = false; m_AniTime = m_LocalTime; m_AniTime -= (LOCAL_TIME)( ( m_fCurFrame / (float)CGlobalValue::GetInstance().GetFPS() ) * 1000.f ); SetRotate( true ); // #56216. } bool CActionObject::IsStop() { return m_bStop; } bool CActionObject::IsPause() { return m_bPause; } void CActionObject::SetCurFrame( float fFrame ) { m_fCurFrame = fFrame; if( m_fCurFrame < 0.f ) m_fCurFrame = 0.f; else if( m_fCurFrame >= (float)m_nTotalFrame ) m_fCurFrame = (float)m_nTotalFrame; // MoveY ½Ã±×³Î °ªÀ¸·Î À̵¿µÈ °Í ¸®¼Â. m_matExWorld.m_vPosition.y = m_fOriginalYPos; ResetMoveYDistance(); } float CActionObject::GetCurFrame() { return m_fCurFrame; } float CActionObject::GetPrevFrame() { return m_fPrevFrame; } void CActionObject::SetLoopCount( int nLoopCount ) { if( m_nLoopCount >= nLoopCount ) { float fTemp = ( ( m_LocalTime - m_AniTime ) / 1000.f ) * (float)CGlobalValue::GetInstance().GetFPS(); float fAniLength = (float)m_nTotalFrame; m_nLoopCount = (int)( fTemp / fAniLength ) + 1; } else m_nLoopCount = nLoopCount; } int CActionObject::GetLoopCount() { return m_nLoopCount; } EtVector3 CActionObject::GetAniDistance() { if( !m_ObjectHandle ) return EtVector3( 0.f, 0.f, 0.f ); if( m_nAniIndex == -1 ) return EtVector3( 0.f, 0.f, 0.f ); EtVector3 vDist; m_ObjectHandle->CalcAniDistance( m_nAniIndex, m_fCurFrame, 0.f, vDist ); vDist.y = m_matExWorld.m_vPosition.y; return vDist; } bool CActionObject::CheckExistLinkAniAction( const char *pFileName ) { FILE *fp; fopen_s( &fp, pFileName, "rb" ); if( fp == NULL ) return false; ActionHeader Header; fread( &Header, sizeof(ActionHeader), 1, fp ); for( int i=0; iSetParent( this ); if( pElement->CheckImportLinkAni( fp ,Header.nVersion) == true ) { fclose(fp); SAFE_DELETE( pElement ); return true; } SAFE_DELETE( pElement ); } fclose(fp); return false; } void CActionObject::ProcessVelocity( LOCAL_TIME LocalTime, float fDelta ) { float fValue = (float)CGlobalValue::GetInstance().GetFPS() / 60.f * fDelta; EtVector3 vVelocity; if( m_vVelocity.x ) { float fTemp = m_vVelocity.x; float fMin = ( fTemp > 0.f ) ? 0.f : -FLT_MAX; float fMax = ( fTemp > 0.f ) ? FLT_MAX : 0.f; float fTemp2 = m_vVelocity.x; m_matExWorld.m_vPosition.x += CalcMovement( m_vVelocity.x, fDelta, fMax, fMin, m_vResistance.x ); if( m_vVelocity.x * fTemp <= 0.f ) { m_matExWorld.m_vPosition.x = 0.f; m_vVelocity.x = 0.f; } } else m_matExWorld.m_vPosition.x = 0.f; if( m_vVelocity.z ) { float fTemp = m_vVelocity.z; float fMin = ( fTemp > 0.f ) ? 0.f : -FLT_MAX; float fMax = ( fTemp > 0.f ) ? FLT_MAX : 0.f; float fTemp2 = m_vVelocity.z; m_matExWorld.m_vPosition.z += CalcMovement( m_vVelocity.z, fDelta, fMax, fMin, m_vResistance.z ); if( m_vVelocity.z * fTemp <= 0.f ) { m_matExWorld.m_vPosition.z = 0.f; m_vVelocity.z = 0.f; } } else m_matExWorld.m_vPosition.z = 0.f; if( m_vVelocity.y ) { m_matExWorld.m_vPosition.y += CalcMovement( m_vVelocity.y, fValue, FLT_MAX, -FLT_MAX, m_vResistance.y ); if( m_vVelocity.y == 0.f ) m_vVelocity.y += 0.0000001f; if( m_matExWorld.m_vPosition.y <= 0.f ) { m_matExWorld.m_vPosition.y = 0.f; m_vVelocity.y = 0.f; } } // #48950 MoveY ½Ã±×³Î ó¸®. if( 0.0f != m_fMoveYDistancePerSec ) { if( 0.0f == m_fOriginalYPos ) m_fOriginalYPos = m_matExWorld.m_vPosition.y; float fMoveDistance = m_fMoveYDistancePerSec * fDelta; m_matExWorld.m_vPosition.y += fMoveDistance; if( 0.0f < fMoveDistance ) m_fLeftMoveYDistance -= fMoveDistance; else m_fLeftMoveYDistance += fMoveDistance; // ³²Àº °Å¸®¸¦ ³Ñ¾î¼³ °æ¿ì µµÂøÇÑ °ÅÀÓ. // À§Ä¡¸¦ ¼ÂÆÃÇØÁÖ°í ³¡³¿. if( m_fLeftMoveYDistance < 0.0f ) { if( 0.0f < fMoveDistance ) m_matExWorld.m_vPosition.y -= (fMoveDistance + m_fLeftMoveYDistance); else m_matExWorld.m_vPosition.y += (fMoveDistance - m_fLeftMoveYDistance); ResetMoveYDistance(); } } } // #56216. void CActionObject::SetAxisPosition( EtVector3 & vPos ) { m_vAxisPos = vPos; // EtMatrixTranslation( &m_AxisRotation, vPos.x, vPos.y, vPos.z ); } void CActionObject::RotateObject( float fDelta ) { float fValue = (float)CGlobalValue::GetInstance().GetFPS() / 60.f * fDelta; EtMatrix * matWorld = (EtMatrix *)(&m_matExWorld); //// ȸÀüÃàÁÂÇ¥À̵¿. m_matExWorld.MoveLocalXAxis( m_vAxisPos.x ); m_matExWorld.MoveLocalYAxis( m_vAxisPos.y ); m_matExWorld.MoveLocalZAxis( m_vAxisPos.z ); // ȸÀü. m_matExWorld.RotateYaw( -(m_fSpeed * fValue) ); //EtVector3 vDist = GetAniDistance(); //EtVector3 vPos = m_vAxisPos - vDist; ////EtVector3 vPos = m_vAxisPos; //// ¿øÁ¡À̵¿. //EtMatrix matPos; //EtMatrixTranslation( &matPos, vPos.x, vPos.y, vPos.z ); //EtMatrixMultiply( matWorld, matWorld, &matPos ); //// ȸÀü. //EtMatrix matRot; //EtMatrixRotationY( &matRot, D3DXToRadian( m_fSpeed * fValue ) ); ////EtMatrixMultiply( matWorld, &matRot, matWorld); //*matWorld = matRot; // ////// AniDistance Àû¿ë. ////EtMatrix matPosAni; ////EtMatrixTranslation( &matPosAni, vDist.x, vDist.y, vDist.z ); ////EtMatrixMultiply( matWorld, matWorld, &matPosAni ); // //EtMatrix * pSaveMat = NULL; ///*static bool bFirst = true; //if( m_bRotate && bFirst ) //{ // bFirst = false;*/ // pSaveMat = GetEtSaveMat()->GetMatrix( m_ObjectHandle->GetSaveMatIndex() ); ////} // //EtVector3 vDist = GetAniDistance(); //// ¾Ö´Ï¸ÞÀ̼ÇÇà·Ä¿¡¼­ AniDistance¸¦ Á¦°Å. //if( pSaveMat ) // pSaveMat->_41 = pSaveMat->_42 = pSaveMat->_43 = 0.0f; ////// ¿øÁ¡À̵¿. ////EtVector3 vDist = GetAniDistance(); ////EtVector3 vPos = m_vAxisPos - vDist; //// ////EtMatrix matPos; ////EtMatrixTranslation( &matPos, vPos.x, vPos.y, vPos.z ); ////EtMatrixMultiply( matWorld, matWorld, &matPos ); //EtMatrix matRot; //EtMatrixRotationY( &matRot, D3DXToRadian( m_fSpeed * fValue ) ); ////EtMatrixMultiply( matWorld, matWorld, &matRot ); //*matWorld = matRot; }