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>
1933 lines
40 KiB
C++
1933 lines
40 KiB
C++
// Z3DGCMDS.cpp: implementation of the CZ3DGCMDS class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Z3DGCMDS.h"
|
|
|
|
#include <stack>
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CZ3DGCMDS::CZ3DGCMDS()
|
|
{
|
|
m_fEffectScale = 1.0f;
|
|
m_fDefaultScale = 1.0f;
|
|
m_lSkeletonCount = 0;
|
|
m_lAniHolderCount = 0;
|
|
m_pSkeletonHierarchy = NULL;
|
|
m_pAniHolderIndex = NULL;
|
|
m_pIndexInSubpart = NULL;
|
|
m_pszSkeletonName = NULL;
|
|
m_pLocalizerMatrix = NULL;
|
|
|
|
m_TokDefaultOutfit = NULL_TOK;
|
|
m_TokDefaultMotionSheet = NULL_TOK;
|
|
m_TokDefaultMotion = NULL_TOK;
|
|
|
|
m_szSkelFileName = NULL;
|
|
m_szFileName = NULL;
|
|
|
|
for( int i = 0; i < Z3D_MAX_SHADER_COUNT; ++i )
|
|
{
|
|
m_aszShaderInfoList[i] = NULL;
|
|
}
|
|
|
|
m_bFixed = false;
|
|
}
|
|
|
|
CZ3DGCMDS::~CZ3DGCMDS()
|
|
{
|
|
std::map<Z3DTOK, Z3DMOTIONSHEET*>::iterator itMsheet;
|
|
for( itMsheet = m_mapTok2MotionSheet.begin(); itMsheet != m_mapTok2MotionSheet.end(); itMsheet++ )
|
|
{
|
|
SAFE_DELETE( itMsheet->second );
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3DATTACHMENTINFO*>::iterator itWInfo;
|
|
for( itWInfo = m_mapTok2AttachmentInfo.begin(); itWInfo != m_mapTok2AttachmentInfo.end(); itWInfo++ )
|
|
{
|
|
SAFE_DELETE( itWInfo->second );
|
|
}
|
|
|
|
std::map<Z3DTOK, Z3DOUTFITINFO*>::iterator itOInfo;
|
|
for( itOInfo = m_mapTok2OutfitInfo.begin(); itOInfo != m_mapTok2OutfitInfo.end(); itOInfo++ )
|
|
{
|
|
SAFE_DELETE( itOInfo->second );
|
|
}
|
|
|
|
for( int i = 0; i < Z3D_MAX_SHADER_COUNT; ++i )
|
|
{
|
|
SAFE_DELETEA( m_aszShaderInfoList[i] );
|
|
}
|
|
|
|
for( i = 0; i < m_vecszEffectInfo.size(); ++i )
|
|
{
|
|
//SAFE_DELETE( m_vecEffectInfo[i] );
|
|
SAFE_DELETEA( m_vecszEffectInfo[i] );
|
|
}
|
|
|
|
if( m_pszSkeletonName )
|
|
{
|
|
for( i = 0; i < m_lSkeletonCount; ++i )
|
|
{
|
|
SAFE_DELETEA( m_pszSkeletonName[i] );
|
|
}
|
|
SAFE_DELETEA( m_pszSkeletonName );
|
|
}
|
|
|
|
SAFE_DELETEA( m_pSkeletonHierarchy );
|
|
SAFE_DELETEA( m_pAniHolderIndex );
|
|
SAFE_DELETEA( m_pIndexInSubpart );
|
|
SAFE_DELETEA( m_pLocalizerMatrix );
|
|
SAFE_DELETEA( m_szFileName );
|
|
SAFE_DELETEA( m_szSkelFileName );
|
|
}
|
|
|
|
|
|
// Loading 관련함수
|
|
|
|
bool CZ3DGCMDS::ReadSkelFile( const char* szFilename )
|
|
{
|
|
FILE* fp;
|
|
if( (fp = fopen( szFilename, "rb" )) == NULL )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
long i, j;
|
|
|
|
// read skeleton count & aniholder count;
|
|
fread( &i, sizeof(long), 1, fp );
|
|
fread( &j, sizeof(int), 1, fp );
|
|
|
|
m_lSkeletonCount = i;
|
|
m_lAniHolderCount = j;
|
|
m_pSkeletonHierarchy = new long[i];
|
|
m_pAniHolderIndex = new long[i];
|
|
m_pIndexInSubpart = new long[i];
|
|
m_pLocalizerMatrix = new matrix[i];
|
|
|
|
// read hierarchy info
|
|
for( i = 0; i < m_lSkeletonCount; ++i )
|
|
{
|
|
fread( &(m_pSkeletonHierarchy[i]), sizeof(int), 1, fp );
|
|
}
|
|
|
|
// read localizer matrix data
|
|
for( i = 0; i < m_lSkeletonCount; ++i )
|
|
{
|
|
fread( &(m_pLocalizerMatrix[i]), sizeof(matrix), 1, fp );
|
|
}
|
|
|
|
// read ani holder index & index in subpart
|
|
if( m_lAniHolderCount > 1 )
|
|
{
|
|
for( i = 0; i < m_lSkeletonCount; i++ )
|
|
{
|
|
fread( &(m_pAniHolderIndex[i]), sizeof(int), 1, fp );
|
|
fread( &(m_pIndexInSubpart[i]), sizeof(int), 1, fp );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( i = 0; i < m_lSkeletonCount; i++ )
|
|
{
|
|
m_pAniHolderIndex[i] = 0;
|
|
m_pIndexInSubpart[i] = i;
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadSkeyFile( const char* szFilename )
|
|
{
|
|
CSimpleParser parser;
|
|
long i, j;
|
|
|
|
if( false == parser.OpenFile( szFilename ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( 0 != stricmp( "SKELETON_KEY_DATA", parser.GetNextToken() ) )
|
|
{
|
|
return false; // invalid header
|
|
}
|
|
|
|
// 이미 할당된 데이터들의 해제
|
|
if( m_pszSkeletonName )
|
|
{
|
|
for( i = 0; i < m_lSkeletonCount; ++i )
|
|
{
|
|
SAFE_DELETEA( m_pszSkeletonName[i] );
|
|
}
|
|
}
|
|
SAFE_DELETEA( m_pSkeletonHierarchy );
|
|
SAFE_DELETEA( m_pAniHolderIndex );
|
|
SAFE_DELETEA( m_pIndexInSubpart );
|
|
SAFE_DELETEA( m_pszSkeletonName );
|
|
SAFE_DELETEA( m_pLocalizerMatrix );
|
|
|
|
|
|
char* szToken;
|
|
|
|
while( (szToken = parser.GetNextToken()) != NULL )
|
|
{
|
|
if( 0 == stricmp( "skeletoncount", szToken ) )
|
|
{
|
|
szToken = parser.GetNextToken();
|
|
m_lSkeletonCount = aton( szToken );
|
|
}
|
|
else if( 0 == stricmp( "skeleton", szToken ) )
|
|
{
|
|
m_pSkeletonHierarchy = new long[m_lSkeletonCount];
|
|
m_pAniHolderIndex = new long[m_lSkeletonCount];
|
|
m_pIndexInSubpart = new long[m_lSkeletonCount];
|
|
m_pszSkeletonName = new char*[m_lSkeletonCount];
|
|
|
|
szToken = parser.GetNextToken();
|
|
while( 0 != stricmp( szToken, ";" ) )
|
|
{
|
|
i = aton(szToken);
|
|
if( i >= m_lSkeletonCount )
|
|
{
|
|
// skip remainder of 4 tokens
|
|
for( j = 0; j < 4; ++j )
|
|
{
|
|
parser.GetNextToken();
|
|
}
|
|
|
|
szToken = parser.GetNextToken();
|
|
continue;
|
|
}
|
|
|
|
m_pSkeletonHierarchy[i] = aton( parser.GetNextToken() );
|
|
m_pAniHolderIndex[i] = aton( parser.GetNextToken() );
|
|
m_pIndexInSubpart[i] = aton( parser.GetNextToken() );
|
|
szToken = parser.GetNextToken();
|
|
m_pszSkeletonName[i] = new char[strlen(szToken)+1];
|
|
strcpy( m_pszSkeletonName[i], szToken );
|
|
|
|
szToken = parser.GetNextToken();
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "aniholdercount", szToken ) )
|
|
{
|
|
szToken = parser.GetNextToken();
|
|
m_lAniHolderCount = aton( szToken );
|
|
}
|
|
else if( 0 == stricmp( "TMInverse", szToken ) )
|
|
{
|
|
m_pLocalizerMatrix = new matrix[m_lSkeletonCount];
|
|
|
|
szToken = parser.GetNextToken();
|
|
while( 0 != stricmp( szToken, ";" ) )
|
|
{
|
|
i = aton(parser.GetNextToken()); // skip "matrix" token
|
|
if( i >= m_lSkeletonCount )
|
|
{
|
|
// skip remainder of 12 tokens
|
|
for( j = 0; j < 12; ++j )
|
|
{
|
|
parser.GetNextToken();
|
|
}
|
|
szToken = parser.GetNextToken();
|
|
continue;
|
|
}
|
|
|
|
m_pLocalizerMatrix[i]._11 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._12 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._13 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._14 = 0.0f;
|
|
|
|
m_pLocalizerMatrix[i]._21 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._22 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._23 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._24 = 0.0f;
|
|
|
|
m_pLocalizerMatrix[i]._31 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._32 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._33 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._34 = 0.0f;
|
|
|
|
m_pLocalizerMatrix[i]._41 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._42 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._43 = atof( parser.GetNextToken() );
|
|
m_pLocalizerMatrix[i]._44 = 1.0f;
|
|
|
|
szToken = parser.GetNextToken();
|
|
}
|
|
}
|
|
}
|
|
|
|
parser.Close();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadSkeletonPartInfo( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
tok = g_TokSkeletonPartName.Add( szToken );
|
|
szToken = rParser.GetNextToken();
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
m_mapTok2SkelpartIdx[tok] = aton( szToken );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadBoundingCylinderInfo( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
|
|
Z3D_BOUNDING_CYLINDER_INFO bci;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
bci.lBottomIdx = aton(szToken);
|
|
|
|
|
|
szToken = rParser.GetNextToken();
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
bci.lTopIdx = aton(szToken);
|
|
|
|
szToken = rParser.GetNextToken();
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
bci.fBottomRadius = atof(szToken);
|
|
|
|
szToken = rParser.GetNextToken();
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
bci.fTopRadius = atof(szToken);
|
|
|
|
m_vecBoundingCylinderInfo.push_back( bci );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadMotionSheet( CSimpleParser &rParser )
|
|
{
|
|
int i;
|
|
char* szToken;
|
|
Z3DMOTIONSHEET* pCurrentSheet;
|
|
std::stack<Z3DMOTIONSHEET*> stackParentSheet;
|
|
|
|
Z3DTOK tok;
|
|
|
|
pCurrentSheet = NULL;
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( "sheet", szToken ) )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
stackParentSheet.push( pCurrentSheet );
|
|
pCurrentSheet = new Z3DMOTIONSHEET;
|
|
pCurrentSheet->rpParentSheet = stackParentSheet.top();
|
|
|
|
tok = g_TokSheetName.Add( szToken );
|
|
if( m_mapTok2MotionSheet.end() != m_mapTok2MotionSheet.find( tok ) )
|
|
{
|
|
return false; // motion sheet 이름 중복
|
|
}
|
|
m_mapTok2MotionSheet[tok] = pCurrentSheet;
|
|
}
|
|
else if( 0 == stricmp( ";", szToken) )
|
|
{
|
|
if( stackParentSheet.empty() )
|
|
{
|
|
break; // "motionsheet" 토큰과 대응되는 ";", sheet 읽기 끝
|
|
}
|
|
|
|
pCurrentSheet = stackParentSheet.top();
|
|
stackParentSheet.pop();
|
|
}
|
|
else
|
|
{
|
|
Z3DTOK tokMotionName = g_TokMotionName.Add( szToken );
|
|
Z3DMOTLET* pMotlet = new Z3DMOTLET;
|
|
|
|
Z3DTOKARRAY ta;
|
|
Z3DTOK tokMotionFile;
|
|
ta.Alloc( m_lAniHolderCount );
|
|
for( i = 0; i < m_lAniHolderCount; ++i )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
if( 0 == stricmp("NULL", szToken) )
|
|
{
|
|
tokMotionFile = NULL_TOK;
|
|
}
|
|
else
|
|
{
|
|
tokMotionFile = g_TokFileName.Add( szToken );
|
|
}
|
|
ta.pArray[i] = tokMotionFile;
|
|
}
|
|
|
|
if( NULL == (szToken = rParser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
if( 0 == stricmp( ";", szToken ) ) // 한줄짜리의 끝
|
|
{
|
|
pMotlet->Alloc( 1 );
|
|
pMotlet->lProbalilitySum = 1;
|
|
pMotlet->pProbabilityIdx[0] = 1;
|
|
pMotlet->pTokArr[0] = ta;
|
|
}
|
|
else // 여러줄짜리
|
|
{
|
|
std::vector<Z3DTOKARRAY> vecTa;
|
|
std::vector<long> vecProbabilityFactor;
|
|
vecProbabilityFactor.push_back( aton(szToken) );
|
|
vecTa.push_back( ta );
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
if( 0 == stricmp( ";", szToken ) ) // 여러줄읽기 끝
|
|
{
|
|
pMotlet->Alloc( vecTa.size() );
|
|
for( i = 0; i < pMotlet->lCount; ++i )
|
|
{
|
|
pMotlet->pTokArr[i] = vecTa[i];
|
|
pMotlet->pProbabilityIdx[i] = vecProbabilityFactor[i];
|
|
}
|
|
pMotlet->lProbalilitySum = vecProbabilityFactor.back();
|
|
break; // MOTLET 작성완료
|
|
}
|
|
else
|
|
{
|
|
ta.Alloc( m_lAniHolderCount );
|
|
for( i = 0; i < m_lAniHolderCount; ++i )
|
|
{
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
if( 0 == stricmp("NULL", szToken) )
|
|
{
|
|
tokMotionFile = NULL_TOK;
|
|
}
|
|
else
|
|
{
|
|
tokMotionFile = g_TokFileName.Add( szToken );
|
|
}
|
|
tokMotionFile = g_TokFileName.Add( szToken );
|
|
ta.pArray[i] = tokMotionFile;
|
|
szToken = rParser.GetNextToken();
|
|
}
|
|
vecTa.push_back( ta );
|
|
// 확률비율 읽기
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
vecProbabilityFactor.push_back( aton(szToken) + vecProbabilityFactor.back() );
|
|
}
|
|
}
|
|
}
|
|
if( pCurrentSheet->mapTok2Motlet.end() !=
|
|
pCurrentSheet->mapTok2Motlet.find( tokMotionName ) )
|
|
{
|
|
return false; // 한 sheet 안에 같은 이름의 motion이 중복됨
|
|
}
|
|
pCurrentSheet->mapTok2Motlet[tokMotionName] = pMotlet;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadStaticSlot( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
tok = g_TokSlotName.Add( szToken );
|
|
// 중복검사
|
|
if( m_vecTokStaticSlot.end() !=
|
|
std::find(
|
|
m_vecTokStaticSlot.begin(), m_vecTokStaticSlot.end(), tok )
|
|
)
|
|
{
|
|
return false;
|
|
}
|
|
m_vecTokStaticSlot.push_back( tok );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadOutfitSlot( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
tok = g_TokSlotName.Add( szToken );
|
|
// 중복검사
|
|
if( m_vecTokOutfitSlot.end() !=
|
|
std::find(
|
|
m_vecTokOutfitSlot.begin(), m_vecTokOutfitSlot.end(), tok )
|
|
)
|
|
{
|
|
return false;
|
|
}
|
|
m_vecTokOutfitSlot.push_back( tok );
|
|
|
|
|
|
if( NULL == (szToken = rParser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
m_vecOutfitSlotOverlayCount.push_back( aton(szToken) );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadAttachementSlot( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
tok = g_TokSlotName.Add( szToken );
|
|
// 중복검사
|
|
if( m_vecTokAttachmentSlot.end() !=
|
|
std::find(
|
|
m_vecTokAttachmentSlot.begin(), m_vecTokAttachmentSlot.end(), tok )
|
|
)
|
|
{
|
|
return false;
|
|
}
|
|
m_vecTokAttachmentSlot.push_back( tok );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadAttachmentSet( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
Z3DATTACHMENTINFO* pAInfo;
|
|
std::vector<Z3DATTACHMENTHOLDERINFO> vecHolder;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( 0 == stricmp( "set", szToken ) )
|
|
{
|
|
if( NULL == ( szToken = rParser.GetNextToken() ) )
|
|
{
|
|
return false;
|
|
}
|
|
Z3DTOK tokName = g_TokAttachmentName.Add( szToken );
|
|
pAInfo = new Z3DATTACHMENTINFO;
|
|
// 값이 들어가지 않을수 있는 필드 초기화
|
|
pAInfo->tokTextureFile2 = NULL_TOK;
|
|
vecHolder.clear();
|
|
|
|
szToken = rParser.GetNextToken();
|
|
while( NULL != szToken )
|
|
{
|
|
if( 0 == stricmp( "type", szToken ) )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
pAInfo->lType = aton( szToken );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
}
|
|
else if( 0 == stricmp( "mesh", szToken ) )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
pAInfo->tokMeshFile = g_TokFileName.Add( szToken );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
}
|
|
else if( 0 == stricmp( "tex", szToken ) )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
pAInfo->tokTextureFile = g_TokFileName.Add( szToken );
|
|
szToken = rParser.GetNextToken();
|
|
if( 0 == stricmp( ":", szToken ) )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
pAInfo->tokTextureFile2 = g_TokFileName.Add( szToken );
|
|
szToken = rParser.GetNextToken();
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "holder", szToken ) )
|
|
{
|
|
if( false == ReadAttachmentHolder( rParser, vecHolder ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
szToken = rParser.GetNextToken();
|
|
}
|
|
else if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
if( m_mapTok2AttachmentInfo.end() != m_mapTok2AttachmentInfo.find( tokName ) )
|
|
{
|
|
return false; // 무기 중복
|
|
}
|
|
if( 0 == (pAInfo->lHolderCount = vecHolder.size()) )
|
|
{
|
|
return false;
|
|
}
|
|
pAInfo->pHolderInfo = new Z3DATTACHMENTHOLDERINFO[pAInfo->lHolderCount];
|
|
for( int i = 0; i < pAInfo->lHolderCount; ++i )
|
|
{
|
|
pAInfo->pHolderInfo[i] = vecHolder[i];
|
|
}
|
|
m_mapTok2AttachmentInfo[tokName] = pAInfo;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadAttachmentHolder( CSimpleParser &rParser, std::vector<Z3DATTACHMENTHOLDERINFO> &r_vecHolder )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
Z3DATTACHMENTHOLDERINFO holder;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( NULL == szToken )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
r_vecHolder.push_back( holder );
|
|
break;
|
|
}
|
|
else if( 0 == stricmp( "skel", szToken ) )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
holder.tokSkelPart = g_TokSkeletonPartName.Add( szToken );
|
|
}
|
|
else if( 0 == stricmp( "pos", szToken ) )
|
|
{
|
|
holder.vPos.x = atof( rParser.GetNextToken() );
|
|
holder.vPos.y = atof( rParser.GetNextToken() );
|
|
holder.vPos.z = atof( rParser.GetNextToken() );
|
|
}
|
|
else if( 0 == stricmp( "rot", szToken ) )
|
|
{
|
|
holder.qRot.x = atof( rParser.GetNextToken() );
|
|
holder.qRot.y = atof( rParser.GetNextToken() );
|
|
holder.qRot.z = atof( rParser.GetNextToken() );
|
|
holder.qRot.w = atof( rParser.GetNextToken() );
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadOutfitSet( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
Z3DTOK tokLink;
|
|
Z3DTOK tokLinkSlot;
|
|
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( 0 == stricmp( "set", szToken ) )
|
|
{
|
|
std::vector<Z3DTOK> vecTokMeshName;
|
|
std::vector<Z3DTOK> vecTokTextureName;
|
|
std::vector<Z3DTOK> vecTokTexture2Name;
|
|
|
|
if( NULL == ( szToken = rParser.GetNextToken() ) )
|
|
{
|
|
return false;
|
|
}
|
|
Z3DTOK tokName = g_TokOutfitName.Add( szToken );
|
|
if( m_mapTok2OutfitInfo.end() != m_mapTok2OutfitInfo.find(tokName) )
|
|
{
|
|
return false; // 복장 명칭 중복
|
|
}
|
|
|
|
szToken = rParser.GetNextToken();
|
|
if( 0 == stricmp( "link", szToken ) )
|
|
{
|
|
if( NULL == (szToken = rParser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
tokLink = g_TokOutfitName.Add( szToken );
|
|
|
|
if( NULL == (szToken = rParser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
tokLinkSlot = g_TokSlotName.GetTOK( szToken );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
}
|
|
else
|
|
{
|
|
tokLink = NULL_TOK;
|
|
tokLinkSlot = NULL_TOK;
|
|
}
|
|
|
|
while( 0 != stricmp( ";", szToken ) )
|
|
{
|
|
if( 0 == stricmp( "NULL", szToken ) )
|
|
{
|
|
tok = NULL_TOK;
|
|
}
|
|
else
|
|
{
|
|
tok = g_TokFileName.Add( szToken );
|
|
}
|
|
vecTokMeshName.push_back( tok );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
if( 0 == stricmp( "NULL", szToken ) )
|
|
{
|
|
tok = NULL_TOK;
|
|
}
|
|
else
|
|
{
|
|
tok = g_TokFileName.Add( szToken );
|
|
}
|
|
vecTokTextureName.push_back( tok );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
if( 0 == stricmp( ":", szToken ) )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
if( 0 == stricmp( "NULL", szToken ) )
|
|
{
|
|
tok = NULL_TOK;
|
|
}
|
|
else
|
|
{
|
|
tok = g_TokFileName.Add( szToken );
|
|
}
|
|
szToken = rParser.GetNextToken();
|
|
}
|
|
else
|
|
{
|
|
tok = NULL_TOK;
|
|
}
|
|
vecTokTexture2Name.push_back( tok );
|
|
}
|
|
|
|
if( 0 == vecTokMeshName.size() )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Z3DOUTFITINFO* pOInfo = new Z3DOUTFITINFO;
|
|
pOInfo->Alloc( vecTokMeshName.size() );
|
|
for( int i = 0; i < pOInfo->lCount; ++i )
|
|
{
|
|
pOInfo->pTokMeshName[i] = vecTokMeshName[i];
|
|
pOInfo->pTokTextureName[i] = vecTokTextureName[i];
|
|
pOInfo->pTokTexture2Name[i] = vecTokTexture2Name[i];
|
|
}
|
|
pOInfo->tokLinkOutfit = tokLink;
|
|
pOInfo->tokLinkSlot = tokLinkSlot;
|
|
m_mapTok2OutfitInfo[tokName] = pOInfo;
|
|
}
|
|
}
|
|
|
|
if( m_mapTok2OutfitInfo.size() > 1 )
|
|
{
|
|
m_bFixed = false;
|
|
}
|
|
else
|
|
{
|
|
m_bFixed = true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadDefaultAttachment( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3DTOK tok;
|
|
Z3DTOK_SLOT_ATTACHMENT TSA;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
tok = g_TokSlotName.GetTOK( szToken );
|
|
if( tok == NULL_TOK )
|
|
{
|
|
return false; // 등록되지 않은 슬롯
|
|
}
|
|
TSA.tokSlot = tok;
|
|
|
|
if( NULL == ( szToken = rParser.GetNextToken() ) )
|
|
{
|
|
return false;
|
|
}
|
|
tok = g_TokAttachmentName.GetTOK( szToken );
|
|
if( tok == NULL_TOK )
|
|
{
|
|
return false; // 등록되지 않은 attachment item
|
|
}
|
|
TSA.tokAttachment = tok;
|
|
|
|
m_vecDefaultAttachment.push_back( TSA );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadShaderInfo( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
long lIndex;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if( 0 == stricmp( "shader", szToken ) )
|
|
{
|
|
szToken = rParser.GetNextToken();
|
|
lIndex = aton(szToken);
|
|
|
|
if( lIndex < Z3D_MAX_SHADER_COUNT )
|
|
{
|
|
SAFE_DELETEA( m_aszShaderInfoList[lIndex] );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
m_aszShaderInfoList[lIndex] = new char[strlen(szToken)+1];
|
|
strcpy( m_aszShaderInfoList[lIndex], szToken );
|
|
}
|
|
else
|
|
{
|
|
// skip text content
|
|
szToken = rParser.GetNextToken();
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::ReadEffectInfo( CSimpleParser &rParser )
|
|
{
|
|
char* szToken;
|
|
Z3D_EFFECT_INFO* pEi;
|
|
|
|
while( szToken = rParser.GetNextToken() )
|
|
{
|
|
if( 0 == stricmp( ";", szToken ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
/*if( 0 == stricmp( "effect", szToken ) )
|
|
{
|
|
pEi = new Z3D_EFFECT_INFO;
|
|
|
|
szToken = rParser.GetNextToken();
|
|
pEi->szSkelName = new char[strlen(szToken) + 1];
|
|
strcpy( pEi->szSkelName, szToken );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
pEi->szESFName = new char[strlen(szToken) + 1];
|
|
strcpy( pEi->szESFName, szToken );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
pEi->vPos.x = atof( szToken );
|
|
szToken = rParser.GetNextToken();
|
|
pEi->vPos.y = atof( szToken );
|
|
szToken = rParser.GetNextToken();
|
|
pEi->vPos.z = atof( szToken );
|
|
|
|
szToken = rParser.GetNextToken();
|
|
pEi->qRot.x = atof( szToken );
|
|
szToken = rParser.GetNextToken();
|
|
pEi->qRot.y = atof( szToken );
|
|
szToken = rParser.GetNextToken();
|
|
pEi->qRot.z = atof( szToken );
|
|
szToken = rParser.GetNextToken();
|
|
pEi->qRot.w = atof( szToken );
|
|
|
|
m_vecEffectInfo.push_back( pEi );
|
|
}*/
|
|
char* szTemp = new char[strlen(szToken)+1];
|
|
strcpy( szTemp, szToken );
|
|
m_vecszEffectInfo.push_back(szTemp);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::Load( const char* szFileName, const char* szPath )
|
|
{
|
|
CSimpleParser parser;
|
|
Z3DTOK tok;
|
|
|
|
//if( false == parser.OpenFile( szFileName ) && szPath )
|
|
if( szPath )
|
|
{
|
|
SimpleString nname( szPath, szFileName );
|
|
|
|
if( false == parser.OpenFile( nname ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( false == parser.OpenFile( szFileName ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
char* szToken;
|
|
char szTmp[260];
|
|
|
|
while( (szToken = parser.GetNextToken()) != NULL )
|
|
{
|
|
if( 0 == stricmp( "skel", szToken ) )
|
|
{
|
|
szToken = parser.GetNextToken();
|
|
if( szPath )
|
|
{
|
|
sprintf( szTmp, "%s%s", szPath, szToken );
|
|
}
|
|
else
|
|
{
|
|
strcpy( szTmp, szToken );
|
|
}
|
|
|
|
if( false == ReadSkelFile( szTmp ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// szToken 에는 path name 을 붙이기 전의 순수한 skel 파일명이 담겨있음
|
|
m_szSkelFileName = new char[strlen(szToken)+1];
|
|
strcpy( m_szSkelFileName, szToken );
|
|
}
|
|
else if( 0 == stricmp( "skey", szToken ) )
|
|
{
|
|
szToken = parser.GetNextToken();
|
|
if( szPath )
|
|
{
|
|
sprintf( szTmp, "%s%s", szPath, szToken );
|
|
}
|
|
else
|
|
{
|
|
strcpy( szTmp, szToken );
|
|
}
|
|
|
|
if( false == ReadSkeyFile( szTmp ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// szToken 에는 path name 을 붙이기 전의 순수한 skel 파일명이 담겨있음
|
|
m_szSkelFileName = new char[strlen(szToken)+1];
|
|
strcpy( m_szSkelFileName, szToken );
|
|
}
|
|
else if( 0 == stricmp( "meshtype", szToken ) )
|
|
{
|
|
if( NULL == (szToken = parser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
long lType = aton( szToken );
|
|
if( 0 == lType )
|
|
{
|
|
m_MPT = Z3D_MPT_TEXPIECE;
|
|
}
|
|
else
|
|
{
|
|
m_MPT = Z3D_MPT_TEXTURE;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "skelpart", szToken ) )
|
|
{
|
|
if( false == ReadSkeletonPartInfo( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "boundingcylinder", szToken ) )
|
|
{
|
|
if( false == ReadBoundingCylinderInfo( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "motionsheet", szToken ) )
|
|
{
|
|
if( false == ReadMotionSheet( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "staticslot", szToken ) )
|
|
{
|
|
if( false == ReadStaticSlot( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "outfitslot", szToken ) )
|
|
{
|
|
if( false == ReadOutfitSlot( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "attachmentslot", szToken ) )
|
|
{
|
|
if( false == ReadAttachementSlot( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "attachmentset", szToken ) )
|
|
{
|
|
if( false == ReadAttachmentSet( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "outfitset", szToken ) )
|
|
{
|
|
if( false == ReadOutfitSet( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "default_outfit", szToken ) )
|
|
{
|
|
if( NULL == (szToken = parser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( NULL_TOK == (m_TokDefaultOutfit = g_TokOutfitName.GetTOK( szToken )) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "default_motion", szToken ) )
|
|
{
|
|
if( NULL == (szToken = parser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( NULL_TOK == (m_TokDefaultMotionSheet = g_TokSheetName.GetTOK( szToken )) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( NULL == (szToken = parser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( NULL_TOK == (m_TokDefaultMotion = g_TokMotionName.GetTOK( szToken )) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "default_attachment", szToken ) )
|
|
{
|
|
if( false == ReadDefaultAttachment( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "default_scale", szToken ) )
|
|
{
|
|
if( NULL == (szToken = parser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_fDefaultScale = atof(szToken);
|
|
}
|
|
else if( 0 == stricmp( "shaderinfo", szToken ) )
|
|
{
|
|
if( false == ReadShaderInfo( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "effectinfo", szToken ) )
|
|
{
|
|
if( false == ReadEffectInfo( parser ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if( 0 == stricmp( "effect_scale", szToken ) )
|
|
{
|
|
if( NULL == (szToken = parser.GetNextToken()) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_fEffectScale = atof(szToken);
|
|
}
|
|
}
|
|
|
|
m_szFileName = new char[strlen(szFileName) + 1];
|
|
strcpy( m_szFileName, szFileName );
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::Save( const char* szFileName, const char* szPath ) const
|
|
{
|
|
CZ3DMaskedStream mstrm;
|
|
Z3DTOK tok;
|
|
int i;
|
|
|
|
if( NULL == m_szFileName )
|
|
{
|
|
return false; // GCMDS not loaded yet for this instance
|
|
}
|
|
|
|
if( NULL == szFileName )
|
|
{
|
|
szFileName = m_szFileName;
|
|
}
|
|
|
|
if( szPath )
|
|
{
|
|
SimpleString nname( szPath, szFileName );
|
|
|
|
if( false == mstrm.Open( nname ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{ if( false == mstrm.Open( szFileName ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// skey
|
|
mstrm.Printf( "skey \"%s\"\n\n\n", m_szSkelFileName );
|
|
|
|
// meshtype (almost obsolete)
|
|
mstrm.Printf( "meshtype %d\t// 0 = TEXPIECE, 1 = TEXTURE\n\n\n", (m_MPT == Z3D_MPT_TEXTURE) ? 1 : 0 );
|
|
|
|
// skelpart
|
|
if( m_mapTok2SkelpartIdx.size() > 0 )
|
|
{
|
|
std::map<Z3DTOK, long>::const_iterator it;
|
|
|
|
mstrm.Printf( "skelpart\n" );
|
|
|
|
for( it = m_mapTok2SkelpartIdx.begin(); it != m_mapTok2SkelpartIdx.end(); ++it )
|
|
{
|
|
mstrm.Printf( "\t%s %d\n", g_TokSkeletonPartName.GetString( it->first ), it->second );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// boundingcylinder
|
|
if( m_vecBoundingCylinderInfo.size() )
|
|
{
|
|
mstrm.Printf( "boundingcylinder\n" );
|
|
|
|
for( i = 0; i < m_vecBoundingCylinderInfo.size(); ++i )
|
|
{
|
|
mstrm.Printf( "\t%d\t%d\t%4.1f\t%4.1f\n",
|
|
m_vecBoundingCylinderInfo[i].lBottomIdx,
|
|
m_vecBoundingCylinderInfo[i].lTopIdx,
|
|
m_vecBoundingCylinderInfo[i].fBottomRadius,
|
|
m_vecBoundingCylinderInfo[i].fTopRadius );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// motionsheet
|
|
if( false == WriteMotionSheet( mstrm ) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// staticslot
|
|
if( m_vecTokStaticSlot.size() )
|
|
{
|
|
mstrm.Printf( "staticslot\n" );
|
|
|
|
for( i = 0; i < m_vecTokStaticSlot.size(); ++i )
|
|
{
|
|
mstrm.Printf( "\t%s", g_TokSlotName.GetString( m_vecTokStaticSlot[i] ) );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// outfitslot
|
|
if( m_vecTokOutfitSlot.size() )
|
|
{
|
|
mstrm.Printf( "outfitslot\n" );
|
|
|
|
for( i = 0; i < m_vecTokOutfitSlot.size(); ++i )
|
|
{
|
|
mstrm.Printf( "\t%s\t%d\n",
|
|
g_TokSlotName.GetString( m_vecTokOutfitSlot[i] ), m_vecOutfitSlotOverlayCount[i] );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// attachmentslot
|
|
if( m_vecTokAttachmentSlot.size() )
|
|
{
|
|
mstrm.Printf( "attachmentslot\n" );
|
|
|
|
for( i = 0; i < m_vecTokAttachmentSlot.size(); ++i )
|
|
{
|
|
mstrm.Printf( "\t%s", g_TokSlotName.GetString( m_vecTokAttachmentSlot[i] ) );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// attachmentset
|
|
if( m_mapTok2AttachmentInfo.size() )
|
|
{
|
|
std::map<Z3DTOK, Z3DATTACHMENTINFO*>::const_iterator it;
|
|
|
|
mstrm.Printf( "attachmentset\n" );
|
|
|
|
for( it = m_mapTok2AttachmentInfo.begin(); it != m_mapTok2AttachmentInfo.end(); ++it )
|
|
{
|
|
mstrm.Printf( "\n\tset\t\"%s\"\n", g_TokAttachmentName.GetString( it->first ) );
|
|
mstrm.Printf( "\t\ttype\t%d\n", it->second->lType );
|
|
mstrm.Printf( "\t\tmesh\t\"%s\"\n", g_TokFileName.GetString( it->second->tokMeshFile ) );
|
|
mstrm.Printf( "\t\ttex\t\t\"%s\"\n", g_TokFileName.GetString( it->second->tokTextureFile ) );
|
|
|
|
for( i = 0; i < it->second->lHolderCount; ++i )
|
|
{
|
|
mstrm.Printf( "\t\tholder\n" );
|
|
|
|
mstrm.Printf( "\t\t\tskel\t%s\n",
|
|
g_TokSkeletonPartName.GetString( it->second->pHolderInfo[i].tokSkelPart ) );
|
|
mstrm.Printf( "\t\t\tpos\t%8.4f\t%8.4f\t%8.4f\n",
|
|
it->second->pHolderInfo[i].vPos.x,
|
|
it->second->pHolderInfo[i].vPos.y,
|
|
it->second->pHolderInfo[i].vPos.z );
|
|
mstrm.Printf( "\t\t\trot\t%f\t%f\t%f\t%f\n",
|
|
it->second->pHolderInfo[i].qRot.x,
|
|
it->second->pHolderInfo[i].qRot.y,
|
|
it->second->pHolderInfo[i].qRot.z,
|
|
it->second->pHolderInfo[i].qRot.w );
|
|
|
|
mstrm.Printf( "\t\t;\n" );
|
|
}
|
|
|
|
mstrm.Printf( "\t;\n\n" );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// outfitset
|
|
if( m_mapTok2OutfitInfo.size() )
|
|
{
|
|
std::map<Z3DTOK, Z3DOUTFITINFO*>::const_iterator it;
|
|
|
|
mstrm.Printf( "outfitset\n" );
|
|
|
|
for( it = m_mapTok2OutfitInfo.begin(); it != m_mapTok2OutfitInfo.end(); ++it )
|
|
{
|
|
mstrm.Printf( "\tset\t\"%s\"", g_TokOutfitName.GetString( it->first ) );
|
|
if( NULL_TOK == it->second->tokLinkSlot )
|
|
{
|
|
mstrm.Printf( "\n" );
|
|
}
|
|
else
|
|
{
|
|
mstrm.Printf( "\tlink \"%s\" %s\n",
|
|
g_TokOutfitName.GetString( it->second->tokLinkOutfit ),
|
|
g_TokSlotName.GetString( it->second->tokLinkSlot ) );
|
|
}
|
|
|
|
for( i = 0; i < it->second->lCount; ++i )
|
|
{
|
|
if( NULL_TOK == it->second->pTokTextureName[i] )
|
|
{
|
|
mstrm.Printf( "\t\t\"%s\"\tNULL\n",
|
|
g_TokFileName.GetString( it->second->pTokMeshName[i] ) );
|
|
}
|
|
else
|
|
{
|
|
mstrm.Printf( "\t\t\"%s\"\t\"%s\"\n",
|
|
g_TokFileName.GetString( it->second->pTokMeshName[i] ),
|
|
g_TokFileName.GetString( it->second->pTokTextureName[i] ) );
|
|
}
|
|
}
|
|
|
|
mstrm.Printf( "\t;\n" );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// default_outfit
|
|
mstrm.Printf( "default_outfit\t\"%s\"\n\n\n",
|
|
g_TokOutfitName.GetString(m_TokDefaultOutfit) );
|
|
|
|
// default_motion
|
|
mstrm.Printf( "default_motion\t%s\t%s\n\n\n",
|
|
g_TokSheetName.GetString( m_TokDefaultMotionSheet ),
|
|
g_TokMotionName.GetString( m_TokDefaultMotion ) );
|
|
|
|
// default_attachment
|
|
if( m_vecDefaultAttachment.size() )
|
|
{
|
|
mstrm.Printf( "default_attachment\n" );
|
|
|
|
for( i = 0; i < m_vecDefaultAttachment.size(); ++i )
|
|
{
|
|
mstrm.Printf( "\t%s\t\"%s\"\n",
|
|
g_TokSlotName.GetString( m_vecDefaultAttachment[i].tokSlot ),
|
|
g_TokAttachmentName.GetString( m_vecDefaultAttachment[i].tokAttachment ) );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// default_scale
|
|
if( 1.0f != m_fDefaultScale )
|
|
{
|
|
mstrm.Printf( "default_scale %f\n\n\n", m_fDefaultScale );
|
|
}
|
|
|
|
// shaderinfo
|
|
for( i = 0; i < Z3D_MAX_SHADER_COUNT; ++i )
|
|
{
|
|
if( NULL != m_aszShaderInfoList[i] )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if( i < Z3D_MAX_SHADER_COUNT ) // shader 정보가 하나라도 있을 경우(위 루프 중간에서 빠져나옴)
|
|
{
|
|
mstrm.Printf( "shaderinfo\n" );
|
|
|
|
for( i = 0; i < Z3D_MAX_SHADER_COUNT; ++i )
|
|
{
|
|
if( NULL != m_aszShaderInfoList[i] )
|
|
{
|
|
mstrm.Printf( "\tshader\t%d\t\"%s\"\n", i, m_aszShaderInfoList[i] );
|
|
}
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// effectinfo
|
|
if( m_vecszEffectInfo.size() )
|
|
{
|
|
mstrm.Printf( "effectinfo\n" );
|
|
|
|
for( i = 0; i < m_vecszEffectInfo.size(); ++i )
|
|
{
|
|
mstrm.Printf( "\t\"%s\"\n", m_vecszEffectInfo[i] );
|
|
}
|
|
|
|
mstrm.Printf( ";\n\n\n" );
|
|
}
|
|
|
|
// effect_scale
|
|
if( 1.0f != m_fEffectScale )
|
|
{
|
|
mstrm.Printf( "effect_scale %f\n\n\n", m_fEffectScale );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
static const char* MakeIndent( int n )
|
|
{
|
|
static char szBuffer[100];
|
|
|
|
if( n > 99 ) n = 99;
|
|
for( int i = 0; i < n; ++i )
|
|
{
|
|
szBuffer[i] = '\t';
|
|
}
|
|
szBuffer[i] = '\0';
|
|
|
|
return szBuffer;
|
|
}
|
|
|
|
#include <list>
|
|
|
|
static bool DumpSheet( CZ3DMaskedStream &rMstrm,
|
|
std::list< std::pair< Z3DTOK,Z3DMOTIONSHEET* > > listMotionSheet,
|
|
std::pair< Z3DTOK, Z3DMOTIONSHEET* > currentSheet, int nIndentCount )
|
|
{
|
|
std::map< Z3DTOK, Z3DMOTLET* >::iterator itMotlet;
|
|
std::list< std::pair< Z3DTOK,Z3DMOTIONSHEET* > >::iterator itMotionSheet;
|
|
std::pair< Z3DTOK, Z3DMOTIONSHEET* > childSheet;
|
|
Z3DMOTLET* pMotlet = NULL;
|
|
int i, j;
|
|
const char* szFileName;
|
|
|
|
// motion sheet name
|
|
rMstrm.Printf( "\n%ssheet %s\n", MakeIndent( nIndentCount ),
|
|
g_TokSheetName.GetString(currentSheet.first) );
|
|
|
|
for( itMotlet = currentSheet.second->mapTok2Motlet.begin();
|
|
itMotlet != currentSheet.second->mapTok2Motlet.end(); ++itMotlet )
|
|
{
|
|
// motion name
|
|
rMstrm.Printf( "%s%s\n", MakeIndent( nIndentCount+1 ),
|
|
g_TokMotionName.GetString( itMotlet->first ) );
|
|
|
|
pMotlet = itMotlet->second;
|
|
|
|
// 단일 동작
|
|
if( 1 == pMotlet->lCount )
|
|
{
|
|
rMstrm.Printf( "%s", MakeIndent( nIndentCount+1 ) );
|
|
for( i = 0; i < pMotlet->pTokArr->lCount; ++i )
|
|
{
|
|
if( NULL_TOK == pMotlet->pTokArr->pArray[i] )
|
|
{
|
|
szFileName = "NULL";
|
|
}
|
|
else
|
|
{
|
|
szFileName = g_TokFileName.GetString( pMotlet->pTokArr->pArray[i] );
|
|
}
|
|
|
|
rMstrm.Printf( "\t%s", szFileName );
|
|
}
|
|
rMstrm.Printf( ";\n\n" );
|
|
}
|
|
// 다중 동작(random)
|
|
else
|
|
{
|
|
long lPrevProbability = 0;
|
|
|
|
for( i = 0; i < pMotlet->lCount; ++i )
|
|
{
|
|
rMstrm.Printf( "%s", MakeIndent( nIndentCount+1 ) );
|
|
for( j = 0; j < pMotlet->pTokArr[i].lCount; ++j )
|
|
{
|
|
if( NULL_TOK == pMotlet->pTokArr->pArray[j] )
|
|
{
|
|
szFileName = "NULL";
|
|
}
|
|
else
|
|
{
|
|
szFileName = g_TokFileName.GetString( pMotlet->pTokArr->pArray[j] );
|
|
}
|
|
|
|
rMstrm.Printf( "\t%s", szFileName );
|
|
}
|
|
rMstrm.Printf( "\t%d", pMotlet->pProbabilityIdx[i] - lPrevProbability );
|
|
lPrevProbability = pMotlet->pProbabilityIdx[i];
|
|
|
|
if( i == pMotlet->lCount-1 ) // last item ?
|
|
{
|
|
rMstrm.Printf( ";\n\n" );
|
|
}
|
|
else
|
|
{
|
|
rMstrm.Printf( "\n" );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for( itMotionSheet = listMotionSheet.begin();
|
|
itMotionSheet != listMotionSheet.end(); ++itMotionSheet )
|
|
{
|
|
if( currentSheet.second == itMotionSheet->second->rpParentSheet )
|
|
{
|
|
DumpSheet( rMstrm, listMotionSheet, *itMotionSheet, nIndentCount+1 );
|
|
}
|
|
}
|
|
|
|
rMstrm.Printf( "%s;\n", MakeIndent( nIndentCount ),
|
|
g_TokSheetName.GetString(currentSheet.first) );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::WriteMotionSheet( CZ3DMaskedStream &rMstrm ) const
|
|
{
|
|
std::map< Z3DTOK, Z3DMOTIONSHEET* >::const_iterator it;
|
|
std::list< std::pair< Z3DTOK,Z3DMOTIONSHEET* > > listMotionSheet;
|
|
std::list< std::pair< Z3DTOK,Z3DMOTIONSHEET* > >::iterator itMotionSheet;
|
|
|
|
|
|
std::pair< Z3DTOK, Z3DMOTIONSHEET* > rootSheet;
|
|
|
|
for( it = m_mapTok2MotionSheet.begin(); it != m_mapTok2MotionSheet.end(); ++it )
|
|
{
|
|
listMotionSheet.push_back( *it );
|
|
}
|
|
|
|
if( 0 == listMotionSheet.size() )
|
|
{
|
|
return false; // no motion sheet (but it's not possible)
|
|
}
|
|
|
|
|
|
rMstrm.Printf( "motionsheet\n" );
|
|
|
|
int nIndentCount = 1;
|
|
|
|
// search for the root sheet
|
|
rootSheet.second = NULL;
|
|
for( itMotionSheet = listMotionSheet.begin();
|
|
itMotionSheet != listMotionSheet.end(); ++itMotionSheet )
|
|
{
|
|
if( NULL == itMotionSheet->second->rpParentSheet )
|
|
{
|
|
rootSheet = *itMotionSheet;
|
|
break;
|
|
}
|
|
}
|
|
if( NULL == rootSheet.second )
|
|
{
|
|
return false; // no root sheet ( it's not possible, either )
|
|
}
|
|
|
|
DumpSheet( rMstrm, listMotionSheet, rootSheet, 1 );
|
|
|
|
rMstrm.Printf( ";\n\n\n" );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// 이용 관련 함수
|
|
|
|
long CZ3DGCMDS::GetSkeletonPartObjectIdx( const char* szSkeletonPartName )
|
|
{
|
|
Z3DTOK tok = g_TokSkeletonPartName.GetTOK( szSkeletonPartName );
|
|
if( NULL_TOK == tok )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return GetSkeletonPartObjectIdx( tok );
|
|
}
|
|
|
|
|
|
long CZ3DGCMDS::GetSkeletonPartObjectIdx( Z3DTOK tokSkeletonPartName )
|
|
{
|
|
std::map<Z3DTOK, long>::iterator it;
|
|
|
|
if( m_mapTok2SkelpartIdx.end() == ( it = m_mapTok2SkelpartIdx.find(tokSkeletonPartName) ) )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
return it->second;
|
|
}
|
|
|
|
|
|
bool CZ3DGCMDS::AllocSkeleton( CZ3DSkeletonObject* &pSkeleton )
|
|
{
|
|
pSkeleton = new CZ3DSkeletonObject[m_lSkeletonCount];
|
|
|
|
for( long i = 0; i < m_lSkeletonCount; ++i )
|
|
{
|
|
if( -1 == m_pSkeletonHierarchy[i] )
|
|
{
|
|
pSkeleton[i].Link( NULL );
|
|
}
|
|
else
|
|
{
|
|
pSkeleton[i].Link( &(pSkeleton[m_pSkeletonHierarchy[i]]) );
|
|
}
|
|
|
|
pSkeleton[i].GetTM()->MakeIdent();
|
|
pSkeleton[i].SetIndex( m_pAniHolderIndex[i], m_pIndexInSubpart[i] );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
const Z3DOUTFITINFO* CZ3DGCMDS::GetOutfitInfo( Z3DTOK tokOutfitName )
|
|
{
|
|
std::map<Z3DTOK, Z3DOUTFITINFO*>::iterator it;
|
|
|
|
it = m_mapTok2OutfitInfo.find( tokOutfitName );
|
|
if( it == m_mapTok2OutfitInfo.end() )
|
|
{
|
|
return NULL;
|
|
}
|
|
//else
|
|
return it->second;
|
|
}
|
|
|
|
|
|
const Z3DATTACHMENTINFO* CZ3DGCMDS::GetAttachmentInfo( Z3DTOK tokAttachmentName )
|
|
{
|
|
std::map<Z3DTOK, Z3DATTACHMENTINFO*>::iterator it;
|
|
|
|
it = m_mapTok2AttachmentInfo.find( tokAttachmentName );
|
|
if( it == m_mapTok2AttachmentInfo.end() )
|
|
{
|
|
return NULL;
|
|
}
|
|
//else
|
|
return it->second;
|
|
}
|
|
|
|
|
|
Z3DMOTIONSHEET* CZ3DGCMDS::GetMotionsheet( Z3DTOK tokSheetName )
|
|
{
|
|
std::map<Z3DTOK, Z3DMOTIONSHEET*>::iterator it;
|
|
|
|
it = m_mapTok2MotionSheet.find( tokSheetName );
|
|
if( m_mapTok2MotionSheet.end() == it )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return it->second;
|
|
}
|
|
|
|
|
|
long CZ3DGCMDS::GetEffectInfoList( const char** &rpszEffectInfo )
|
|
{
|
|
if( 0 == m_vecszEffectInfo.size() )
|
|
{
|
|
rpszEffectInfo = NULL;
|
|
return 0;
|
|
}
|
|
|
|
rpszEffectInfo = const_cast<const char**>( &(m_vecszEffectInfo[0]) );
|
|
return m_vecszEffectInfo.size();
|
|
}
|
|
|
|
|
|
float CZ3DGCMDS::GetSizeFactor()
|
|
{
|
|
long lIdx = GetSkeletonPartObjectIdx( "HEAD" );
|
|
if( -1 == lIdx )
|
|
{
|
|
return 0.0f;
|
|
}
|
|
|
|
float fRet = 0.0f;
|
|
|
|
fRet += m_pLocalizerMatrix[lIdx]._41 * m_pLocalizerMatrix[lIdx]._41;
|
|
fRet += m_pLocalizerMatrix[lIdx]._42 * m_pLocalizerMatrix[lIdx]._42;
|
|
fRet += m_pLocalizerMatrix[lIdx]._43 * m_pLocalizerMatrix[lIdx]._43;
|
|
|
|
return sqrtf( fRet );
|
|
}
|
|
|
|
|
|
|
|
|
|
// 편집용 retrieval / modification 함수군
|
|
const char* CZ3DGCMDS::GetSkeyFileName()
|
|
{
|
|
return m_szSkelFileName;
|
|
}
|
|
|
|
void CZ3DGCMDS::SetSkeyFilename( const char* szFileName )
|
|
{
|
|
if( false == ReadSkeyFile( szFileName ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
SAFE_DELETEA( m_szSkelFileName );
|
|
m_szSkelFileName = new char[strlen(szFileName)+1];
|
|
strcpy( m_szSkelFileName, szFileName );
|
|
}
|
|
|
|
long CZ3DGCMDS::GetMeshType()
|
|
{
|
|
if( Z3D_MPT_TEXPIECE == m_MPT )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if( Z3D_MPT_TEXTURE == m_MPT )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void CZ3DGCMDS::SetMeshType( long lMeshType )
|
|
{
|
|
if( 0 == lMeshType )
|
|
{
|
|
m_MPT = Z3D_MPT_TEXPIECE;
|
|
}
|
|
|
|
if( 1 == lMeshType )
|
|
{
|
|
m_MPT = Z3D_MPT_TEXTURE;
|
|
}
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveSkelpartList( std::map<Z3DTOK, long>* &prSkelpartList )
|
|
{
|
|
prSkelpartList = &m_mapTok2SkelpartIdx;
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveMotionSheetList( std::map<Z3DTOK, Z3DMOTIONSHEET*>* &prMotionsheetList )
|
|
{
|
|
prMotionsheetList = &m_mapTok2MotionSheet;
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveOutfitList( std::map<Z3DTOK, Z3DOUTFITINFO*>* &prOutfitList )
|
|
{
|
|
prOutfitList = &m_mapTok2OutfitInfo;
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveAttachmentList( std::map<Z3DTOK, Z3DATTACHMENTINFO*>* &prAttachmentList )
|
|
{
|
|
prAttachmentList = &m_mapTok2AttachmentInfo;
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveStaticSlot( std::vector<Z3DTOK>* &prStaticSlot )
|
|
{
|
|
prStaticSlot = &m_vecTokStaticSlot;
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveOutfitSlot( std::vector<Z3DTOK>* &prOutfitSlot, std::vector<long>* &prOSOverlapCount )
|
|
{
|
|
prOutfitSlot = &m_vecTokOutfitSlot;
|
|
prOSOverlapCount = &m_vecOutfitSlotOverlayCount;
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveAttachmentSlot( std::vector<Z3DTOK>* &prAttachmentSlot )
|
|
{
|
|
prAttachmentSlot = &m_vecTokAttachmentSlot;
|
|
}
|
|
|
|
Z3DTOK CZ3DGCMDS::GetDefaultOutfit()
|
|
{
|
|
return m_TokDefaultOutfit;
|
|
}
|
|
|
|
void CZ3DGCMDS::SetDefaultOutfit( Z3DTOK tokDefaultOutfit )
|
|
{
|
|
m_TokDefaultOutfit = tokDefaultOutfit;
|
|
}
|
|
|
|
Z3DTOK CZ3DGCMDS::GetDefaultMotion()
|
|
{
|
|
return m_TokDefaultMotion;
|
|
}
|
|
|
|
void CZ3DGCMDS::SetDefaultMotion( Z3DTOK tok )
|
|
{
|
|
m_TokDefaultMotion = tok;
|
|
}
|
|
|
|
/*void CZ3DGCMDS::GetDefaultMotion( Z3DTOK &rtokMotionSheet, Z3DTOK &rtokMotion )
|
|
{
|
|
rtokMotionSheet = m_TokDefaultMotionSheet;
|
|
rtokMotion = m_TokDefaultMotion;
|
|
}
|
|
|
|
void CZ3DGCMDS::SetDefaultMotion( Z3DTOK tokMotionSheet, Z3DTOK tokMotion )
|
|
{
|
|
m_TokDefaultMotionSheet = tokMotionSheet;
|
|
m_TokDefaultMotion = tokMotion;
|
|
}*/
|
|
|
|
Z3DTOK CZ3DGCMDS::GetDefaultMotionSheet()
|
|
{
|
|
return m_TokDefaultMotionSheet;
|
|
}
|
|
|
|
void CZ3DGCMDS::SetDefaultMotionSheet( Z3DTOK tok )
|
|
{
|
|
m_TokDefaultMotionSheet = tok;
|
|
}
|
|
|
|
float CZ3DGCMDS::GetDefaultScale()
|
|
{
|
|
return m_fDefaultScale;
|
|
}
|
|
|
|
void CZ3DGCMDS::SetDefaultScale( float f )
|
|
{
|
|
if( f > 0.0f )
|
|
{
|
|
m_fDefaultScale = f;
|
|
}
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveDefaultAttachmentList( std::vector<Z3DTOK_SLOT_ATTACHMENT>* &prDefaultAttachmentList )
|
|
{
|
|
prDefaultAttachmentList = &m_vecDefaultAttachment;
|
|
}
|
|
|
|
void CZ3DGCMDS::RetrieveEffectInfoList( std::vector<char*>* &prEffectInfoList )
|
|
{
|
|
prEffectInfoList = &m_vecszEffectInfo;
|
|
}
|
|
|
|
|
|
const char* CZ3DGCMDS::GetSkeletonName( int idx )
|
|
{
|
|
if( idx >= m_lSkeletonCount )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if( NULL == m_pszSkeletonName )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return m_pszSkeletonName[idx];
|
|
}
|
|
|
|
|
|
float CZ3DGCMDS::GetEffectScale()
|
|
{
|
|
return m_fEffectScale;
|
|
}
|
|
|
|
void CZ3DGCMDS::SetEffectScale( float f )
|
|
{
|
|
if( f > 0.0f )
|
|
{
|
|
m_fEffectScale = f;
|
|
}
|
|
}
|