mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 22:27:05 +00:00
228 lines
6.9 KiB
C++
228 lines
6.9 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "dmserializers.h"
|
|
#include "dmebaseimporter.h"
|
|
#include "datamodel/idatamodel.h"
|
|
#include "datamodel/dmelement.h"
|
|
#include "tier1/KeyValues.h"
|
|
#include "tier1/utlbuffer.h"
|
|
#include "tier1/utlmap.h"
|
|
#include <limits.h>
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Format converter
|
|
//-----------------------------------------------------------------------------
|
|
class CImportSFMV3 : public CSFMBaseImporter
|
|
{
|
|
typedef CSFMBaseImporter BaseClass;
|
|
public:
|
|
CImportSFMV3( char const *formatName, char const *nextFormatName );
|
|
|
|
private:
|
|
virtual bool DoFixup( CDmElement *pSourceRoot );
|
|
|
|
|
|
void FixupElement( CDmElement *pElement );
|
|
// Fixes up all elements
|
|
void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Singleton instance
|
|
//-----------------------------------------------------------------------------
|
|
static CImportSFMV3 s_ImportSFMV3( "sfm_v3", "sfm_v4" );
|
|
|
|
void InstallSFMV3Importer( IDataModel *pFactory )
|
|
{
|
|
pFactory->AddLegacyUpdater( &s_ImportSFMV3 );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CImportSFMV3::CImportSFMV3( char const *formatName, char const *nextFormatName ) :
|
|
BaseClass( formatName, nextFormatName )
|
|
{
|
|
}
|
|
|
|
|
|
struct LogToCurveInfoTypeMap_t
|
|
{
|
|
const char *pLogType;
|
|
const char *pLogLayerType;
|
|
const char *pCurveInfoType;
|
|
};
|
|
|
|
LogToCurveInfoTypeMap_t g_typeMap[] =
|
|
{
|
|
{ "DmeIntLog", "DmeIntLogLayer", "DmeIntCurveInfo" },
|
|
{ "DmeFloatLog", "DmeFloatLogLayer", "DmeFloatCurveInfo" },
|
|
{ "DmeBoolLog", "DmeBoolLogLayer", "DmeBoolCurveInfo" },
|
|
// string,
|
|
// void,
|
|
// objectid,
|
|
{ "DmeColorLog", "DmeColorLogLayer", "DmeColorCurveInfo" },
|
|
{ "DmeVector2Log", "DmeVector2LogLayer", "DmeVector2CurveInfo" },
|
|
{ "DmeVector3Log", "DmeVector3LogLayer", "DmeVector3CurveInfo" },
|
|
{ "DmeVector4Log", "DmeVector4LogLayer", "DmeVector4CurveInfo" },
|
|
{ "DmeQAngleLog", "DmeQAngleLogLayer", "DmeQAngleCurveInfo" },
|
|
{ "DmeQuaternionLog", "DmeQuaternionLogLayer","DmeQuaternionCurveInfo" },
|
|
{ "DmeVMatrixLog", "DmeVMatrixLogLayer", "DmeVMatrixCurveInfo" },
|
|
};
|
|
|
|
const char *GetCurveInfoTypeFromLogType( const char *pLogType )
|
|
{
|
|
int c = ARRAYSIZE( g_typeMap );
|
|
for ( int i = 0; i < c; ++i )
|
|
{
|
|
if ( !Q_stricmp( pLogType, g_typeMap[ i ].pLogType ) )
|
|
return g_typeMap[ i ].pCurveInfoType;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
bool IsLogLayerType( const char *pLogLayerType )
|
|
{
|
|
int c = ARRAYSIZE( g_typeMap );
|
|
for ( int i = 0; i < c; ++i )
|
|
{
|
|
if ( !Q_stricmp( pLogLayerType, g_typeMap[ i ].pLogLayerType ) )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void MoveAttribute( CDmElement *pFromElement, const char *pFromAttrName, CDmElement *pToElement = NULL, const char *pToAttrName = NULL, DmAttributeType_t toType = AT_UNKNOWN )
|
|
{
|
|
if ( !pToAttrName )
|
|
{
|
|
pToAttrName = pFromAttrName;
|
|
}
|
|
|
|
if ( pToElement )
|
|
{
|
|
CDmAttribute *pFromAttr = pFromElement->GetAttribute( pFromAttrName );
|
|
const void *pValue = pFromAttr->GetValueUntyped();
|
|
DmAttributeType_t fromType = pFromAttr->GetType();
|
|
if ( toType == AT_UNKNOWN )
|
|
{
|
|
toType = fromType;
|
|
}
|
|
|
|
CDmAttribute *pToAttr = pToElement->AddAttribute( pToAttrName, toType );
|
|
if ( !pToAttr )
|
|
{
|
|
Warning( "*** Problem in converter encountered!\n" );
|
|
Warning( "*** Unable to find or add attribute \"%s\" to element \"%s\"!\n", pToAttrName, pToElement->GetName() );
|
|
}
|
|
else if ( fromType != toType )
|
|
{
|
|
Warning( "*** Problem in file encountered!\n" );
|
|
Warning( "*** Element \"%s\" has attribute \"%s\" with an unexpected type!\n", pFromElement->GetName(), pFromAttrName );
|
|
}
|
|
else
|
|
{
|
|
pToAttr->SetValue( toType, pValue );
|
|
}
|
|
}
|
|
|
|
pFromElement->RemoveAttribute( pFromAttrName );
|
|
}
|
|
|
|
// Fixes up all elements
|
|
//-----------------------------------------------------------------------------
|
|
void CImportSFMV3::FixupElement( CDmElement *pElement )
|
|
{
|
|
if ( !pElement )
|
|
return;
|
|
|
|
const char *pType = pElement->GetTypeString();
|
|
|
|
// log layer
|
|
if ( IsLogLayerType( pType ) )
|
|
{
|
|
pElement->RemoveAttribute( "ownerlog" );
|
|
return;
|
|
}
|
|
|
|
// log
|
|
const char *pCurveInfoType = GetCurveInfoTypeFromLogType( pType );
|
|
if ( !pCurveInfoType )
|
|
return;
|
|
|
|
CDmElement *pCurveInfo = NULL;
|
|
CDmAttribute *pUseCurveTypeAttr = pElement->GetAttribute( "usecurvetypes" );
|
|
if ( pUseCurveTypeAttr && pUseCurveTypeAttr->GetValue<bool>() )
|
|
{
|
|
DmElementHandle_t hElement = g_pDataModel->CreateElement( "curve info", pCurveInfoType, pElement->GetFileId() );
|
|
pCurveInfo = g_pDataModel->GetElement( hElement );
|
|
}
|
|
pElement->RemoveAttribute( "usecurvetypes" );
|
|
|
|
MoveAttribute( pElement, "defaultcurvetype", pCurveInfo, "defaultCurveType", AT_INT );
|
|
MoveAttribute( pElement, "defaultedgezerovalue",pCurveInfo, "defaultEdgeZeroValue" );
|
|
MoveAttribute( pElement, "useedgeinfo", pCurveInfo, "useEdgeInfo", AT_BOOL );
|
|
MoveAttribute( pElement, "rightedgetime", pCurveInfo, "rightEdgeTime", AT_INT );
|
|
MoveAttribute( pElement, "left_edge_active", pCurveInfo, "leftEdgeActive", AT_BOOL );
|
|
MoveAttribute( pElement, "right_edge_active", pCurveInfo, "rightEdgeActive", AT_BOOL );
|
|
MoveAttribute( pElement, "left_edge_curvetype", pCurveInfo, "leftEdgeCurveType", AT_INT );
|
|
MoveAttribute( pElement, "right_edge_curvetype",pCurveInfo, "rightEdgeCurveType", AT_INT );
|
|
MoveAttribute( pElement, "left_edge_value", pCurveInfo, "leftEdgeValue" );
|
|
MoveAttribute( pElement, "right_edge_value", pCurveInfo, "rightEdgeValue" );
|
|
}
|
|
|
|
// Fixes up all elements
|
|
//-----------------------------------------------------------------------------
|
|
void CImportSFMV3::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
|
|
{
|
|
if ( !pElement )
|
|
return;
|
|
|
|
if ( list.Find( pElement ) != list.InvalidIndex() )
|
|
return;
|
|
|
|
list.Insert( pElement );
|
|
|
|
// Descend to bottom of tree, then do fixup coming back up the tree
|
|
for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
|
|
{
|
|
if ( pAttribute->GetType() == AT_ELEMENT )
|
|
{
|
|
CDmElement *pElementAt = pAttribute->GetValueElement<CDmElement>( );
|
|
BuildList( pElementAt, list );
|
|
continue;
|
|
}
|
|
|
|
if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
|
|
{
|
|
CDmrElementArray<> array( pAttribute );
|
|
int nCount = array.Count();
|
|
for ( int i = 0; i < nCount; ++i )
|
|
{
|
|
CDmElement *pChild = array[ i ];
|
|
BuildList( pChild, list );
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CImportSFMV3::DoFixup( CDmElement *pSourceRoot )
|
|
{
|
|
CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
|
|
BuildList( pSourceRoot, fixlist );
|
|
for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
|
|
{
|
|
// Search and replace in the entire tree!
|
|
FixupElement( fixlist[ i ] );
|
|
}
|
|
return true;
|
|
}
|