diff options
Diffstat (limited to 'dmserializers/importsfmv2.cpp')
| -rw-r--r-- | dmserializers/importsfmv2.cpp | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/dmserializers/importsfmv2.cpp b/dmserializers/importsfmv2.cpp new file mode 100644 index 0000000..829ae0c --- /dev/null +++ b/dmserializers/importsfmv2.cpp @@ -0,0 +1,294 @@ +//========= 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 CImportSFMV2 : public CSFMBaseImporter +{ + typedef CSFMBaseImporter BaseClass; +public: + CImportSFMV2( 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 CImportSFMV2 s_ImportSFMV2( "sfm_v2", "sfm_v3" ); + +void InstallSFMV2Importer( IDataModel *pFactory ) +{ + pFactory->AddLegacyUpdater( &s_ImportSFMV2 ); +} + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CImportSFMV2::CImportSFMV2( char const *formatName, char const *nextFormatName ) : + BaseClass( formatName, nextFormatName ) +{ +} + + +struct LayerType_t +{ + char const *loglayertype; + int datatype; + char const *logtype; +}; + +static LayerType_t g_LayerTypes[] = +{ + { "DmeIntLogLayer", AT_INT_ARRAY, "DmeIntLog" }, + { "DmeFloatLogLayer", AT_FLOAT_ARRAY, "DmeFloatLog" }, + { "DmeBoolLogLayer", AT_BOOL_ARRAY, "DmeBoolLog" }, + // AT_STRING_ARRAY, + // AT_VOID_ARRAY, + // AT_OBJECTID_ARRAY, + { "DmeColorLogLayer", AT_COLOR_ARRAY, "DmeColorLog" }, + { "DmeVector2LogLayer", AT_VECTOR2_ARRAY, "DmeVector2Log" }, + { "DmeVector3LogLayer", AT_VECTOR3_ARRAY, "DmeVector3Log" }, + { "DmeVector4LogLayer", AT_VECTOR4_ARRAY, "DmeVector4Log" }, + { "DmeQAngleLogLayer", AT_QANGLE_ARRAY, "DmeQAngleLog" }, + { "DmeQuaternionLogLayer", AT_QUATERNION_ARRAY, "DmeQuaternionLog" }, + { "DmeVMatrixLogLayer", AT_VMATRIX_ARRAY, "DmeVMatrixLog" }, + // AT_ELEMENT_ARRAY + // NO ARRAY TYPES EITHER!!! +}; + +int GetLogType( char const *type ) +{ + int c = ARRAYSIZE( g_LayerTypes ); + for ( int i = 0; i < c; ++i ) + { + if ( !Q_stricmp( type, g_LayerTypes[ i ].logtype ) ) + return g_LayerTypes[ i ].datatype; + } + return AT_UNKNOWN; +} + +char const *GetLogLayerType( int nDataType ) +{ + int c = ARRAYSIZE( g_LayerTypes ); + for ( int i = 0; i < c; ++i ) + { + if ( nDataType == g_LayerTypes[ i ].datatype ) + return g_LayerTypes[ i ].loglayertype; + } + return NULL; +} + +char const *GetLogLayerType( char const *logType ) +{ + int c = ARRAYSIZE( g_LayerTypes ); + for ( int i = 0; i < c; ++i ) + { + if ( !Q_stricmp( logType, g_LayerTypes[ i ].logtype ) ) + return g_LayerTypes[ i ].loglayertype; + } + return NULL; +} + +template< class T > +void CopyValues( int layerType, CDmElement *pElement, CDmElement *pLayer, CDmAttribute *pInTimeAttribute, CDmAttribute *pInCurveTypeAttribute ) +{ + CDmAttribute *pInValueAttribute = pElement->GetAttribute( "values" ); + if ( !pInValueAttribute ) + { + Assert( 0 ); + return; + } + + CDmrArray<T> outValues( pLayer->AddAttribute( "values", (DmAttributeType_t)layerType ) ); + CDmrArray<int> outTimes( pLayer->AddAttribute( "times", AT_INT_ARRAY ) ); + CDmrArray<int> outCurveTypes; + if ( pInCurveTypeAttribute ) + { + outCurveTypes.Init( pLayer->AddAttribute( "curvetypes", AT_INT_ARRAY ) ); + } + + CDmrArray<T> inValues( pInValueAttribute ); + CDmrArray<int> inTimes( pInTimeAttribute ); + CDmrArray<int> inCurveTypes( pInCurveTypeAttribute ); + + Assert( inValues.Count() == inTimes.Count() ); + int c = inValues.Count(); + for ( int i = 0; i < c; ++i ) + { + outTimes.AddToTail( inTimes[ i ] ); + outValues.AddToTail( inValues[ i ] ); + if ( outCurveTypes.IsValid() ) + { + outCurveTypes.AddToTail( inCurveTypes[ i ] ); + } + } +} + + +//----------------------------------------------------------------------------- +// Fixes up all elements +//----------------------------------------------------------------------------- +void CImportSFMV2::FixupElement( CDmElement *pElement ) +{ + if ( !pElement ) + return; + + // Perform the fixup + const char *pType = pElement->GetTypeString(); + int layerType = GetLogType( pType ); + if ( layerType != AT_UNKNOWN ) + { + /* + char buf[ 128 ]; + g_pDataModel->ToString( pElement->GetId(), buf, sizeof( buf ) ); + + Msg( "Processing %s %s id %s\n", + pElement->GetTypeString(), pElement->GetName(), buf ); + */ + + // Find attribute arrays for times, values and curvetypes + CDmAttribute *pTimes = pElement->GetAttribute( "times" ); + CDmAttribute *pCurveTypes = NULL; + + // FIX + CDmAttribute *pAttr = pElement->AddAttribute( "usecurvetypes", AT_BOOL ); + if ( pAttr->GetValue<bool>() ) + { + pCurveTypes = pElement->GetAttribute( "curvetypes" ); + } + + // Get the default layer (added when the new style log is created) + CDmrElementArray<> layers( pElement->AddAttribute( "layers", AT_ELEMENT_ARRAY ) ); + CDmElement *layer = NULL; + if ( layers.Count() == 0 ) + { + DmElementHandle_t hElement = g_pDataModel->CreateElement( GetLogLayerType( layerType ), GetLogLayerType( layerType ), pElement->GetFileId() ); + layer = g_pDataModel->GetElement( hElement ); + layers.AddToTail( layer ); + } + else + { + Assert( layers.Count() == 1 ); + layer = layers[ 0 ]; + } + + // Copy data + switch ( layerType ) + { + default: + case AT_UNKNOWN: + break; + case AT_FLOAT_ARRAY: + CopyValues< float >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_INT_ARRAY: + CopyValues< int >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_BOOL_ARRAY: + CopyValues< bool >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_COLOR_ARRAY: + CopyValues< Color >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_VECTOR2_ARRAY: + CopyValues< Vector2D >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_VECTOR3_ARRAY: + CopyValues< Vector >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_VECTOR4_ARRAY: + CopyValues< Vector4D >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_QANGLE_ARRAY: + CopyValues< QAngle >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_QUATERNION_ARRAY: + CopyValues< Quaternion >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + case AT_VMATRIX_ARRAY: + CopyValues< VMatrix >( layerType, pElement, layer, pTimes, pCurveTypes ); + break; + } + + // Set the back pointer + CDmAttribute *ownerLog = layer->AddAttribute( "ownerlog", AT_ELEMENT ); + Assert( ownerLog ); + ownerLog->SetValue( pElement->GetHandle() ); + + // Delete the base attributes + pElement->RemoveAttribute( "times" ); + pElement->RemoveAttribute( "values" ); + pElement->RemoveAttribute( "curvetypes" ); + } +} + +// Fixes up all elements +//----------------------------------------------------------------------------- +void CImportSFMV2::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list ) +{ + if ( !pElement ) + return; + + if ( list.Find( pElement ) != list.InvalidIndex() ) + return; + + list.Insert( pElement ); + + // Descene 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 CImportSFMV2::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; +} |