diff options
Diffstat (limited to 'dmserializers/importsfmv3.cpp')
| -rw-r--r-- | dmserializers/importsfmv3.cpp | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/dmserializers/importsfmv3.cpp b/dmserializers/importsfmv3.cpp new file mode 100644 index 0000000..d421eb3 --- /dev/null +++ b/dmserializers/importsfmv3.cpp @@ -0,0 +1,227 @@ +//========= 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; +} |