// KSeqAvatar.cpp: implementation of the KSeqAvatar class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "KViewport.h" #include ".\kseqavatar.h" #include "KResourceManager.h" #include "KRenderObjectBone.h" #include "KRenderObjectMesh.h" //#include "Util.h" #include ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// BOOL KSeqAvatar::m_bEffectPosRenderFlag = FALSE; BOOL KSeqAvatar::m_sMeshRenderFlag = TRUE; KSeqAvatar::KSeqAvatar( int nAniPartIndex ) { m_ViewVectorX = K3DVector(1,0,0); //좌우 m_ViewVectorZ = K3DVector(1,0,0); //상하 m_BodyVector = K3DVector(1,0,0); //몸통 m_CurViewVector = K3DVector(1,0,0); //현재 뷰~ m_nPrevViewVector = K3DVector(1,0,0); //전 뷰~ m_vViewTarget = K3DVector(0,0,0); //보는 위치~ for( int i(0); MPART_MAX>i; i++ ) { m_pMeshPart[i] = NULL; m_bMeshRender[i] = FALSE; } for( int i(0); MDECOPART_MAX>i ; ++i ) { m_pDecoMeshPart[i] = NULL; m_bDecoMeshRender[i] = FALSE; } for( int i(0); ATTACH_MAX>i; i++ ) { m_pItemPart[i] = NULL; m_bItemRender[i] = FALSE; } for( int i(0); EFFECT_POS_MAX>i; i++ ) { m_pEffectPos[i] = NULL; m_bEffectPos[i] = FALSE; } for( int i(0); BONE_EFFECT_MAX>i; i++ ) { m_pBoneEffect[i] = NULL; m_bBoneEffect[i] = FALSE; m_nBoneEffectIndex[i] = -1; } m_bBoneEffectCheck = FALSE; m_bRenderRotCube = FALSE; m_bItemCheck = FALSE; m_bEffectPosCheck = FALSE; m_bMeshCheck = FALSE; m_bDecoMeshCheck = FALSE; K3DMatrixIdentity( m_matTransform ); m_nAniPartIndex = nAniPartIndex; m_decoShoulderPrevTime = 0; } KSeqAvatar::~KSeqAvatar() { Clear(); } void KSeqAvatar::Clear() { KSeqForm::Clear(); for( int i(0); MPART_MAX>i; i++ ) { SAFE_DELETE( m_pMeshPart[i]); m_bMeshRender[i] = FALSE; } for( int i(0); MDECOPART_MAX>i ; ++i ) { SAFE_DELETE( m_pDecoMeshPart[i] ); m_bDecoMeshRender[i] = FALSE; } m_bDecoMeshCheck = FALSE; for( int i(0); ATTACH_MAX>i; i++ ) { SAFE_DELETE( m_pItemPart[i] ); m_bItemRender[i] = FALSE; } for( int i(0); EFFECT_POS_MAX>i; i++ ) { SAFE_DELETE( m_pEffectPos[i] ); m_bEffectPos[i] = FALSE; } for( int i(0); BONE_EFFECT_MAX>i; i++ ) { SAFE_DELETE( m_pBoneEffect[i] ); m_bBoneEffect[i] = FALSE; m_nBoneEffectIndex[i] = -1; } } void KSeqAvatar::ClipTest( const K3DVector* pFrustrum ) { /// 2010.01.03 - prodongi bool isMeshPart = false; for( int i(0); MPART_MAX>i; i++ ) { if( m_pMeshPart[i] ) { isMeshPart = true; m_pMeshPart[i]->ClipTest( pFrustrum ); } } /// 2011.01.03 일반 메쉬가 없을 때는 데코 메쉬를 검사해야 된다 - prodongi if (!isMeshPart) { for (int i = 0; i < MDECOPART_MAX; ++i) { if (m_pDecoMeshPart[i]) m_pDecoMeshPart[i]->ClipTest(pFrustrum); } } } bool KSeqAvatar::GetIsClip() { /// 2010.01.03 - prodongi bool isMeshPart = false; bool bIsClip = true; for( int i(0); MPART_MAX>i; i++ ) { if( m_pMeshPart[i] ) { isMeshPart = true; bIsClip = m_pMeshPart[i]->GetIsClip(); if( !bIsClip ) return bIsClip; } } /// 2011.01.03 일반 메쉬가 없을 때는 데코 메쉬를 검사해야 된다 - prodongi if (!isMeshPart) { for (int i = 0; i < MDECOPART_MAX; ++i) { if (m_pDecoMeshPart[i]) { bIsClip = m_pDecoMeshPart[i]->GetIsClip(); if (!bIsClip) return bIsClip; } } } return bIsClip; } void KSeqAvatar::ClearAnimation() { StopAnimation(); KSeqForm::Clear(); } void KSeqAvatar::DelAnimation( const char *pszAniKey ) { RemoveAnimation( pszAniKey ); } bool KSeqAvatar::AddAnimation( const char *filename, BOOL bOld, bool bNowLoading ) { std::string strKey; CStringUtil::GetStrKey( filename, '_' , strKey, bOld ); if( strKey.length() <= 0 ) return false; return KSeqForm::AddAnimation( strKey.c_str(), filename, bNowLoading ); } void KSeqAvatar::ClearMesh() { for( int i(0); MPART_MAX>i; i++ ) { SAFE_DELETE( m_pMeshPart[i]); //이미 있는것 제거.. m_bMeshRender[i] = FALSE; } for( int i(0); MDECOPART_MAX>i; ++i ) { SAFE_DELETE( m_pDecoMeshPart[i] ); m_bDecoMeshRender[i] = FALSE; } for( int i(0); ATTACH_MAX>i; i++ ) { SAFE_DELETE( m_pItemPart[i] ); m_bItemRender[i] = FALSE; } } void KSeqAvatar::AddBoneEffect( int nIndex, KSeqObject *obj ) { SAFE_DELETE( m_pBoneEffect[nIndex]); //이미 있는것 제거.. m_pBoneEffect[nIndex] = static_cast(obj); if( obj ) { m_bBoneEffect[nIndex] = true; m_bBoneEffectCheck = TRUE; obj->SetParentTransform( m_pMatParent, NULL, TRUE ); } else { m_bBoneEffect[nIndex] = false; m_nBoneEffectIndex[nIndex] = -1; } } bool KSeqAvatar::AddBoneEffect( int nIndex, const char *bonename, const char *filename ) { if( nIndex < 0 || nIndex >= BONE_EFFECT_MAX ) return false; NX3LoadPack loadpack; loadpack.Init(); _CID( GETBONEMATRIX ); KSeqForm* obj = new KSeqForm; obj->AddAnimation( "default", filename ); obj->PlayAnimation( m_dwTime, "default", SEQTYPE_LOOP ); AddBoneEffect( nIndex, obj ); if( !obj ) { _oprint( "!!!Graphic resource Bone Effect Error: %s\n", filename ); return false; } else { KMsgGET_BONEMATRIX msg; msg.strBoneName = bonename; Perform( id_GETBONEMATRIX, msg ); m_nBoneEffectIndex[nIndex] = msg.nBoneMatIndex; if( m_bBoneEffect[nIndex] && m_pBoneEffect[nIndex] && m_nBoneEffectIndex[nIndex] != -1 ) { m_pBoneEffect[nIndex]->SetParentTransform( m_pMatParent, msg.pBoneMat ); // if( m_pCurSeq ) m_pCurSeq->SetAttachEffectBone( m_nBoneEffectIndex[nIndex], m_pBoneEffect[nIndex] ); } } return true; } bool KSeqAvatar::AddEffectPos( int nAttachIndex, const char *filename ) { //TODO : 외부에서 받거나, 옵션에서 얻어 올 수 있게 바꿔야 한다. NX3LoadPack loadpack; loadpack.Init(); KSeqObject *obj = KNX3Manager::GetManager()->CreateSequencer( filename, &loadpack ); AddEffectPos( nAttachIndex, obj ); if( !obj ) { _oprint( "Graphic Resource Effect Pos Error: %s\n", filename ); return false; } return true; } void KSeqAvatar::AddMorphMesh( KMsgSET_MORPHMESH* pMsg ) { _CID( SET_MORPHMESH ); for( int i(0); MPART_MAX>i; i++ ) { if( m_pMeshPart[i] ) m_pMeshPart[i]->Perform( id_SET_MORPHMESH, *pMsg ); } } void KSeqAvatar::SetFixTexture( KMsgSET_FIXTEXTURE* pMsg ) { _CID( SET_FIX_TEXTURE ); for( int i(0); MPART_MAX>i; ++i ) { if( m_pMeshPart[i] ) m_pMeshPart[i]->Perform( id_SET_FIX_TEXTURE, *pMsg ); } for( int i(0); MDECOPART_MAX>i; ++i ) { if( m_pDecoMeshPart[i] ) m_pDecoMeshPart[i]->Perform( id_SET_FIX_TEXTURE, *pMsg ); } for( int i(0); ATTACH_MAX>i; ++i ) { if( m_bItemRender[i] && m_pItemPart[i] ) m_pItemPart[i]->Perform( id_SET_FIX_TEXTURE, *pMsg ); } } void KSeqAvatar::AddEffectPos( int nAttachIndex, KSeqObject *obj ) { SAFE_DELETE( m_pEffectPos[nAttachIndex]); //이미 있는것 제거.. m_pEffectPos[nAttachIndex] = obj; m_bEffectPos[nAttachIndex] = false; if( obj ) { m_bEffectPos[nAttachIndex] = true; m_bEffectPosCheck = TRUE; // if( m_bEffectPosCheck == FALSE ) // obj->Perform( id_SETFORCERENDER_FLAG, NULL ); //강제로 Off obj->SetParentTransform( &m_matResult, NULL, TRUE ); } } //아바타 살들~ KSeqObject *KSeqAvatar::GetMesh( int nIndex ) { assert(nIndex>=0 && nIndex=0 && nIndex=0 && nIndex=0 && nIndex=0 && index=0 && indexPerform( id_GETMESH_NAME, msg ); //모두 On SetRenderFlag( "leg", TRUE ); for( unsigned int i(0); msg.vNameList.size()>i; i++ ) { const char * pName = msg.vNameList[i]; //상위 if( strstr( pName, "leg" ) != NULL ) //겹치는게 있으면서 Off { SetRenderFlag( "leg", FALSE ); } } } else if( nIndex == MPART_HAND ) { KMsgGET_MESHNAME msg; obj->Perform( id_GETMESH_NAME, msg ); //모두 On SetRenderFlag( "arm", true ); for( unsigned int i(0); msg.vNameList.size()>i; i++ ) { const char * pName = msg.vNameList[i]; //하위 if( strstr( pName, "arm" ) != NULL ) //겹치는게 있으면서 Off { SetRenderFlag( "arm", false ); } } } obj->SetParentTransform( &m_matResult ); } } bool KSeqAvatar::AddMesh( int nIndex, const char *filename ) { //TODO NX3LoadPack loadpack; loadpack.Init(); #ifdef _RAC KSeqObject *obj = KNX3Manager::GetManager()->CreateSequencer( filename, &loadpack, (KNX3Manager::SEQTYPE_ALL & (~KNX3Manager::SEQTYPE_CAMERA)) ); #else KSeqObject *obj = KNX3Manager::GetManager()->CreateSequencer( filename, &loadpack, (KNX3Manager::SEQTYPE_ALL) ); #endif AddMesh( nIndex, obj ); if( obj ) return true; else { #ifdef _DEBUG if( strlen(filename) > 0 ) _oprint( "!!!Resource Not Found (AddMesh) : %s\n", filename ); #endif return false; } return true; } void KSeqAvatar::AddDecoMesh( int nIndex, KSeqObject *obj ) { SAFE_DELETE( m_pDecoMeshPart[nIndex]); //이미 있는것 제거.. m_pDecoMeshPart[nIndex] = obj; m_bDecoMeshRender[nIndex] = FALSE; _CID( GETMESH_NAME ); if ( obj ) { m_bDecoMeshCheck = TRUE; m_bDecoMeshRender[nIndex] = TRUE; //몸통에 1st가 있으면, Foot, Hand의 겹치는 부분을 Off //없으면, Foot, Hand 에 2nd 가 붙으면, 몸통의 교차 부분 Off // //Hand, Foot 일 경우 Body와 겹치는 부분이 있으면, Body의 Mesh들을 Render Off 한다. /* if( nIndex == MDECOPART_FOOT ) { KMsgGET_MESHNAME msg; obj->Perform( id_GETMESH_NAME, msg ); //모두 On SetRenderFlag( "leg", TRUE ); for( unsigned int i(0); msg.vNameList.size()>i; i++ ) { const char * pName = msg.vNameList[i]; //상위 if( strstr( pName, "leg" ) != NULL ) //겹치는게 있으면서 Off { SetRenderFlag( "leg", FALSE ); } } } else if( nIndex == MDECOPART_HAND ) { KMsgGET_MESHNAME msg; obj->Perform( id_GETMESH_NAME, msg ); //모두 On SetRenderFlag( "arm", true ); for( unsigned int i(0); msg.vNameList.size()>i; i++ ) { const char * pName = msg.vNameList[i]; //하위 if( strstr( pName, "arm" ) != NULL ) //겹치는게 있으면서 Off { SetRenderFlag( "arm", false ); } } }*/ obj->SetParentTransform( &m_matResult ); } } bool KSeqAvatar::AddDecoMesh( int nIndex, const char *filename ) { //TODO NX3LoadPack loadpack; loadpack.Init(); #ifdef _RAC KSeqObject *obj = KNX3Manager::GetManager()->CreateSequencer( filename, &loadpack, (KNX3Manager::SEQTYPE_ALL & (~KNX3Manager::SEQTYPE_CAMERA)) ); #else KSeqObject *obj = KNX3Manager::GetManager()->CreateSequencer( filename, &loadpack, (KNX3Manager::SEQTYPE_ALL) ); #endif AddDecoMesh( nIndex, obj ); if( obj ) return true; else return false; return true; } //아바타 무기 링크들~ void KSeqAvatar::AddAttachItem( int nIndex, KSeqObject *obj ) { SAFE_DELETE( m_pItemPart[nIndex] ); m_pItemPart[nIndex] = static_cast(obj); _CID ( SETRENDER_FLAG ); if ( obj ) { m_bItemCheck = true; if( nIndex == ATTACH_HAND_LEFT ) { KMsgSET_RENDERFLAG rendermsg; rendermsg.pName = "right"; rendermsg.bRenderFlag = FALSE; obj->Perform( id_SETRENDER_FLAG, rendermsg); } else if( nIndex == ATTACH_HAND_RIGHT ) { KMsgSET_RENDERFLAG rendermsg; rendermsg.pName = "left"; rendermsg.bRenderFlag = FALSE; obj->Perform( id_SETRENDER_FLAG, rendermsg); } m_bItemRender[nIndex] = TRUE; obj->SetParentTransform( &m_matResult ); } } void KSeqAvatar::AddAttachItem( int nIndex, const char *filename ) { //UV Ani 있는 것이 있음. KSeqForm* obj = new KSeqForm; obj->AddAnimation( "default", filename, true ); obj->PlayAnimation( m_dwTime, "default", SEQTYPE_LOOP ); AddAttachItem( nIndex, obj ); //임시 //m_bRenderRotCube = true; } void KSeqAvatar::SetItemRenderFlag( int nIndex, BOOL bRenderFlag ) { m_bItemRender[nIndex] = bRenderFlag; } void KSeqAvatar::SetItemRenderFlag( BOOL bRenderFlag ) { _CID( SETRENDER_FLAG ); KMsgSET_RENDERFLAG msg; msg.bRenderFlag = bRenderFlag; msg.pName = "NULL"; for( int i(0); ATTACH_MAX>i; i++ ) { if( m_bItemRender[i] && m_pItemPart[i] ) m_pItemPart[i]->Perform( id_SETRENDER_FLAG , msg ); } } // Bone sequencer포인터를 직접 돌려줌 KBoneSeqObject* KSeqAvatar::getBoneSequencer() { if (m_pCurSeq) { return (KBoneSeqObject*)((KSequencer*)m_pCurSeq)->GetSeqObject(0); } return NULL; } //Perform로 바꾸자~ float KSeqAvatar::GetHeadZ() { if(m_pCurSeq) { KBoneSeqObject* pBoneSeq = (KBoneSeqObject*)((KSequencer*)m_pCurSeq)->GetSeqObject(0); if( pBoneSeq ) return pBoneSeq->GetHeadZ(); } return 0.f; } //Perform로 바꾸자~ void KSeqAvatar::GetHandPos( K3DVector &posLeft, K3DVector &posRight ) { if(m_pCurSeq) { KBoneSeqObject* pBoneSeq = (KBoneSeqObject*)((KSequencer*)m_pCurSeq)->GetSeqObject(0); if( pBoneSeq ) { pBoneSeq->GetHandLeft( posLeft ); pBoneSeq->GetHandRight( posRight ); } } } bool KSeqAvatar::PlayAnimation( DWORD dwCurTime, const char *name, int nAniType, float fPlayRate ) { /// 2011.01.25 false 체크 - prodongi if (!KSeqForm::PlayAnimation( dwCurTime, name, nAniType, fPlayRate )) return false; SetDeform(); //현재 애니메이션과 메쉬 스키닝 SetAttach(); //아이템 붙이기 SetAttachEffectPos(); //이펙트 위치 붙이기 SetAttachEffectBone(); return true; } bool KSeqAvatar::PlayOverride( DWORD dwCurTime, const char *name, float fPlayRate /* = 4.8f */ ) { if ( KSeqForm::PlayOverride( dwCurTime, name, fPlayRate ) == true ) { SetDeform(); SetAttach(); SetAttachEffectPos(); SetAttachEffectBone(); return true; } return false; } KSeqObject* KSeqAvatar::Clone() { KSeqAvatar *newobj = new KSeqAvatar; SeqObjList::iterator it = m_vSeqObj.begin(); //Animation while ( it != m_vSeqObj.end() ) { newobj->KSeqForm::AddAnimation( (*it)->strName.c_str(), (*it)->strFileName.c_str() ); ++it; } //살들~ for( int i(0); MPART_MAX>i; i++ ) { if( m_pMeshPart[i] ) newobj->AddMesh( i, m_pMeshPart[i]->Clone() ); } //치장용 for( int i(0); MDECOPART_MAX>i ; ++i ) { if( m_pDecoMeshPart[i] ) newobj->AddDecoMesh( i, m_pDecoMeshPart[i]->Clone() ); } //아이템들 for( int i(0); ATTACH_MAX>i; i++ ) { if( m_pItemPart[i] ) newobj->AddAttachItem( i, m_pItemPart[i]->Clone() ); } for( int i(0); EFFECT_POS_MAX>i; i++ ) { if( m_pEffectPos[i] ) newobj->AddEffectPos( i, m_pEffectPos[i]->Clone() ); } for( int i(0); BONE_EFFECT_MAX>i; i++ ) { if( m_pBoneEffect[i] ) newobj->AddBoneEffect( i, m_pBoneEffect[i]->Clone() ); } return (KSeqObject*)(newobj); } int KSeqAvatar::Process( DWORD dwTime ) { int process_state = KSeqForm::Process( dwTime ); if ( m_pCurSeq ) { KSequencer *kseq=dynamic_cast(m_pCurSeq); if (kseq!=NULL) kseq->Process( kseq->GetCurTime() ); } if ( isPendActivate() ) { SetDeform(); //현재 애니메이션과 메쉬 스키닝 SetAttach(); //아이템 붙이기 SetAttachEffectPos(); SetAttachEffectBone(); } //Mesh if( m_bMeshCheck ) { for( int i(0); MPART_MAX>i; i++ ) { if( m_bMeshRender[i] && m_pMeshPart[i] ) m_pMeshPart[i]->SetTime( dwTime ); } } if( m_bDecoMeshCheck ) { for( int i(0); MDECOPART_MAX>i ; ++i ) { if( m_bDecoMeshRender[i] && m_pDecoMeshPart[i] ) { const KInterval inter = m_pDecoMeshPart[i]->GetInterval(); if ((i == MDECOPART_SHOULDER || i == MDECOPART_SHOULDER2 ) && (inter.GetEnd() != 0)) // 어깨치창아이템이고 애니메이션이 있을 경우 재생 { /// 2012.08.13 꾸미기 어깨 이전 애니메이션 시간이 static으로 되어 있어서 한 유저의 꾸미기 어깨만 애니메이션이 되고 있었다. /// static을 클래스 멤버 변수로 바꿈, 그런데 왜 꾸미기 어깨만 따로 관리를 하고 있나?, /// SetAniTime에서도 SetTime을 하고 있는데, 왜 여기서 따로 관리를 하나? - prodongi if (0 == m_decoShoulderPrevTime) m_decoShoulderPrevTime = dwTime; DWORD advance = (DWORD)((dwTime - m_decoShoulderPrevTime) * 4.8f); DWORD nowTime = m_pDecoMeshPart[i]->GetCurTime(); DWORD newTime = nowTime + advance; newTime = newTime % inter.GetEnd(); m_pDecoMeshPart[i]->SetTime( newTime ); m_decoShoulderPrevTime = dwTime; } } } } //Item if( m_bItemCheck ) { for( int i(0); ATTACH_MAX>i; i++ ) { if( m_bItemRender[i] && m_pItemPart[i] ) m_pItemPart[i]->Process( dwTime ); } } //Effect Pos if( m_bEffectPosCheck ) { for( int i(0); EFFECT_POS_MAX>i; i++ ) { if( m_bEffectPos[i] && m_pEffectPos[i] ) m_pEffectPos[i]->SetTime( dwTime ); } } //Bone Effect if( m_bBoneEffectCheck ) { for( int i(0); BONE_EFFECT_MAX>i; i++ ) { if( m_bBoneEffect[i] && m_pBoneEffect[i] ) m_pBoneEffect[i]->Process( dwTime ); } } return process_state; } void KSeqAvatar::SetAniTime( DWORD dwTime ) { KSeqForm::SetAniTime(dwTime); //if( m_pCurSeq ) m_pCurSeq->SetTime( dwTime ); if ( m_pCurSeq ) { KSequencer *kseq=dynamic_cast(m_pCurSeq); if (kseq!=NULL) kseq->Process( kseq->GetCurTime() ); } //Mesh for( int i(0); MPART_MAX>i; i++ ) { if( m_bMeshRender[i] && m_pMeshPart[i] ) m_pMeshPart[i]->SetTime( dwTime ); } if( m_bDecoMeshCheck ) { for( int i(0); MDECOPART_MAX>i; ++i ) { if( m_bDecoMeshRender[i] && m_pDecoMeshPart[i] ) m_pDecoMeshPart[i]->SetTime( dwTime ); } } if( m_bItemCheck ) { //Item for( int i(0); ATTACH_MAX>i; i++ ) { if( m_bItemRender[i] && m_pItemPart[i] ) m_pItemPart[i]->Process( GetSafeTickCount() ); } } //Effect Pos if( m_bEffectPosCheck ) { for( int i(0); EFFECT_POS_MAX>i; i++ ) { if( m_bEffectPos[i] && m_pEffectPos[i] ) m_pEffectPos[i]->SetTime( dwTime ); } } //Bone Effect if( m_bBoneEffectCheck ) { for( int i(0); BONE_EFFECT_MAX>i; i++ ) { if( m_bBoneEffect[i] && m_pBoneEffect[i] ) m_pBoneEffect[i]->SetTime( dwTime ); } } } const char* KSeqAvatar::GetMeshSeqObjName( int nMeshIndex ) { if( nMeshIndex >= 0 && nMeshIndex < MPART_MAX ) { if( m_pMeshPart[nMeshIndex] ) return m_pMeshPart[nMeshIndex]->GetName(); } return NULL; } void *KSeqAvatar::MeshPerform( int nMeshIndex, KID id, KArg& msg ) { // Apply only to the skin mesh if( nMeshIndex >= 0 && nMeshIndex < MPART_MAX ) { if( m_pMeshPart[nMeshIndex] ) return m_pMeshPart[nMeshIndex]->Perform( id, msg ); } return NULL; } void *KSeqAvatar::DecoMeshPerform( int nMeshIndex, KID id, KArg& msg ) { //살~ Mesh 한테만~ if( nMeshIndex >= 0 && nMeshIndex < MPART_MAX ) { if( m_pDecoMeshPart[nMeshIndex] ) return m_pDecoMeshPart[nMeshIndex]->Perform( id, msg ); } return NULL; } void *KSeqAvatar::Perform( KID id, KArg& msg ) { _CID( SETBONEBLEND ); _CID( ITEM_RENDER ); _CID( SET_MTETEX ); if( id == id_SETBONEBLEND ) { KMsgGET_SETBONEBLEND *useBlend = static_cast(&msg); m_bUseBlend = useBlend->bUseBlend; return NULL; } //MTE if( id == id_SET_MTETEX ) { for( int i(0); MPART_MAX>i; i++ ) { if( m_pMeshPart[i] ) m_pMeshPart[i]->Perform( id, msg ); } return NULL; } if( id == id_ITEM_RENDER ) m_bItemCheck = !m_bItemCheck; if( m_bMeshCheck ) { //살~ Mesh 한테두~ for( int i(0); MPART_MAX>i; i++ ) { if( m_bMeshRender[i] && m_pMeshPart[i] ) m_pMeshPart[i]->Perform( id, msg ); } } if( m_bDecoMeshCheck ) { for( int i(0); MDECOPART_MAX>i ; ++i ) { if( m_bDecoMeshRender[i] && m_pDecoMeshPart[i] ) m_pDecoMeshPart[i]->Perform( id, msg ); } } if( m_bItemCheck ) { //Item for( int i(0); ATTACH_MAX>i; i++ ) { if( m_bItemRender[i] && m_pItemPart[i] ) m_pItemPart[i]->Perform( id, msg ); } } //Effect Pos 얻기 위함~ for( int i(0); EFFECT_POS_MAX>i; i++ ) { if( m_bEffectPos[i] && m_pEffectPos[i] ) m_pEffectPos[i]->Perform( id, msg ); } //Bone if ( m_pCurSeq ) { return m_pCurSeq->Perform( id, msg ); } return NULL; } // void *KSeqAvatar::PerformWithIgnoreMesh( KID id, KArg& msg, std::set* ignoreMeshList ) { _CID( SETBONEBLEND ); _CID( ITEM_RENDER ); // 2010.06.24 - prodongi _CID( SET_COLORIZE ); if( id == id_SETBONEBLEND ) { KMsgGET_SETBONEBLEND *useBlend = static_cast(&msg); m_bUseBlend = useBlend->bUseBlend; return NULL; } if( id == id_ITEM_RENDER ) m_bItemCheck = !m_bItemCheck; if( m_bMeshCheck ) { // 2010.06.24 - prodongi int oldMode; KMsgSET_COLORIZE* colorize; if (id == id_SET_COLORIZE) { colorize = static_cast(&msg); oldMode = colorize->nMode; } //살~ Mesh 한테두~ for( int i(0); MPART_MAX>i; i++ ) { if( m_bMeshRender[i] && m_pMeshPart[i] ) { if (ignoreMeshList) { std::set::iterator it = ignoreMeshList->find(i); if (it != ignoreMeshList->end()) continue; } // 2010.06.24 살이 없는 part는 알파값을 유지하도록 수정- prodongi if (id == id_SET_COLORIZE) { if (i >= MPART_L_SKIRT && i <= MPART_HELM) colorize->nMode = K3DTexture::COLORIZED_KEEP_ALPHA; else colorize->nMode = oldMode; } m_pMeshPart[i]->Perform( id, msg ); } } // 2010.07.09 복구 - prodongi if (id == id_SET_COLORIZE) { colorize->nMode = oldMode; } } if( m_bDecoMeshCheck ) { for( int i(0); MDECOPART_MAX>i ; ++i ) { if( m_bDecoMeshRender[i] && m_pDecoMeshPart[i] ) m_pDecoMeshPart[i]->Perform( id, msg ); } } if( m_bItemCheck ) { //Item for( int i(0); ATTACH_MAX>i; i++ ) { if( m_bItemRender[i] && m_pItemPart[i] ) m_pItemPart[i]->Perform( id, msg ); } } //Effect Pos 얻기 위함~ for( int i(0); EFFECT_POS_MAX>i; i++ ) { if( m_bEffectPos[i] && m_pEffectPos[i] ) m_pEffectPos[i]->Perform( id, msg ); } //Bone if ( m_pCurSeq ) { return m_pCurSeq->Perform( id, msg ); } return NULL; } void KSeqAvatar::Render( KViewportObject *viewport, DWORD flag, const K3DMatrix * pAttachMat ) { if ( m_pCurSeq ) { if ( m_pMatAttach != NULL && m_pMatParent != NULL ) { K3DMatrix matTemp; K3DMatrixIdentity( matTemp ); K3DMatrixMultiply( matTemp, *m_pMatAttach, *m_pMatParent ); K3DMatrixMultiply( m_matResult, m_matTransform, matTemp ); } else if ( m_pMatParent != NULL ) K3DMatrixMultiply( m_matResult, m_matTransform, *m_pMatParent ); else m_matResult = m_matTransform; m_pCurSeq->SetVisibility( m_fMasterVisibility ); m_pCurSeq->SetSkinDiffuse( m_SkinDiffuse ); m_pCurSeq->SetParentTransform( &m_matResult ); m_pCurSeq->Render( viewport ); //Mesh 그리기 if( m_sMeshRenderFlag && m_bMeshCheck ) { for( int i(0); MPART_MAX>i; i++ ) { if( m_bMeshRender[i] && m_pMeshPart[i] ) { m_pMeshPart[i]->SetVisibility( m_fMasterVisibility ); m_pMeshPart[i]->SetSkinDiffuse( m_SkinDiffuse ); m_pMeshPart[i]->Render(viewport, flag, m_pMatAttach); } } } //DecoMesh 그리기 if( m_bDecoMeshCheck ) { for( int i(0); MDECOPART_MAX > i; ++i ) { if( m_bDecoMeshRender[i] && m_pDecoMeshPart[i] ) { m_pDecoMeshPart[i]->SetVisibility( m_fMasterVisibility ); m_pDecoMeshPart[i]->SetSkinDiffuse( m_SkinDiffuse ); m_pDecoMeshPart[i]->Render(viewport, flag, m_pMatAttach); } } } //Item if( m_bItemCheck ) { for( int i(0); ATTACH_MAX>i; i++ ) { if( m_bItemRender[i] && m_pItemPart[i] ) { m_pItemPart[i]->SetVisibility( m_fMasterVisibility ); m_pItemPart[i]->Render(viewport, flag); } } } if( viewport->GetAttributes() & KViewportObject::VIEWPORT_GAME ) { //Effect Pos if( m_bEffectPosRenderFlag && m_bEffectPosCheck ) { //Le rendu doit être effectué en raison de l'emplacement du SeqPoint. Pour vérifier l'emplacement, désactivez l'indicateur de rendu. for( int i(0); EFFECT_POS_MAX>i; i++ ) { if( m_bEffectPos[i] && m_pEffectPos[i] ) { //TODO : 임시 사각 박스 끄기, 추후에 제대로 되게 수정 요. //m_pEffectPos[i]->Perform( id_SETFORCERENDER_FLAG, NULL ); m_pEffectPos[i]->Render(viewport, flag); } } } //Bone Effect if( m_bBoneEffectCheck ) { for( int i(0); BONE_EFFECT_MAX>i; i++ ) { if( m_bBoneEffect[i] && m_pBoneEffect[i] ) { m_pBoneEffect[i]->SetVisibility( m_fMasterVisibility ); m_pBoneEffect[i]->Render(viewport, flag); } } } if( m_bRenderRotCube ) GetBoundCube()->Render( viewport ); } } } //void KSeqAvatar::SetAttachBone( const K3DMatrix *pMatParent, const K3DMatrix *pMatAttach ) //{ // _oprint( "KSeqAvatar::SetAttachBone\n" ); // // if( m_pCurSeq ) // m_pCurSeq->SetAttachBone( pMatParent, pMatAttach ); //} //현재 Animation에 Attach void KSeqAvatar::SetAttach() { if( m_pCurSeq ) { for( int i(0); ATTACH_MAX>i; i++ ) { if( m_bItemRender[i] && m_pItemPart[i] ) { m_pCurSeq->SetAttach( i, m_pItemPart[i] ); } } } } void KSeqAvatar::SetAttachEffectPos() { if( m_pCurSeq ) { for( int i(0); EFFECT_POS_MAX>i; i++ ) { if( m_bEffectPos[i] && m_pEffectPos[i] ) { //Top, Middle 일때만, 뼈에 Link if( i == EFFECT_POS_TOP || i == EFFECT_POS_MIDDLE || i == EFFECT_POS_SADDLE || i == EFFECT_POS_W_LEFT || i == EFFECT_POS_W_RIGHT || i == EFFECT_POS_W_TWOHAND ) m_pCurSeq->SetAttachEffectPos( i, m_pEffectPos[i] ); } } } } void KSeqAvatar::SetAttachEffectBone() { if( m_pCurSeq ) { _CID( GETBONEMATRIX3 ); for( int i(0); BONE_EFFECT_MAX>i; i++ ) { if( m_bBoneEffect[i] && m_pBoneEffect[i] && m_nBoneEffectIndex[i] != -1 ) { KMsgGET_BONEMATRIX3 msg; msg.nBoneIndex = m_nBoneEffectIndex[i]; Perform( id_GETBONEMATRIX3, msg ); m_pBoneEffect[i]->SetParentTransform( m_pMatParent, msg.pBoneMat ); // m_pCurSeq->SetAttachEffectBone( m_nBoneEffectIndex[i], m_pBoneEffect[i] ); } } } } void KSeqAvatar::SetParentTransform( const K3DMatrix *pMatParent, const K3DMatrix *pMatAttach, BOOL bRotationLock ) { m_pMatParent = pMatParent; m_pMatAttach = pMatAttach; //뭔가 이상함... for( int i(0); MPART_MAX>i; i++ ) { if( m_bMeshRender[i] && m_pMeshPart[i] ) { m_pMeshPart[i]->SetParentTransform(pMatParent, pMatAttach, bRotationLock); } } if( m_bDecoMeshCheck ) { for( int i(0); MDECOPART_MAX > i; ++i ) { if( m_bDecoMeshRender[i] && m_pDecoMeshPart[i] ) { if (i == MDECOPART_SHOULDER || i == MDECOPART_SHOULDER2 ) { if (m_pDecoMeshPart[i]->GetAttachTransform() == NULL) m_pDecoMeshPart[i]->SetParentTransform( pMatParent, pMatAttach, bRotationLock ); else m_pDecoMeshPart[i]->SetParentTransform( pMatParent, m_pDecoMeshPart[i]->GetAttachTransform(), bRotationLock ); } else m_pDecoMeshPart[i]->SetParentTransform( pMatParent, pMatAttach, bRotationLock ); } } } #ifndef _RAC //뭐하는 코드 였지?? - -;; if( m_pCurSeq ) { m_pCurSeq->SetParentTransform( pMatParent, pMatAttach, bRotationLock ); } #endif } //현재 채널과 Deform void KSeqAvatar::SetDeform() { //뼈를 Mesh들에게 Deform if( m_pCurSeq ) { //모든 Mesh에게 뼈 설정. for( int i(0); MPART_MAX>i; i++ ) { if( m_pMeshPart[i] ) m_pCurSeq->SetDeform( m_pMeshPart[i] ); } if( m_bDecoMeshCheck ) { for( int i(0); MDECOPART_MAX > i; ++i ) { if( m_pDecoMeshPart[i] ) m_pCurSeq->SetDeform( m_pDecoMeshPart[i] ); } } } } void KSeqAvatar::SetMeshRenderFlag( int nIndex, BOOL bRenderFlag ) { if( nIndex < MPART_MAX ) m_bMeshRender[nIndex] = bRenderFlag; } void KSeqAvatar::SetDecoMeshRenderFlag( int nIndex, BOOL bRenderFlag ) { if( nIndex < MDECOPART_MAX ) m_bDecoMeshRender[nIndex] = bRenderFlag; } //교차 부위 없애기~ void KSeqAvatar::SetRenderFlag( const char * pStr, BOOL bRenderFlag ) { _CID( SETRENDER_FLAG ); KMsgSET_RENDERFLAG rendermsg; rendermsg.pName = pStr; rendermsg.bRenderFlag = bRenderFlag; if( m_pMeshPart[MPART_BODY] && m_bMeshRender[MPART_BODY] ) m_pMeshPart[MPART_BODY]->Perform( id_SETRENDER_FLAG, rendermsg); } //몬스터 같은 경우는 없다. void KSeqAvatar::Weld(int nIndex) { } void KSeqAvatar::GetFrameInfo( const char * strKey, int &nBoneCount, DWORD &dwMinTime, DWORD &dwMaxTime ) { KSeqObject *obj = GetAnimation( strKey ); _CID( GETBONEINFO ); KMsgGET_BONEINFO msg; if( obj && obj->Perform( id_GETBONEINFO, msg ) ) { nBoneCount = msg.nBoneCount; dwMinTime = msg.dwMinTime ; dwMaxTime = msg.dwMaxTime ; } } bool KSeqAvatar::CheckPendingSeq() { return KSeqForm::CheckPendingSeq(); } // sfreer 임시코드임. 인벤토리 창에 나오는 아바타에서 방패 장착시 표시 안되0 버그을 위해 추가한 함수. 2009.03.09 bool KSeqAvatar::PlayAnimation_temp( DWORD dwCurTime, const char *name, int nAniType, float fPlayRate ) { KSeqForm::PlayAnimation( dwCurTime, name, nAniType, fPlayRate ); if( m_bItemCheck ) { for( int i(0); ATTACH_MAX>i; i++ ) { if( m_bItemRender[i] && m_pItemPart[i] ) { //if( m_pItemPart[i]->GetAnimation("default") != NULL) { //_oprint("KSeqAvatar::PlayAnimation_temp - default 애니메이션이 없음으로 아이템(방패등) 출력이 안되니 주의바람." ); m_pItemPart[i]->PlayAnimation(dwCurTime, "default"/*GetCurrentAnimationName()*/, nAniType, fPlayRate); } } } } SetDeform(); //현재 애니메이션과 메쉬 스키닝 SetAttach(); //아이템 붙이기 SetAttachEffectPos(); //이펙트 위치 붙이기 SetAttachEffectBone(); return true; }