Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1572 lines
34 KiB
C++
1572 lines
34 KiB
C++
// Z3DGeneralChrModel.cpp: implementation of the CZ3DGeneralChrModel class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
//#include "winsock2.h"
|
|
//#include "FunctionPerformanceCheck.h"
|
|
#include "Z3DGeneralChrModel.h"
|
|
#include "RenderOption.h"
|
|
#include "BaseDataDefine.h"
|
|
|
|
#include <io.h>
|
|
|
|
|
|
|
|
std::map<Z3DTOK, CZ3DGCMDS*> CZ3DGeneralChrModel::ms_mapTok2GCMDS;
|
|
|
|
|
|
bool CZ3DGeneralChrModel::_BuildCMDSList( const char* szFileSpec )
|
|
{
|
|
SimpleString strFullPath( ms_strDataPath, szFileSpec );
|
|
char* szFileNamePart;
|
|
Z3DTOK tokFileName;
|
|
CZ3DGCMDS* pGCMDS;
|
|
|
|
_finddata_t fileinfo;
|
|
long lFindHandle = _findfirst( strFullPath, &fileinfo );
|
|
|
|
if( -1 == lFindHandle )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
do
|
|
{
|
|
szFileNamePart = strrchr( fileinfo.name, '\\' );
|
|
if( NULL == szFileNamePart )
|
|
{
|
|
szFileNamePart = fileinfo.name;
|
|
}
|
|
else
|
|
{
|
|
++szFileNamePart;
|
|
}
|
|
|
|
tokFileName = g_TokFileName.Add( szFileNamePart );
|
|
pGCMDS = new CZ3DGCMDS;
|
|
if( false == pGCMDS->Load( fileinfo.name, ms_strDataPath ) )
|
|
{
|
|
SAFE_DELETE( pGCMDS );
|
|
return false;
|
|
}
|
|
if( ms_mapTok2GCMDS.end() != ms_mapTok2GCMDS.find( tokFileName ) )
|
|
{
|
|
SAFE_DELETE( pGCMDS );
|
|
return false;
|
|
}
|
|
ms_mapTok2GCMDS[tokFileName] = pGCMDS;
|
|
|
|
} while( 0 == _findnext( lFindHandle, &fileinfo ) );
|
|
|
|
_findclose( lFindHandle );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::_ClearCMDSList()
|
|
{
|
|
std::map<Z3DTOK, CZ3DGCMDS*>::iterator it;
|
|
|
|
for( it = ms_mapTok2GCMDS.begin(); it != ms_mapTok2GCMDS.end(); it++ )
|
|
{
|
|
SAFE_DELETE( it->second );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::_RetrieveCMDSNameList( std::vector<const char*>& r_vecList )
|
|
{
|
|
std::map<Z3DTOK, CZ3DGCMDS*>::iterator it;
|
|
|
|
for( it = ms_mapTok2GCMDS.begin(); it != ms_mapTok2GCMDS.end(); it++ )
|
|
{
|
|
r_vecList.push_back( g_TokFileName.GetString( it->first ) );
|
|
}
|
|
}
|
|
|
|
|
|
CZ3DGCMDS* CZ3DGeneralChrModel::_GetGCMDSByName( const char* szFilename )
|
|
{
|
|
Z3DTOK tokFileName = g_TokFileName.GetTOK( szFilename );
|
|
if( NULL_TOK == tokFileName )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::map<Z3DTOK, CZ3DGCMDS*>::iterator it;
|
|
if( ms_mapTok2GCMDS.end() == (it = ms_mapTok2GCMDS.find(tokFileName)) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return it->second;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CZ3DGeneralChrModel::CZ3DGeneralChrModel()
|
|
{
|
|
m_pSkeletonObjects = NULL;
|
|
|
|
m_pSkin = NULL;
|
|
m_pPseudoCloth = NULL;
|
|
|
|
//m_pTokCurrentAniKeyPackFile = NULL;
|
|
m_pTagAniKeyPack = NULL;
|
|
m_pAniHolder = NULL;
|
|
m_pEventGenerator = NULL;
|
|
|
|
m_pTagAddonAniKeyPack = NULL;
|
|
m_pAddonAniHolder = NULL;
|
|
m_pAddonEventGenerator = NULL;
|
|
|
|
m_fScaleFactor = 1.0f;
|
|
|
|
m_rpCurrentMotionSheet = NULL;
|
|
m_tokCurrentMotionSheet = NULL_TOK;
|
|
|
|
m_pBoundingCylinder = NULL;
|
|
|
|
m_bInitialized = false;
|
|
|
|
m_bAniTestMode = false;
|
|
m_fFixHeight = 0.0f;
|
|
}
|
|
|
|
CZ3DGeneralChrModel::~CZ3DGeneralChrModel()
|
|
{
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator itA;
|
|
for( itA = m_mapAttachmentSlot.begin(); itA != m_mapAttachmentSlot.end(); itA++ )
|
|
{
|
|
Z3D_TOK_N_ATTACHMENT tna = itA->second;
|
|
|
|
if( itA->second.pAttachment )
|
|
{
|
|
itA->second.pAttachment->UnLink();
|
|
SAFE_DELETE( itA->second.pAttachment );
|
|
}
|
|
}
|
|
|
|
if( m_pSkeletonObjects )
|
|
{
|
|
m_pSkeletonObjects[0].UnLink();
|
|
}
|
|
SAFE_DELETEA( m_pSkeletonObjects );
|
|
|
|
SAFE_DELETE( m_pSkin );
|
|
SAFE_DELETE( m_pPseudoCloth );
|
|
|
|
//SAFE_DELETEA( m_pTokCurrentAniKeyPackFile );
|
|
SAFE_DELETEA( m_pTagAniKeyPack );
|
|
SAFE_DELETEA( m_pAniHolder );
|
|
SAFE_DELETEA( m_pEventGenerator );
|
|
|
|
SAFE_DELETEA( m_pTagAddonAniKeyPack );
|
|
SAFE_DELETEA( m_pAddonAniHolder );
|
|
SAFE_DELETEA( m_pAddonEventGenerator );
|
|
|
|
std::map<Z3DTOK, Z3DTOK_OVERLAY_SLOT*>::iterator itO;
|
|
for( itO = m_mapOutfitSlot.begin(); itO != m_mapOutfitSlot.end(); itO++ )
|
|
{
|
|
SAFE_DELETE( itO->second );
|
|
}
|
|
|
|
SAFE_DELETEA( m_pBoundingCylinder );
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::Init( const char* szGCMDSname )
|
|
{
|
|
if( m_bInitialized )
|
|
{
|
|
return false; // trying to initialize more than one time on this instance
|
|
}
|
|
|
|
Z3DTOK tokFileName = g_TokFileName.GetTOK( szGCMDSname );
|
|
if( NULL_TOK == tokFileName )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::map<Z3DTOK, CZ3DGCMDS*>::iterator it;
|
|
if( ms_mapTok2GCMDS.end() == (it = ms_mapTok2GCMDS.find(tokFileName)) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_rpGCMDS = it->second;
|
|
|
|
// allocating skeleton obejct & setting hierarchy
|
|
if( false == m_rpGCMDS->AllocSkeleton( m_pSkeletonObjects ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_pSkin = new CZ3DMultipartSkin( m_rpGCMDS->GetMPT() );
|
|
m_pPseudoCloth = new CZ3DPseudoCloth();
|
|
m_pPseudoCloth->Link( NULL );
|
|
|
|
m_pSkin->SetSkeleton( m_pSkeletonObjects, m_rpGCMDS->GetSkeletonCount() );
|
|
|
|
m_pSkin->SetSkeletonLocalizer( m_rpGCMDS->GetLocalizerMatrix() );
|
|
|
|
//m_pTokCurrentAniKeyPackFile = new Z3DTOK[m_rpGCMDS->GetAniHolderCount()];
|
|
m_pTagAniKeyPack = new H3DAniKeyPackTag[m_rpGCMDS->GetAniHolderCount()];
|
|
m_pAniHolder = new Z3DAniHolder[m_rpGCMDS->GetAniHolderCount()];
|
|
m_pEventGenerator = new CZ3DChrEventGenerator[m_rpGCMDS->GetAniHolderCount()];
|
|
|
|
m_pTagAddonAniKeyPack = new H3DAniKeyPackTag[m_rpGCMDS->GetAniHolderCount()];
|
|
m_pAddonAniHolder = new Z3DAniHolder[m_rpGCMDS->GetAniHolderCount()];
|
|
m_pAddonEventGenerator = new CZ3DChrEventGenerator[m_rpGCMDS->GetAniHolderCount()];
|
|
|
|
m_AniMixer.Init( m_pSkeletonObjects, m_pAniHolder, m_pAddonAniHolder,
|
|
m_rpGCMDS->GetSkeletonCount(), m_rpGCMDS->GetAniHolderCount() );
|
|
|
|
const std::vector<Z3DTOK>* p_vecTok;
|
|
p_vecTok = m_rpGCMDS->GetStaticSlotVector();
|
|
for( int i = 0; i < p_vecTok->size(); ++i )
|
|
{
|
|
m_mapStaticSlot[(*p_vecTok)[i]] = NULL_TOK;
|
|
}
|
|
|
|
const std::vector<long>* p_vecOverlayCount = m_rpGCMDS->GetOutfitSlotOverlayVector();
|
|
p_vecTok = m_rpGCMDS->GetOutfitSlotVector();
|
|
Z3DTOK_OVERLAY_SLOT* pSlot = NULL;
|
|
for( i = 0; i < p_vecTok->size(); ++i )
|
|
{
|
|
pSlot = new Z3DTOK_OVERLAY_SLOT;
|
|
pSlot->Alloc( (*p_vecOverlayCount)[i] );
|
|
m_mapOutfitSlot[(*p_vecTok)[i]] = pSlot;
|
|
}
|
|
|
|
Z3D_TOK_N_ATTACHMENT tna;
|
|
tna.tokAttachmentName = NULL_TOK;
|
|
tna.pAttachment = NULL;
|
|
tna.lHolderIndex = 0;
|
|
p_vecTok = m_rpGCMDS->GetAttachmentSlotVector();
|
|
for( i = 0; i < p_vecTok->size(); ++i )
|
|
{
|
|
m_mapAttachmentSlot[(*p_vecTok)[i]] = tna;
|
|
}
|
|
|
|
BeginOutfitSetting();
|
|
EndOutfitSetting();
|
|
|
|
SetMotionSheet( m_rpGCMDS->GetDefaultMotionSheet() );
|
|
SetMotion( m_rpGCMDS->GetDefaultMotion(), 0, false );
|
|
|
|
|
|
/*(#ifdef _DEBUG
|
|
for( int xxxi = 0; xxxi < m_rpGCMDS->GetAniHolderCount(); xxxi++ )
|
|
{
|
|
if( NULL == m_pAniHolder[xxxi].GetAniKeyPackInterface() )
|
|
{
|
|
MessageBox( NULL, "CZ3DGeneralChrModel::Init() - 뭔가 수상해뵈네잉..", 0, 0 );
|
|
}
|
|
}
|
|
#endif*/
|
|
|
|
|
|
const std::vector<Z3DTOK_SLOT_ATTACHMENT>* p_vecAttachmentDefSetting =
|
|
m_rpGCMDS->GetAttachmentDefaultSettingVector();
|
|
for( i = 0; i < p_vecAttachmentDefSetting->size(); ++i )
|
|
{
|
|
SetAttachmentSlot(
|
|
(*p_vecAttachmentDefSetting)[i].tokSlot,
|
|
(*p_vecAttachmentDefSetting)[i].tokAttachment, true );
|
|
}
|
|
|
|
const std::vector<Z3D_BOUNDING_CYLINDER_INFO>* pBCList =
|
|
m_rpGCMDS->GetBoundingCylinderVector();
|
|
if( pBCList->size() )
|
|
{
|
|
m_pBoundingCylinder = new Z3D_BOUNDING_CYLINDER[pBCList->size()];
|
|
for( i = 0; i < pBCList->size(); ++i )
|
|
{
|
|
m_pBoundingCylinder[i].fBottomRadius = (*pBCList)[i].fBottomRadius;
|
|
m_pBoundingCylinder[i].fTopRadius = (*pBCList)[i].fTopRadius;
|
|
}
|
|
}
|
|
|
|
m_bInitialized = true;
|
|
|
|
// 2003.5.8 추가 - default scale 기능 추가
|
|
SetScale( 1.0f ); // 이렇게 불러주면 SetScale() 내부에서 알아서 해준다.
|
|
|
|
m_pSkin->SetTestMode( m_bAniTestMode );
|
|
|
|
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
CZ3DObject* CZ3DGeneralChrModel::GetSkeletonPartObject( const char* szSkeletonPartName )
|
|
{
|
|
if( NULL == m_rpGCMDS )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
long lIndex = m_rpGCMDS->GetSkeletonPartObjectIdx( szSkeletonPartName );
|
|
|
|
if( -1 == lIndex )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// else
|
|
return &(m_pSkeletonObjects[lIndex]);
|
|
}
|
|
|
|
|
|
CZ3DObject* CZ3DGeneralChrModel::GetSkeletonPartObject( Z3DTOK tokSkeletonPartName )
|
|
{
|
|
if( NULL == m_rpGCMDS )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
long lIndex = m_rpGCMDS->GetSkeletonPartObjectIdx( tokSkeletonPartName );
|
|
|
|
if( -1 == lIndex )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// else
|
|
return &(m_pSkeletonObjects[lIndex]);
|
|
}
|
|
|
|
|
|
Z3DTOKARRAY* CZ3DGeneralChrModel::GetTokArray( Z3DTOK tokMotionName, long lRandomIndex )
|
|
{
|
|
if( NULL == m_rpCurrentMotionSheet )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
Z3DMOTLET* pMotlet;
|
|
Z3DMOTIONSHEET* pSheet = const_cast<Z3DMOTIONSHEET*>(m_rpCurrentMotionSheet);
|
|
std::map<Z3DTOK, Z3DMOTLET*>::iterator it;
|
|
while( 1 )
|
|
{
|
|
it = pSheet->mapTok2Motlet.find( tokMotionName );
|
|
if( it != pSheet->mapTok2Motlet.end() )
|
|
{
|
|
// 현재 sheet에서 해당 motion의 motlet을 찾은 경우
|
|
pMotlet = it->second;
|
|
break;
|
|
}
|
|
//else
|
|
pSheet = pSheet->rpParentSheet;
|
|
if( NULL == pSheet )
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
Z3DTOKARRAY* pTokArr;
|
|
if( -1 == lRandomIndex )
|
|
{
|
|
long lMotSeed = rand() % (pMotlet->lProbalilitySum);
|
|
for( int i = 0; i < pMotlet->lCount; ++i )
|
|
{
|
|
// 확률필드가 없는 데이터의 경우
|
|
// lProbalilitySum = 1, lMotSeed = 0 이므로 아래 조건식은 항상 true
|
|
if( lMotSeed < pMotlet->pProbabilityIdx[i] )
|
|
{
|
|
pTokArr = &(pMotlet->pTokArr[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pTokArr = &(pMotlet->pTokArr[min( lRandomIndex, (pMotlet->lCount-1) )]);
|
|
}
|
|
|
|
return pTokArr;
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::SetMotion( const char* szMotionName, unsigned long ulFlag, bool bTransit, long lRandomIndex )
|
|
{
|
|
if( NULL == m_rpCurrentMotionSheet )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Z3DTOK tokMotionName = g_TokMotionName.GetTOK( szMotionName );
|
|
if( NULL_TOK == tokMotionName )
|
|
{
|
|
return;
|
|
}
|
|
|
|
SetMotion( tokMotionName, ulFlag, bTransit, lRandomIndex );
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::SetMotion( Z3DTOK tokMotionName, unsigned long ulFlag, bool bTransit, long lRandomIndex )
|
|
{
|
|
if( NULL == m_rpCurrentMotionSheet )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Z3DTOKARRAY* pTokArr = GetTokArray( tokMotionName, lRandomIndex );
|
|
if( NULL == pTokArr )
|
|
{
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
if( 0 == ulFlag ) // flag setting 없음. 모든 ani holder에 setting
|
|
{
|
|
for( i = 0; i < m_rpGCMDS->GetAniHolderCount(); ++i )
|
|
{
|
|
SetAniKeyPack( i, pTokArr->pArray[i], bTransit );
|
|
}
|
|
}
|
|
else // flag 적용 setting
|
|
{
|
|
for( i = 0; i < m_rpGCMDS->GetAniHolderCount(); ++i )
|
|
{
|
|
if( ulFlag & (0x1 << i) )
|
|
{
|
|
SetAniKeyPack( i, pTokArr->pArray[i], bTransit );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::AddMotion( const char* szMotionName, unsigned long ulFlag, float fFactorPeak, bool bSustainLast )
|
|
{
|
|
if( NULL == m_rpCurrentMotionSheet )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Z3DTOK tokMotionName = g_TokMotionName.GetTOK( szMotionName );
|
|
if( NULL_TOK == tokMotionName )
|
|
{
|
|
return;
|
|
}
|
|
|
|
AddMotion( tokMotionName, ulFlag, fFactorPeak, bSustainLast );
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::AddMotion( Z3DTOK tokMotionName, unsigned long ulFlag, float fFactorPeak, bool bSustainLast )
|
|
{
|
|
if( NULL == m_rpCurrentMotionSheet )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Z3DTOKARRAY* pTokArr = GetTokArray( tokMotionName );
|
|
if( NULL == pTokArr )
|
|
{
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
if( 0 == ulFlag ) // flag setting 없음. 모든 ani holder에 setting
|
|
{
|
|
for( i = 0; i < m_rpGCMDS->GetAniHolderCount(); ++i )
|
|
{
|
|
SetAddonAniKeyPack( i, pTokArr->pArray[i], fFactorPeak );
|
|
}
|
|
}
|
|
else // flag 적용 setting
|
|
{
|
|
for( i = 0; i < m_rpGCMDS->GetAniHolderCount(); ++i )
|
|
{
|
|
if( ulFlag & (0x1 << i) )
|
|
{
|
|
SetAddonAniKeyPack( i, pTokArr->pArray[i], fFactorPeak );
|
|
}
|
|
}
|
|
}
|
|
|
|
m_AniMixer.SetAddonFactorPeak( fFactorPeak );
|
|
m_AniMixer.SustainLast( bSustainLast );
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::Act( Z3D_CHR_ACTION action, long lParam1, long lParam2 )
|
|
{
|
|
switch( action )
|
|
{
|
|
case Z3D_CA_SET_MOTION_SHEET:
|
|
break;
|
|
|
|
case Z3D_CA_ACT_MOTION:
|
|
break;
|
|
|
|
case Z3D_CA_SET_STATIC_SLOT:
|
|
break;
|
|
|
|
case Z3D_CA_BEGIN_OUTFIT_SET:
|
|
break;
|
|
|
|
case Z3D_CA_SET_OUTFIT_SLOT:
|
|
break;
|
|
|
|
case Z3D_CA_END_OUTFIT_SET:
|
|
break;
|
|
|
|
case Z3D_CA_SET_WEAPON:
|
|
break;
|
|
|
|
case Z3D_CA_SET_SHIELD:
|
|
break;
|
|
|
|
default:
|
|
CZ3DCharacterModel::Act( action, lParam1, lParam2 );
|
|
}
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetAniKeyPack( int n, Z3DTOK tokFileName, bool bTransit )
|
|
{
|
|
H3DAniKeyPackTag tagAniKeyPack;
|
|
|
|
if( NULL_TOK == tokFileName )
|
|
{
|
|
return false;
|
|
}
|
|
if( n >= m_rpGCMDS->GetAniHolderCount() )
|
|
{
|
|
return false;
|
|
}
|
|
const char* szFileName = g_TokFileName.GetString( tokFileName );
|
|
if( NULL == szFileName )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
g_ContAniKeyPack.GetObject( tagAniKeyPack, szFileName );
|
|
if( NULL == tagAniKeyPack.GetObject() )
|
|
{
|
|
return false;
|
|
}
|
|
if( tagAniKeyPack == m_pTagAniKeyPack[n] )
|
|
{
|
|
tagAniKeyPack.Release();
|
|
//return false;
|
|
// 이전 것과 같은 동작을 세팅해주더라도 처음부터 다시 플레이하도록 해
|
|
// 해 줘야지 그냥 종료해버리면 안된다.
|
|
}
|
|
else
|
|
{
|
|
m_pTagAniKeyPack[n] = tagAniKeyPack;
|
|
}
|
|
m_pAniHolder[n].SetAniPack( m_pTagAniKeyPack[n].GetObject() );
|
|
m_AniMixer.Swap( n, bTransit );
|
|
m_pEventGenerator[n].SetTokAniPack( tokFileName );
|
|
//m_pTokCurrentAniKeyPackFile = tokFileName;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetAddonAniKeyPack( int n, Z3DTOK tokFileName, float fFactorPeak )
|
|
{
|
|
H3DAniKeyPackTag tagAniKeyPack;
|
|
|
|
if( NULL_TOK == tokFileName )
|
|
{
|
|
return false;
|
|
}
|
|
if( n >= m_rpGCMDS->GetAniHolderCount() )
|
|
{
|
|
return false;
|
|
}
|
|
const char* szFileName = g_TokFileName.GetString( tokFileName );
|
|
if( NULL == szFileName )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
g_ContAniKeyPack.GetObject( tagAniKeyPack, szFileName );
|
|
if( NULL == tagAniKeyPack.GetObject() )
|
|
{
|
|
return false;
|
|
}
|
|
if( tagAniKeyPack == m_pTagAddonAniKeyPack[n] )
|
|
{
|
|
tagAniKeyPack.Release();
|
|
//return false;
|
|
// 이전 것과 같은 동작을 세팅해주더라도 처음부터 다시 플레이하도록 해
|
|
// 해 줘야지 그냥 종료해버리면 안된다.
|
|
}
|
|
else
|
|
{
|
|
m_pTagAddonAniKeyPack[n] = tagAniKeyPack;
|
|
}
|
|
m_pAddonAniHolder[n].SetAniPack( m_pTagAddonAniKeyPack[n].GetObject() );
|
|
m_pAddonEventGenerator[n].SetTokAniPack( tokFileName );
|
|
//m_pTokCurrentAniKeyPackFile = tokFileName;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetStaticSlot( const char* szSlotName, const char* szOutfitName )
|
|
{
|
|
if( m_rpGCMDS->IsFixed() )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( NULL == m_pSkin )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Z3DTOK tokSlotName = g_TokSlotName.GetTOK( szSlotName );
|
|
Z3DTOK tokOutfitName = g_TokOutfitName.GetTOK( szOutfitName );
|
|
if( NULL_TOK == tokSlotName || NULL_TOK == tokOutfitName )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3DTOK>::iterator it;
|
|
it = m_mapStaticSlot.find( tokSlotName );
|
|
if( m_mapStaticSlot.end() == it )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
it->second = tokOutfitName;
|
|
|
|
EndOutfitSetting(); // mesh 구성 자체를 완전히 다시 해줘야하므로
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::BeginOutfitSetting()
|
|
{
|
|
if( NULL == m_pSkin )
|
|
{
|
|
return;
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3DTOK_OVERLAY_SLOT*>::iterator it;
|
|
|
|
for( it = m_mapOutfitSlot.begin(); it != m_mapOutfitSlot.end(); it++ )
|
|
{
|
|
it->second->lUsed = 0;
|
|
for( int i = 0; i < it->second->lCount; ++i )
|
|
{
|
|
it->second->pArray[i] = NULL_TOK;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetOutfitSlot( const char* szSlotName, const char* szOutfitName )
|
|
{
|
|
if( m_rpGCMDS->IsFixed() )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( NULL == m_pSkin )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Z3DTOK tokSlotName = g_TokSlotName.GetTOK( szSlotName );
|
|
Z3DTOK tokOutfitName = g_TokOutfitName.GetTOK( szOutfitName );
|
|
while( 1 )
|
|
{
|
|
if( NULL_TOK == tokSlotName || NULL_TOK == tokOutfitName )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3DTOK_OVERLAY_SLOT*>::iterator it;
|
|
it = m_mapOutfitSlot.find( tokSlotName );
|
|
if( m_mapOutfitSlot.end() == it )
|
|
{
|
|
return false;
|
|
}
|
|
Z3DTOK_OVERLAY_SLOT* pOS = it->second;
|
|
|
|
if( 1 == pOS->lCount ) // 겹침이 없을 경우(slot holder 1개)
|
|
{
|
|
// 덮어쓰기가 가능
|
|
pOS->pArray[0] = tokOutfitName;
|
|
pOS->lUsed = 1;
|
|
}
|
|
else // 아닐 때는
|
|
{
|
|
// holder 갯수만큼만 setting 가능하고 덮어쓰기 불가능
|
|
if( pOS->lUsed < pOS->lCount )
|
|
{
|
|
pOS->pArray[pOS->lUsed] = tokOutfitName;
|
|
++(pOS->lUsed);
|
|
}
|
|
}
|
|
|
|
// link part setting
|
|
const Z3DOUTFITINFO* pOI = m_rpGCMDS->GetOutfitInfo( tokOutfitName );
|
|
if( NULL == pOI )
|
|
{
|
|
break;
|
|
}
|
|
tokOutfitName = pOI->tokLinkOutfit;
|
|
tokSlotName = pOI->tokLinkSlot;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::EndOutfitSetting()
|
|
{
|
|
//DeclareBlockTimingCheck( "Begin", aa );
|
|
//DeclareBlockTimingCheck( "Setting", bb );
|
|
//DeclareBlockTimingCheck( "Begin+Setting", cc );
|
|
//DeclareBlockTimingCheck( "End", dd );
|
|
|
|
if( NULL == m_pSkin )
|
|
{
|
|
return;
|
|
}
|
|
|
|
int i, j;
|
|
const std::vector<Z3DTOK>* p_vecTok;
|
|
Z3DTOK_OVERLAY_SLOT* pSlot;
|
|
|
|
//BlockTimingCheckStart(cc);
|
|
|
|
//BlockTimingCheckStart(aa);
|
|
m_pSkin->BatchOpen();
|
|
//BlockTimingCheckStop(aa);
|
|
|
|
//BlockTimingCheckStart(bb);
|
|
// 기본형(웃통벗고 반바지..같은거) 적용
|
|
ApplyOutfit( m_rpGCMDS->GetDefaultOutfit() );
|
|
|
|
// static slot(얼굴, 헤어스타일) 적용
|
|
p_vecTok = m_rpGCMDS->GetStaticSlotVector();
|
|
for( i = 0; i < p_vecTok->size(); ++i )
|
|
{
|
|
ApplyOutfit( m_mapStaticSlot[(*p_vecTok)[i]] );
|
|
}
|
|
|
|
// 옷가지 적용
|
|
p_vecTok = m_rpGCMDS->GetOutfitSlotVector();
|
|
for( i = 0; i < p_vecTok->size(); ++i )
|
|
{
|
|
pSlot = m_mapOutfitSlot[(*p_vecTok)[i]];
|
|
for( j = 0; j < pSlot->lUsed; ++j )
|
|
{
|
|
ApplyOutfit( pSlot->pArray[j] );
|
|
}
|
|
}
|
|
//BlockTimingCheckStop(bb);
|
|
|
|
m_pSkin->BatchClose();
|
|
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetAttachmentSlot( const char* szSlotName, const char* szAttachmentName, bool bForced )
|
|
{
|
|
if( !bForced && m_rpGCMDS->IsFixed() )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Z3DTOK tokSlotName, tokAttachmentName;
|
|
|
|
tokSlotName = g_TokSlotName.GetTOK( szSlotName );
|
|
if( NULL_TOK == tokSlotName )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( NULL == szAttachmentName )
|
|
{
|
|
return SetAttachmentSlot( tokSlotName, NULL_TOK );
|
|
}
|
|
|
|
tokAttachmentName = g_TokAttachmentName.GetTOK( szAttachmentName );
|
|
/*if( NULL_TOK == tokAttachmentName )
|
|
{
|
|
return false;
|
|
}*/
|
|
|
|
return SetAttachmentSlot( tokSlotName, tokAttachmentName );
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetAttachmentSlot( Z3DTOK tokSlotName, Z3DTOK tokAttachmentName, bool bForced )
|
|
{
|
|
if( !bForced && m_rpGCMDS->IsFixed() )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
|
|
it = m_mapAttachmentSlot.find( tokSlotName );
|
|
if( m_mapAttachmentSlot.end() == it )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// attachment 이름이 null : 현재 attachment 삭제
|
|
if( NULL_TOK == tokAttachmentName )
|
|
{
|
|
it->second.tokAttachmentName = NULL_TOK;
|
|
SAFE_DELETE( it->second.pAttachment );
|
|
return true;
|
|
}
|
|
|
|
const Z3DATTACHMENTINFO* pAInfo = m_rpGCMDS->GetAttachmentInfo( tokAttachmentName );
|
|
if( NULL == pAInfo )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( it->second.tokAttachmentName == tokAttachmentName )
|
|
{
|
|
// 이전에 세팅된것과 같은 attachment
|
|
return false;
|
|
}
|
|
|
|
const char* szMeshName = g_TokFileName.GetString( pAInfo->tokMeshFile );
|
|
const char* szTexName = g_TokFileName.GetString( pAInfo->tokTextureFile );
|
|
const char* szTexName2 = g_TokFileName.GetString( pAInfo->tokTextureFile2 );
|
|
if( !(szMeshName && szTexName) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//SAFE_DELETE( it->second.pAttachment );
|
|
if( NULL == it->second.pAttachment )
|
|
{
|
|
it->second.pAttachment = new CZ3DWeapon( GetSkeletonPartObject("R_HAND") );
|
|
it->second.pAttachment->SetScale( m_fScaleFactor );
|
|
}
|
|
|
|
char strBumpTextureName[256] = { 0, };
|
|
char strSpecTextureName[256] = { 0, };
|
|
//if( NULL == szTexName2 && CRenderOption::m_TextureMethod && CRenderOption::m_CharacterPerPixelLighting)
|
|
//{
|
|
sprintf(strBumpTextureName, "%sTexture\\%s", CHARACTERDATAPATH,szTexName);
|
|
int nStrLens=strlen(strBumpTextureName);
|
|
|
|
strcpy( &strBumpTextureName[nStrLens-4], "_bump.dds" );
|
|
|
|
FILE *fp=fopen(strBumpTextureName,"rb");
|
|
if(fp==NULL)
|
|
strcpy(strBumpTextureName,"");
|
|
else
|
|
{
|
|
sprintf(strBumpTextureName, "%s", szTexName);
|
|
|
|
nStrLens=strlen(strBumpTextureName);
|
|
strcpy( &strBumpTextureName[nStrLens-4], "_bump.dds" );
|
|
fclose( fp );
|
|
}
|
|
|
|
sprintf(strSpecTextureName, "%sTexture\\%s", CHARACTERDATAPATH,szTexName);
|
|
nStrLens=strlen(strSpecTextureName);
|
|
strcpy( &strSpecTextureName[nStrLens-4], "_spec.dds" );
|
|
|
|
fp=fopen(strSpecTextureName,"rb");
|
|
if(fp==NULL)
|
|
strcpy(strSpecTextureName,"spec_black.dds");
|
|
else
|
|
{
|
|
sprintf(strSpecTextureName, "%s", szTexName);
|
|
|
|
nStrLens=strlen(strSpecTextureName);
|
|
strcpy( &strSpecTextureName[nStrLens-4], "_spec.dds" );
|
|
fclose( fp );
|
|
}
|
|
|
|
|
|
it->second.pAttachment->Set( szMeshName, szTexName, strBumpTextureName, strSpecTextureName );
|
|
//}
|
|
//else
|
|
//{
|
|
// it->second.pAttachment->Set( szMeshName, szTexName, szTexName2, NULL );
|
|
//}
|
|
|
|
const Z3DATTACHMENTHOLDERINFO* pholderInfo =
|
|
pAInfo->GetAttachmentHolderInfo(it->second.lHolderIndex);
|
|
it->second.pAttachment->Link(
|
|
GetSkeletonPartObject(pholderInfo->tokSkelPart) );
|
|
it->second.pAttachment->SetPositionLocal( pholderInfo->vPos );
|
|
it->second.pAttachment->SetDirectionLocal( pholderInfo->qRot );
|
|
|
|
if( 5 == pAInfo->lType ) // type 5 == bow
|
|
{
|
|
it->second.pAttachment->SetBowMode( true );
|
|
}
|
|
else
|
|
{
|
|
it->second.pAttachment->SetBowMode( false );
|
|
}
|
|
|
|
|
|
it->second.tokAttachmentName = tokAttachmentName;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetAttachmentHolder( const char* szSlotName, long lIndex )
|
|
{
|
|
Z3DTOK tokSlotName;
|
|
|
|
tokSlotName = g_TokSlotName.GetTOK( szSlotName );
|
|
if( NULL_TOK == tokSlotName )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return SetAttachmentHolder( tokSlotName, lIndex );
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetAttachmentHolder( Z3DTOK tokSlotName, long lIndex )
|
|
{
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
|
|
it = m_mapAttachmentSlot.find( tokSlotName );
|
|
if( m_mapAttachmentSlot.end() == it )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( NULL == it->second.pAttachment )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
const Z3DATTACHMENTINFO* pAInfo = m_rpGCMDS->GetAttachmentInfo( it->second.tokAttachmentName );
|
|
if( NULL == pAInfo )
|
|
{
|
|
return false; // 이쪽이 실행될 일은 없음..
|
|
}
|
|
|
|
const Z3DATTACHMENTHOLDERINFO* pholderInfo = pAInfo->GetAttachmentHolderInfo(lIndex);
|
|
it->second.pAttachment->Link(
|
|
GetSkeletonPartObject(pholderInfo->tokSkelPart) );
|
|
it->second.pAttachment->SetPositionLocal( pholderInfo->vPos );
|
|
it->second.pAttachment->SetDirectionLocal( pholderInfo->qRot );
|
|
it->second.lHolderIndex = lIndex;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
long CZ3DGeneralChrModel::GetAttachmentHolder( const char* szSlotName )
|
|
{
|
|
Z3DTOK tokSlotName;
|
|
|
|
tokSlotName = g_TokSlotName.GetTOK( szSlotName );
|
|
if( NULL_TOK == tokSlotName )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return GetAttachmentHolder( tokSlotName );
|
|
}
|
|
|
|
|
|
long CZ3DGeneralChrModel::GetAttachmentHolder( Z3DTOK tokSlotName )
|
|
{
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
|
|
it = m_mapAttachmentSlot.find( tokSlotName );
|
|
if( m_mapAttachmentSlot.end() == it )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return it->second.lHolderIndex;
|
|
}
|
|
|
|
|
|
CZ3DWeapon* CZ3DGeneralChrModel::GetAttachmentObject( const char* szSlotName )
|
|
{
|
|
Z3DTOK tokSlotName;
|
|
|
|
tokSlotName = g_TokSlotName.GetTOK( szSlotName );
|
|
if( NULL_TOK == tokSlotName )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return GetAttachmentObject( tokSlotName );
|
|
}
|
|
|
|
|
|
CZ3DWeapon* CZ3DGeneralChrModel::GetAttachmentObject( Z3DTOK tokSlotName )
|
|
{
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
|
|
it = m_mapAttachmentSlot.find( tokSlotName );
|
|
if( m_mapAttachmentSlot.end() == it )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return it->second.pAttachment;
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::ApplyOutfit( Z3DTOK tokOutfitName )
|
|
{
|
|
if( NULL_TOK == tokOutfitName )
|
|
{
|
|
// 잘못된 oufit 이름
|
|
return;
|
|
}
|
|
|
|
const Z3DOUTFITINFO* pOI = m_rpGCMDS->GetOutfitInfo( tokOutfitName );
|
|
if( NULL == pOI )
|
|
{
|
|
return;
|
|
}
|
|
|
|
int i;
|
|
const char* szMeshName;
|
|
const char* szTextureName;
|
|
//const char* szTexture2Name;
|
|
if( Z3D_MPT_TEXPIECE == m_rpGCMDS->GetMPT() )
|
|
{
|
|
// mesh type == texpiece 일 경우
|
|
for( i = 0; i < pOI->lCount; i++ )
|
|
{
|
|
szMeshName = g_TokFileName.GetString( pOI->pTokMeshName[i] );
|
|
if( szMeshName )
|
|
{
|
|
m_pSkin->SetMesh( szMeshName );
|
|
}
|
|
|
|
szTextureName = g_TokFileName.GetString( pOI->pTokTextureName[i] );
|
|
|
|
char strBumpTextureName[256];
|
|
FILE *fp=NULL;
|
|
|
|
if(CRenderOption::m_TextureMethod && CRenderOption::m_CharacterPerPixelLighting)
|
|
{
|
|
sprintf(strBumpTextureName, "%sTexture\\", CHARACTERDATAPATH,szTextureName);
|
|
}
|
|
|
|
//szTexture2Name = g_TokFileName.GetString( pOI->pTokTexture2Name[i] );
|
|
/*if( NULL_TOK == pOI->pTokTexture2Name[i] )
|
|
{
|
|
szTexture2Name = NULL;
|
|
}
|
|
else
|
|
{
|
|
szTexture2Name = g_TokFileName.GetString( pOI->pTokTexture2Name[i] );
|
|
}*/
|
|
|
|
if( szTextureName )
|
|
{
|
|
m_pSkin->SetTex( szTextureName, strBumpTextureName);
|
|
}
|
|
/*
|
|
if( szTextureName )
|
|
{
|
|
m_pSkin->SetTex( szTextureName, szTexture2Name );
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// mesh type == texture 일 경우
|
|
|
|
for( i = 0; i < pOI->lCount; i++ )
|
|
{
|
|
szMeshName = g_TokFileName.GetString( pOI->pTokMeshName[i] );
|
|
szTextureName = g_TokFileName.GetString( pOI->pTokTextureName[i] );
|
|
|
|
char strBumpTextureName[256] = { 0, };
|
|
char strSpecTextureName[256] = { 0, };
|
|
|
|
//if(CRenderOption::m_TextureMethod && CRenderOption::m_CharacterPerPixelLighting)
|
|
//{
|
|
sprintf(strBumpTextureName, "%sTexture\\%s", CHARACTERDATAPATH,szTextureName);
|
|
|
|
int nStrLens=strlen(strBumpTextureName);
|
|
strcpy( &strBumpTextureName[nStrLens-4], "_bump.dds" );
|
|
|
|
FILE *fp=fopen(strBumpTextureName,"rb");
|
|
if(fp==NULL)
|
|
strcpy(strBumpTextureName,"");
|
|
else
|
|
{
|
|
sprintf(strBumpTextureName, "%s", szTextureName);
|
|
|
|
nStrLens=strlen(strBumpTextureName);
|
|
strcpy( &strBumpTextureName[nStrLens-4], "_bump.dds" );
|
|
fclose( fp );
|
|
}
|
|
|
|
|
|
sprintf(strSpecTextureName, "%sTexture\\%s", CHARACTERDATAPATH,szTextureName);
|
|
|
|
nStrLens=strlen(strSpecTextureName);
|
|
strcpy( &strSpecTextureName[nStrLens-4], "_spec.dds" );
|
|
|
|
fp=fopen(strSpecTextureName,"rb");
|
|
if(fp==NULL)
|
|
strcpy(strSpecTextureName,"spec_black.dds");
|
|
else
|
|
{
|
|
sprintf(strSpecTextureName, "%s", szTextureName);
|
|
|
|
nStrLens=strlen(strSpecTextureName);
|
|
strcpy( &strSpecTextureName[nStrLens-4], "_spec.dds" );
|
|
fclose( fp );
|
|
}
|
|
//}
|
|
|
|
//szTexture2Name = g_TokFileName.GetString( pOI->pTokTexture2Name[i] );
|
|
|
|
if( szMeshName )
|
|
{
|
|
//m_pSkin->SetMeshTexture( szMeshName, szTextureName, szTexture2Name );
|
|
m_pSkin->SetMeshTexture(szMeshName,szTextureName,strBumpTextureName,strSpecTextureName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::FrameMove()
|
|
{
|
|
/*#ifdef _DEBUG
|
|
for( int xxxi = 0; xxxi < m_rpGCMDS->GetAniHolderCount(); xxxi++ )
|
|
{
|
|
if( NULL == m_pAniHolder[xxxi].GetAniKeyPackInterface() )
|
|
{
|
|
MessageBox( NULL, "AniKeyPack 데이터 손상(this pointer = NULL", 0, 0 );
|
|
}
|
|
}
|
|
#endif*/
|
|
|
|
int i;
|
|
vector3 vd;
|
|
|
|
|
|
if( NULL == m_pAniHolder )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if( m_bAniTestMode )
|
|
{
|
|
for( i = 0; i < m_rpGCMDS->GetSkeletonCount(); ++i )
|
|
{
|
|
m_pSkeletonObjects[i].SetPositionLocal( 0, 0, 0 );
|
|
m_pSkeletonObjects[i].SetDirectionLocal( 0, 0, 0, 1 );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*for( i = 0; i < m_rpGCMDS->GetSkeletonCount(); i++ )
|
|
{
|
|
m_pSkeletonObjects[i].ApplyAniKey( m_pAniHolder );
|
|
}*/
|
|
m_AniMixer.Mix();
|
|
/*for( i = 0; i < m_rpGCMDS->GetSkeletonCount(); i++ )
|
|
{
|
|
m_pSkeletonObjects[i].SetPositionLocal( 0, 0, 0 );
|
|
m_pSkeletonObjects[i].SetDirectionLocal( 0, 0, 0, 1 );
|
|
}*/
|
|
|
|
|
|
// Bip01 오브젝트와 pelvis 오브젝트간의 x-z거리를 무시한다
|
|
/* m_pSkeletonObjects[1].GetPositionLocal( vd );
|
|
vd.x = 0;
|
|
vd.z = 0;
|
|
m_pSkeletonObjects[1].SetPositionLocal( vd );
|
|
*/
|
|
// 캐릭터모델의 위치를 skin과 attachment 의 pivot으로..
|
|
if( m_pSkin )
|
|
{
|
|
m_pSkin->SetPivot( m_Pos );
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
for( it = m_mapAttachmentSlot.begin(); it != m_mapAttachmentSlot.end(); it++ )
|
|
{
|
|
if( it->second.pAttachment )
|
|
{
|
|
it->second.pAttachment->SetPivot( m_Pos );
|
|
}
|
|
}
|
|
|
|
quaternion q1, q2;
|
|
z3d::QuaternionAxisAngle( q1, 0, 1.0f, 0, m_fDir );
|
|
//m_pSkeletonObjects[0].Rotate( q );
|
|
m_pSkeletonObjects[0].GetDirectionLocal( q2 );
|
|
m_pSkeletonObjects[0].SetDirectionLocal( q2*q1 );
|
|
m_pSkeletonObjects[0].GetPositionLocal( vd );
|
|
z3d::VectorRotate( vd, vd, q1 );
|
|
m_pSkeletonObjects[0].SetPositionLocal( vd );
|
|
|
|
|
|
|
|
// event 체크
|
|
m_vec_tokEventStorage.clear();
|
|
m_vec_tokSecondaryEventStorage.clear();
|
|
for( i = 0; i < m_rpGCMDS->GetAniHolderCount(); ++i )
|
|
{
|
|
m_pEventGenerator[i].CheckEvent(
|
|
m_pAniHolder[i].GetCurrentFrame(),
|
|
m_pAniHolder[i].GetPrevFrame(),
|
|
m_vec_tokEventStorage, m_vec_tokSecondaryEventStorage );
|
|
|
|
m_pAddonEventGenerator[i].CheckEvent(
|
|
m_pAddonAniHolder[i].GetCurrentFrame(),
|
|
m_pAddonAniHolder[i].GetPrevFrame(),
|
|
m_vec_tokEventStorage, m_vec_tokSecondaryEventStorage );
|
|
}
|
|
|
|
for( i = 0; i < m_rpGCMDS->GetAniHolderCount(); i++ )
|
|
{
|
|
m_pAniHolder[i].Progress();
|
|
m_pAddonAniHolder[i].Progress();
|
|
}
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::CheckEvent( const char* szEventName, Z3DTOK* p_tokSecondaryEvent )
|
|
{
|
|
Z3DTOK tok = g_TokEventName.GetTOK( szEventName );
|
|
if( NULL_TOK == tok )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::vector<Z3DTOK>::iterator it;
|
|
|
|
if( m_vec_tokEventStorage.end() ==
|
|
( it = std::find( m_vec_tokEventStorage.begin(),
|
|
m_vec_tokEventStorage.end(), tok ) ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( p_tokSecondaryEvent )
|
|
{
|
|
*p_tokSecondaryEvent =
|
|
m_vec_tokSecondaryEventStorage[it - m_vec_tokEventStorage.begin()];
|
|
}
|
|
|
|
*it = NULL_TOK; // clear checked event;
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetMotionSheet( const char* szSheetName )
|
|
{
|
|
if( NULL == szSheetName )
|
|
{
|
|
return false;
|
|
}
|
|
Z3DTOK tok = g_TokSheetName.GetTOK( szSheetName );
|
|
if( NULL_TOK == tok )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return SetMotionSheet( tok );
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::SetMotionSheet( Z3DTOK tokSheetName )
|
|
{
|
|
if( NULL == m_rpGCMDS )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const Z3DMOTIONSHEET* pSheet = m_rpGCMDS->GetMotionsheet( tokSheetName );
|
|
if( NULL == pSheet )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_rpCurrentMotionSheet = pSheet;
|
|
m_tokCurrentMotionSheet = tokSheetName;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
const char* CZ3DGeneralChrModel::GetCurrentMotionSheetName()
|
|
{
|
|
return g_TokSheetName.GetString( m_tokCurrentMotionSheet );
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::PreRender()
|
|
{
|
|
if( m_pSkin )
|
|
{
|
|
m_pSkin->ApplyAnimation();
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
for( it = m_mapAttachmentSlot.begin(); it != m_mapAttachmentSlot.end(); it++ )
|
|
{
|
|
if( it->second.pAttachment )
|
|
{
|
|
it->second.pAttachment->ApplyTransform();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::Render()
|
|
{
|
|
if( m_pSkin )
|
|
{
|
|
m_pSkin->RenderIndividual();
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
for( it = m_mapAttachmentSlot.begin(); it != m_mapAttachmentSlot.end(); it++ )
|
|
{
|
|
if( it->second.pAttachment )
|
|
{
|
|
it->second.pAttachment->RenderIndividual();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::DrawShadow( DWORD vertexShader )
|
|
{
|
|
if( m_pSkin )
|
|
{
|
|
m_pSkin->RenderShadow( vertexShader );
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
for( it = m_mapAttachmentSlot.begin(); it != m_mapAttachmentSlot.end(); it++ )
|
|
{
|
|
if( it->second.pAttachment )
|
|
{
|
|
it->second.pAttachment->RenderShadow( vertexShader );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::DrawSpecular( DWORD vertexShader )
|
|
{
|
|
if( m_pSkin )
|
|
{
|
|
m_pSkin->RenderSpecular( vertexShader );
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
for( it = m_mapAttachmentSlot.begin(); it != m_mapAttachmentSlot.end(); it++ )
|
|
{
|
|
if( it->second.pAttachment )
|
|
{
|
|
it->second.pAttachment->RenderSpecular( vertexShader );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::GetAniDataDisplacement( vector3 &v_disp, int n )
|
|
{
|
|
if( !(n < m_rpGCMDS->GetAniHolderCount()) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if( NULL == m_pTagAniKeyPack[n].GetObject() )
|
|
{
|
|
v_disp.Identity();
|
|
return;
|
|
}
|
|
|
|
Z3DAniKeyPack* pPack = m_pTagAniKeyPack[n].GetObject();
|
|
if( false == pPack->GetDisplacement( v_disp, 0 ) )
|
|
{
|
|
v_disp.Identity();
|
|
}
|
|
}
|
|
|
|
|
|
long CZ3DGeneralChrModel::GetAniDataLength( int n )
|
|
{
|
|
if( !(n < m_rpGCMDS->GetAniHolderCount()) )
|
|
{
|
|
return 0L;
|
|
}
|
|
|
|
if( NULL == m_pTagAniKeyPack[n].GetObject() )
|
|
{
|
|
return 0L;
|
|
}
|
|
|
|
Z3DAniKeyPack* pPack = m_pTagAniKeyPack[n].GetObject();
|
|
|
|
return pPack->GetAniLength();
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::SetDisable( bool bDisabled )
|
|
{
|
|
CZ3DCharacterModel::SetDisable( bDisabled );
|
|
|
|
SetCull( bDisabled );
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::SetCull( bool bCulled )
|
|
{
|
|
if( m_pSkeletonObjects ) // init 의 증거
|
|
{
|
|
m_pSkeletonObjects[0].SetDisable( bCulled );
|
|
}
|
|
|
|
if( m_pSkin )
|
|
{
|
|
m_pSkin->SetCull( bCulled );
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
for( it = m_mapAttachmentSlot.begin(); it != m_mapAttachmentSlot.end(); it++ )
|
|
{
|
|
if( it->second.pAttachment )
|
|
{
|
|
it->second.pAttachment->SetCull( bCulled );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::SetScale( float f )
|
|
{
|
|
float fDefaultScale = 1.0f;
|
|
|
|
if( m_rpGCMDS )
|
|
{
|
|
fDefaultScale = m_rpGCMDS->GetDefaultScale();
|
|
}
|
|
|
|
m_fScaleFactor = f;
|
|
if( m_pSkin )
|
|
{
|
|
m_pSkin->SetScale( f * fDefaultScale );
|
|
}
|
|
|
|
// attachment 관련 설정
|
|
std::map<Z3DTOK, Z3D_TOK_N_ATTACHMENT>::iterator it;
|
|
for( it = m_mapAttachmentSlot.begin(); it != m_mapAttachmentSlot.end(); it++ )
|
|
{
|
|
if( it->second.pAttachment )
|
|
{
|
|
it->second.pAttachment->SetScale( f * fDefaultScale );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
float CZ3DGeneralChrModel::GetEffectScale()
|
|
{
|
|
return this->GetScale() * m_rpGCMDS->GetEffectScale();
|
|
}
|
|
|
|
|
|
void CZ3DGeneralChrModel::GetBoundingBox( vector3& r_vmin, vector3& r_vmax )
|
|
{
|
|
if( NULL == m_pSkin )
|
|
{
|
|
r_vmin = vector3( 0, 0, 0 );
|
|
r_vmax = vector3( 0, 0, 0 );
|
|
return;
|
|
}
|
|
|
|
m_pSkin->GetBoundingBox( r_vmin, r_vmax );
|
|
}
|
|
|
|
|
|
const Z3D_BOUNDING_CYLINDER* CZ3DGeneralChrModel::GetBoundingCylinderList()
|
|
{
|
|
if( NULL == m_rpGCMDS )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
const std::vector<Z3D_BOUNDING_CYLINDER_INFO>& rBCIList =
|
|
*(m_rpGCMDS->GetBoundingCylinderVector());
|
|
for( int i = 0; i < rBCIList.size(); ++i )
|
|
{
|
|
m_pBoundingCylinder[i].vBottom.x = m_pSkeletonObjects[rBCIList[i].lBottomIdx].GetTM()->_41;
|
|
m_pBoundingCylinder[i].vBottom.y = m_pSkeletonObjects[rBCIList[i].lBottomIdx].GetTM()->_42;
|
|
m_pBoundingCylinder[i].vBottom.z = m_pSkeletonObjects[rBCIList[i].lBottomIdx].GetTM()->_43;
|
|
|
|
m_pBoundingCylinder[i].vTop.x = m_pSkeletonObjects[rBCIList[i].lTopIdx].GetTM()->_41;
|
|
m_pBoundingCylinder[i].vTop.y = m_pSkeletonObjects[rBCIList[i].lTopIdx].GetTM()->_42;
|
|
m_pBoundingCylinder[i].vTop.z = m_pSkeletonObjects[rBCIList[i].lTopIdx].GetTM()->_43;
|
|
}
|
|
|
|
return m_pBoundingCylinder;
|
|
}
|
|
|
|
|
|
bool CZ3DGeneralChrModel::IsShaderParameterAvailable( long lIdx )
|
|
{
|
|
if( NULL == m_rpGCMDS )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return m_rpGCMDS->IsShaderParameterAvailable( lIdx );
|
|
}
|
|
|
|
|
|
const char* CZ3DGeneralChrModel::GetShaderParameterInfo( long lIdx )
|
|
{
|
|
if( NULL == m_rpGCMDS )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return m_rpGCMDS->GetShaderParameterInfo( lIdx );
|
|
}
|
|
|
|
|
|
long CZ3DGeneralChrModel::GetEffectInfoList( const char** &rpszEffectInfo )
|
|
{
|
|
if( NULL == m_rpGCMDS )
|
|
{
|
|
rpszEffectInfo = NULL;
|
|
return 0;
|
|
}
|
|
|
|
return m_rpGCMDS->GetEffectInfoList( rpszEffectInfo );
|
|
} |