DragonNest/Common/EternityEngine/EtMergedSkin.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

355 lines
No EOL
13 KiB
C++

#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<std::string> 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<std::string> *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();
}
}