summaryrefslogtreecommitdiff
path: root/dmserializers/importsfmv2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dmserializers/importsfmv2.cpp')
-rw-r--r--dmserializers/importsfmv2.cpp294
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;
+}