#include "StdAfx.h" #include "EtSkin.h" #include "EtMesh.h" #include "EtLoader.h" #include "EtCustomParam.h" #include "EtMergedSkin.h" #ifdef _DEBUG #define new new(_NORMAL_BLOCK,__FILE__,__LINE__) #endif #define MASK_TEXTURE_SCALE 2 CEtMergedSkin::CEtMergedSkin() { m_bDeleteImmediate = true; m_nTextureWidth = 512; m_nTextureHeight = 512; } CEtMergedSkin::~CEtMergedSkin() { // EtSkin µð½ºÆ®·°ÅÍ¿¡¼­ Áö¿öÁֱ⠶§¹®¿¡ ¿©±â¼­ Áö¿ï ÇÊ¿ä ¾ø´Ù. // SAFE_RELEASE_SPTR( m_hCombineTexture ); // SAFE_RELEASE_SPTR( m_hCombineMaskTexture ); SAFE_RELEASE_SPTR( m_MeshHandle ); } EtVector4 CEtMergedSkin::MergeTexture( EtTextureHandle hTexture, EtTextureHandle hMaskTexture, int nMergeOrder, RECT TextureRect ) { EtVector4 ScaleBias; ScaleBias.x = ( TextureRect.right - TextureRect.left ) / ( float )m_nTextureWidth; ScaleBias.y = ( TextureRect.bottom - TextureRect.top ) / ( float )m_nTextureHeight; ScaleBias.z = TextureRect.left / ( float )m_nTextureWidth;; ScaleBias.w = TextureRect.top / ( float )m_nTextureHeight; if( ( m_hCombineTexture ) && ( m_hCombineTexture->GetTexturePtr() ) && ( hTexture ) && ( hTexture->GetTexturePtr() ) ) { EtSurface *pCombineSurface = m_hCombineTexture->GetSurfaceLevel(); EtSurface *pSourSurface = hTexture->GetSurfaceLevel(); D3DXLoadSurfaceFromSurface( pCombineSurface, NULL, &TextureRect, pSourSurface, NULL, NULL, D3DX_DEFAULT, 0 ); } if( ( m_hCombineMaskTexture ) && ( m_hCombineMaskTexture->GetTexturePtr() ) && ( hMaskTexture ) && ( hMaskTexture->GetTexturePtr() ) ) { TextureRect.left /= MASK_TEXTURE_SCALE; TextureRect.right /= MASK_TEXTURE_SCALE; TextureRect.top /= MASK_TEXTURE_SCALE; TextureRect.bottom /= MASK_TEXTURE_SCALE; EtSurface *pCombineSurface = m_hCombineMaskTexture->GetSurfaceLevel(); EtSurface *pSourSurface = hMaskTexture->GetSurfaceLevel(); D3DXLoadSurfaceFromSurface( pCombineSurface, NULL, &TextureRect, pSourSurface, NULL, NULL, D3DX_DEFAULT, 0 ); } return ScaleBias; } bool CEtMergedSkin::Assign( EtSkinHandle hSkin, RECT TextureRect ) { m_SkinHeader = hSkin->m_SkinHeader; m_vecSubSkinHeader = hSkin->m_vecSubSkinHeader; m_vecMaterialHandle = hSkin->m_vecMaterialHandle; int i, nSize; nSize = (int)m_vecMaterialHandle.size(); for( i = 0; i < nSize; i++) { m_vecMaterialHandle[i]->AddRef(); } m_vecCustomParam = hSkin->m_vecCustomParam; m_IsAlphaTextureList = hSkin->m_IsAlphaTextureList; m_hCombineTexture = CEtTexture::CreateNormalTexture( m_nTextureWidth, m_nTextureHeight, FMT_DXT1, USAGE_DEFAULT, POOL_MANAGED ); if( !m_hCombineTexture || m_hCombineTexture->GetTexturePtr() == NULL ) { return false; } EtParameterHandle hEmissiveParam = m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissiveColor" ); EtParameterHandle hPowerParam = m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissivePower" ); EtParameterHandle hRangeParam = m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissivePowerRange" ); EtParameterHandle hAniSpeedParam = m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissiveAniSpeed" ); int *pTextureIndex = NULL, *pMaskTextureIndex = NULL; if( !m_vecCustomParam.empty() ) { for( int j = 0; j < ( int )m_vecCustomParam[ 0 ].size(); j++ ) { if( m_vecCustomParam[ 0 ][ j ].Type == EPT_TEX ) { if( m_vecCustomParam[ 0 ][ j ].nTextureIndex != -1 ) { if( !pTextureIndex ) { pTextureIndex = &m_vecCustomParam[ 0 ][ j ].nTextureIndex; } else { ASSERT( pMaskTextureIndex == NULL ); pMaskTextureIndex = &m_vecCustomParam[ 0 ][ j ].nTextureIndex; } } } else if( hEmissiveParam != -1 && m_vecCustomParam[ 0 ][ j ].hParamHandle == hEmissiveParam ) { memcpy(&m_EmissiveParam[ 0 ].Color, m_vecCustomParam[ 0 ][ j ].fFloat4, sizeof(float)*4); m_vecCustomParam[ 0 ][ j ].nVariableCount = 1; } else if( hPowerParam != -1 && m_vecCustomParam[ 0 ][ j ].hParamHandle == hPowerParam ) { m_EmissiveParam[ 0 ].fPower = m_vecCustomParam[ 0 ][ j ].fFloat; } else if( hRangeParam != -1 && m_vecCustomParam[ 0 ][ j ].hParamHandle == hRangeParam ) { m_EmissiveParam[ 0 ].fRange = m_vecCustomParam[ 0 ][ j ].fFloat; } else if( hAniSpeedParam != -1 && m_vecCustomParam[ 0 ][ j ].hParamHandle == hAniSpeedParam ) { m_EmissiveParam[ 0 ].fAniSpeed = m_vecCustomParam[ 0 ][ j ].fFloat; } } } EtTextureHandle hTexture, hMaskTexture; if( pTextureIndex ) { hTexture = CEtResource::GetSmartPtr( *pTextureIndex ); } if( !hTexture ) return false; if( pMaskTextureIndex ) { hMaskTexture = CEtResource::GetSmartPtr( *pMaskTextureIndex ); m_hCombineMaskTexture = CEtTexture::CreateNormalTexture( m_nTextureWidth / MASK_TEXTURE_SCALE, m_nTextureHeight / MASK_TEXTURE_SCALE, FMT_DXT1, USAGE_DEFAULT, POOL_MANAGED ); if( !m_hCombineMaskTexture || m_hCombineMaskTexture->GetTexturePtr() == NULL ) { return false; } int nStride; char *pPtr = ( char * )m_hCombineMaskTexture->Lock( nStride ); if( pPtr ) { // dxt1 ÀÌ¶ó¼­ ¾ÐÃàµÇ À־.. Height ³ª´©±â 4 ÇØÁá´Ù. memset( pPtr, 0, nStride * m_hCombineMaskTexture->Height() / 4 ); } m_hCombineMaskTexture->Unlock(); } EtVector4 ScaleBias = MergeTexture( hTexture, hMaskTexture, 0, TextureRect ); if( pTextureIndex ) { *pTextureIndex = m_hCombineTexture->GetMyIndex(); } if( pMaskTextureIndex ) { *pMaskTextureIndex = m_hCombineMaskTexture->GetMyIndex(); } m_nAlphaParamIndex = hSkin->m_nAlphaParamIndex; m_DiffuseTexIndexList.resize(1); m_DiffuseTexIndexList[0] = m_hCombineTexture->GetMyIndex(); m_vecTehiniqueIndex = hSkin->m_vecTehiniqueIndex; m_hShadowMaterial = hSkin->m_hShadowMaterial; hSkin->m_hShadowMaterial->AddRef(); m_MeshHandle = (new CEtMesh)->GetMySmartPtr(); m_MeshHandle->Assign( hSkin->m_MeshHandle, ScaleBias ); return true; } #ifdef PRE_MOD_WARRIOR_RIGHTHAND void CEtMergedSkin::Merge( EtSkinHandle hSkin, RECT TextureRect, CEtSkinInstance *pSkinInstance ) #else void CEtMergedSkin::Merge( EtSkinHandle hSkin, RECT TextureRect ) #endif // #ifdef PRE_MOD_WARRIOR_RIGHTHAND { if( !hSkin->GetMeshHandle() || hSkin->GetMeshHandle()->GetSubMeshCount() == 0 ) return; EtParameterHandle hSourceEmissiveParam = hSkin->m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissiveColor" ); EtParameterHandle hSourcePowerParam = m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissivePower" ); EtParameterHandle hSourceRangeParam = m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissivePowerRange" ); EtParameterHandle hSourceAniSpeedParam = m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissiveAniSpeed" ); int nSourceEmissiveParamIndex = -1; int nSourcePowerParamIndex = -1; int nSourceRangeParamIndex = -1; int nSourceAniSpeedParamIndex = -1; int nSourceTextureIndex = -1, nSourceMaskTextureIndex = -1; if( !m_vecCustomParam.empty() ) { for( int j = 0; j < ( int )m_vecCustomParam[ 0 ].size(); j++ ) { if( m_vecCustomParam[ 0 ][ j ].Type == EPT_TEX ) { if( m_vecCustomParam[ 0 ][ j ].nTextureIndex != -1 ) { if( nSourceTextureIndex == -1 ) { nSourceTextureIndex = m_vecCustomParam[ 0 ][ j ].nTextureIndex; } else { ASSERT( nSourceMaskTextureIndex == -1 ); nSourceMaskTextureIndex = m_vecCustomParam[ 0 ][ j ].nTextureIndex; } } } else if( hSourceEmissiveParam != -1 && m_vecCustomParam[ 0 ][ j ].hParamHandle == hSourceEmissiveParam ) { nSourceEmissiveParamIndex = j; } else if( hSourcePowerParam != -1 && m_vecCustomParam[ 0 ][ j ].hParamHandle == hSourcePowerParam ) { nSourcePowerParamIndex = j; } else if( hSourceRangeParam != -1 && m_vecCustomParam[ 0 ][ j ].hParamHandle == hSourceRangeParam ) { nSourceRangeParamIndex = j; } else if( hSourceAniSpeedParam != -1 && m_vecCustomParam[ 0 ][ j ].hParamHandle == hSourceAniSpeedParam ) { nSourceAniSpeedParamIndex = j; } } } if( nSourceTextureIndex == -1 ) { return; } EtParameterHandle hEmissiveParam = hSkin->m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissiveColor" ); EtParameterHandle hPowerParam = hSkin->m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissivePower" ); EtParameterHandle hRangeParam = hSkin->m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissivePowerRange" ); EtParameterHandle hAniSpeedParam = hSkin->m_vecMaterialHandle[ 0 ]->GetParameterByName( "g_EmissiveAniSpeed" ); int nDestTextureIndex = -1, nDestMaskTextureIndex = -1; int nMergeOrder = 0; if( nSourceEmissiveParamIndex != -1 ) { nMergeOrder = m_vecCustomParam[ 0 ][ nSourceEmissiveParamIndex ].nVariableCount; } if( !hSkin->m_vecCustomParam.empty() ) { for( int j = 0; j < ( int )hSkin->m_vecCustomParam[ 0 ].size(); j++ ) { if( hSkin->m_vecCustomParam[ 0 ][ j ].Type == EPT_TEX ) { if( hSkin->m_vecCustomParam[ 0 ][ j ].nTextureIndex != -1 ) { if( nDestTextureIndex == -1 ) { nDestTextureIndex = hSkin->m_vecCustomParam[ 0 ][ j ].nTextureIndex; } else { ASSERT( nDestMaskTextureIndex == -1 ); nDestMaskTextureIndex = hSkin->m_vecCustomParam[ 0 ][ j ].nTextureIndex; } } } else if( nSourceEmissiveParamIndex != -1 && hEmissiveParam != -1 && hSkin->m_vecCustomParam[ 0 ][ j ].hParamHandle == hEmissiveParam ) { memcpy(&m_EmissiveParam[ nMergeOrder ].Color, hSkin->m_vecCustomParam[ 0 ][ j ].fFloat4, sizeof(EtColor) ); m_vecCustomParam[ 0 ][ nSourceEmissiveParamIndex ].nVariableCount++; m_vecCustomParam[ 0 ][ nSourceEmissiveParamIndex ].pPointer = (void *)m_EmissiveParam; } else if( nSourcePowerParamIndex != -1 && hPowerParam != -1 && hSkin->m_vecCustomParam[ 0 ][ j ].hParamHandle == hPowerParam ) { m_EmissiveParam[ nMergeOrder ].fPower = hSkin->m_vecCustomParam[ 0 ][ j ].fFloat; m_vecCustomParam[ 0 ][ nSourcePowerParamIndex ].nVariableCount++; } else if( nSourceRangeParamIndex != -1 && hRangeParam != -1 && hSkin->m_vecCustomParam[ 0 ][ j ].hParamHandle == hRangeParam ) { m_EmissiveParam[ nMergeOrder ].fRange = hSkin->m_vecCustomParam[ 0 ][ j ].fFloat; m_vecCustomParam[ 0 ][ nSourceRangeParamIndex ].nVariableCount++; } else if( nSourceAniSpeedParamIndex != -1 && hAniSpeedParam != -1 && hSkin->m_vecCustomParam[ 0 ][ j ].hParamHandle == hAniSpeedParam ) { m_EmissiveParam[ nMergeOrder ].fAniSpeed = hSkin->m_vecCustomParam[ 0 ][ j ].fFloat; m_vecCustomParam[ 0 ][ nSourceAniSpeedParamIndex ].nVariableCount++; } } } if( nDestTextureIndex == -1 ) { return; } EtTextureHandle hTexture = CEtResource::GetSmartPtr( nDestTextureIndex ); EtTextureHandle hMaskTexture; if( !m_hCombineTexture || !hTexture ) return; if( nDestMaskTextureIndex != -1 ) { hMaskTexture = CEtResource::GetSmartPtr( nDestMaskTextureIndex ); } EtVector4 ScaleBias = MergeTexture( hTexture, hMaskTexture, nMergeOrder, TextureRect ); std::map< std::string, int > BoneSets; int j, nBoneSize; std::vector BoneNames; for( j = 0; j < hSkin->GetMeshHandle()->GetSubMeshCount(); j++) { if( hSkin->IsAlphaTexture( j ) ) { // ¾ËÆÄÅØ½ºÃİ¡ ´Ü Çϳª¶óµµ ÀÖÀ¸¸é TRUE m_IsAlphaTextureList[ 0 ] = TRUE; } for( int k = 0; k < (int)hSkin->GetMeshHandle()->GetSubMesh(j)->GetBoneName().size(); k++ ) { BoneNames.push_back( hSkin->GetMeshHandle()->GetSubMesh(j)->GetBoneName()[k] ); } } nBoneSize = (int)BoneNames.size(); for( j = 0; j < nBoneSize; j++) { BoneSets.insert( std::make_pair(BoneNames[j], 0) ); } std::vector *pThisBoneNames = NULL; if( GetMeshHandle()->GetSubMeshCount() > 0 ) { pThisBoneNames = &GetMeshHandle()->GetSubMesh(0)->GetBoneName(); } if( pThisBoneNames ) { nBoneSize = (int)pThisBoneNames->size(); for( j = 0; j < nBoneSize; j++) { BoneSets.insert( std::make_pair( (*pThisBoneNames)[j], 0) ); } } std::map< std::string, int >::iterator it = BoneSets.begin(); int nCount = 0; while( it != BoneSets.end() ) { it->second = nCount++; ++it; } std::vector< int > boneRemapTable; if( pThisBoneNames ) { for( j = 0; j < nBoneSize; j++) { int nIndex = BoneSets[ (*pThisBoneNames)[j] ] ; boneRemapTable.push_back( nIndex ); } GetMeshHandle()->GetSubMesh(0)->GetMeshStream()->RemapBoneIndices( boneRemapTable ); } GetMeshHandle()->GetSubMesh(0)->RemoveLinkInfo(); if( pThisBoneNames ) { it = BoneSets.begin(); while( it != BoneSets.end() ) { (*pThisBoneNames).push_back( it->first ); ++it; } } for( j = 0; j < hSkin->GetMeshHandle()->GetSubMeshCount(); j++) { #ifdef PRE_MOD_WARRIOR_RIGHTHAND if( pSkinInstance && pSkinInstance->GetSkinRenderInfo( j ) && !pSkinInstance->GetSkinRenderInfo( j )->bShowSubmesh ) continue; #endif // #ifdef PRE_MOD_WARRIOR_RIGHTHAND nBoneSize = (int)hSkin->GetMeshHandle()->GetSubMesh(j)->GetBoneName().size(); boneRemapTable.clear(); for( int k = 0; k < nBoneSize; k++) { assert(BoneSets.count( hSkin->GetMeshHandle()->GetSubMesh(j)->GetBoneName()[k]) != 0); int nIndex = BoneSets[ hSkin->GetMeshHandle()->GetSubMesh(j)->GetBoneName()[k] ] ; boneRemapTable.push_back( nIndex ); } GetMeshHandle()->GetSubMesh(0)->GetMeshStream()->Attach( hSkin->GetMeshHandle()->GetSubMesh(j)->GetMeshStream(), boneRemapTable, ScaleBias , nMergeOrder); } } void CEtMergedSkin::BuildMipmap() { if( m_hCombineTexture ) { m_hCombineTexture->BuildMipmap(); } }