Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
8.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "dmserializers.h"
  7. #include "dmebaseimporter.h"
  8. #include "datamodel/idatamodel.h"
  9. #include "datamodel/dmelement.h"
  10. #include "tier1/KeyValues.h"
  11. #include "tier1/utlbuffer.h"
  12. #include "tier1/utlmap.h"
  13. #include <limits.h>
  14. //-----------------------------------------------------------------------------
  15. // Format converter
  16. //-----------------------------------------------------------------------------
  17. class CImportSFMV2 : public CSFMBaseImporter
  18. {
  19. typedef CSFMBaseImporter BaseClass;
  20. public:
  21. CImportSFMV2( char const *formatName, char const *nextFormatName );
  22. private:
  23. virtual bool DoFixup( CDmElement *pSourceRoot );
  24. void FixupElement( CDmElement *pElement );
  25. // Fixes up all elements
  26. void BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list );
  27. };
  28. //-----------------------------------------------------------------------------
  29. // Singleton instance
  30. //-----------------------------------------------------------------------------
  31. static CImportSFMV2 s_ImportSFMV2( "sfm_v2", "sfm_v3" );
  32. void InstallSFMV2Importer( IDataModel *pFactory )
  33. {
  34. pFactory->AddLegacyUpdater( &s_ImportSFMV2 );
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Constructor
  38. //-----------------------------------------------------------------------------
  39. CImportSFMV2::CImportSFMV2( char const *formatName, char const *nextFormatName ) :
  40. BaseClass( formatName, nextFormatName )
  41. {
  42. }
  43. struct LayerType_t
  44. {
  45. char const *loglayertype;
  46. int datatype;
  47. char const *logtype;
  48. };
  49. static LayerType_t g_LayerTypes[] =
  50. {
  51. { "DmeIntLogLayer", AT_INT_ARRAY, "DmeIntLog" },
  52. { "DmeFloatLogLayer", AT_FLOAT_ARRAY, "DmeFloatLog" },
  53. { "DmeBoolLogLayer", AT_BOOL_ARRAY, "DmeBoolLog" },
  54. // AT_STRING_ARRAY,
  55. // AT_VOID_ARRAY,
  56. // AT_OBJECTID_ARRAY,
  57. { "DmeColorLogLayer", AT_COLOR_ARRAY, "DmeColorLog" },
  58. { "DmeVector2LogLayer", AT_VECTOR2_ARRAY, "DmeVector2Log" },
  59. { "DmeVector3LogLayer", AT_VECTOR3_ARRAY, "DmeVector3Log" },
  60. { "DmeVector4LogLayer", AT_VECTOR4_ARRAY, "DmeVector4Log" },
  61. { "DmeQAngleLogLayer", AT_QANGLE_ARRAY, "DmeQAngleLog" },
  62. { "DmeQuaternionLogLayer", AT_QUATERNION_ARRAY, "DmeQuaternionLog" },
  63. { "DmeVMatrixLogLayer", AT_VMATRIX_ARRAY, "DmeVMatrixLog" },
  64. // AT_ELEMENT_ARRAY
  65. // NO ARRAY TYPES EITHER!!!
  66. };
  67. int GetLogType( char const *type )
  68. {
  69. int c = ARRAYSIZE( g_LayerTypes );
  70. for ( int i = 0; i < c; ++i )
  71. {
  72. if ( !Q_stricmp( type, g_LayerTypes[ i ].logtype ) )
  73. return g_LayerTypes[ i ].datatype;
  74. }
  75. return AT_UNKNOWN;
  76. }
  77. char const *GetLogLayerType( int nDataType )
  78. {
  79. int c = ARRAYSIZE( g_LayerTypes );
  80. for ( int i = 0; i < c; ++i )
  81. {
  82. if ( nDataType == g_LayerTypes[ i ].datatype )
  83. return g_LayerTypes[ i ].loglayertype;
  84. }
  85. return NULL;
  86. }
  87. char const *GetLogLayerType( char const *logType )
  88. {
  89. int c = ARRAYSIZE( g_LayerTypes );
  90. for ( int i = 0; i < c; ++i )
  91. {
  92. if ( !Q_stricmp( logType, g_LayerTypes[ i ].logtype ) )
  93. return g_LayerTypes[ i ].loglayertype;
  94. }
  95. return NULL;
  96. }
  97. template< class T >
  98. void CopyValues( int layerType, CDmElement *pElement, CDmElement *pLayer, CDmAttribute *pInTimeAttribute, CDmAttribute *pInCurveTypeAttribute )
  99. {
  100. CDmAttribute *pInValueAttribute = pElement->GetAttribute( "values" );
  101. if ( !pInValueAttribute )
  102. {
  103. Assert( 0 );
  104. return;
  105. }
  106. CDmrArray<T> outValues( pLayer->AddAttribute( "values", (DmAttributeType_t)layerType ) );
  107. CDmrArray<int> outTimes( pLayer->AddAttribute( "times", AT_INT_ARRAY ) );
  108. CDmrArray<int> outCurveTypes;
  109. if ( pInCurveTypeAttribute )
  110. {
  111. outCurveTypes.Init( pLayer->AddAttribute( "curvetypes", AT_INT_ARRAY ) );
  112. }
  113. CDmrArray<T> inValues( pInValueAttribute );
  114. CDmrArray<int> inTimes( pInTimeAttribute );
  115. CDmrArray<int> inCurveTypes( pInCurveTypeAttribute );
  116. Assert( inValues.Count() == inTimes.Count() );
  117. int c = inValues.Count();
  118. for ( int i = 0; i < c; ++i )
  119. {
  120. outTimes.AddToTail( inTimes[ i ] );
  121. outValues.AddToTail( inValues[ i ] );
  122. if ( outCurveTypes.IsValid() )
  123. {
  124. outCurveTypes.AddToTail( inCurveTypes[ i ] );
  125. }
  126. }
  127. }
  128. //-----------------------------------------------------------------------------
  129. // Fixes up all elements
  130. //-----------------------------------------------------------------------------
  131. void CImportSFMV2::FixupElement( CDmElement *pElement )
  132. {
  133. if ( !pElement )
  134. return;
  135. // Perform the fixup
  136. const char *pType = pElement->GetTypeString();
  137. int layerType = GetLogType( pType );
  138. if ( layerType != AT_UNKNOWN )
  139. {
  140. /*
  141. char buf[ 128 ];
  142. g_pDataModel->ToString( pElement->GetId(), buf, sizeof( buf ) );
  143. Msg( "Processing %s %s id %s\n",
  144. pElement->GetTypeString(), pElement->GetName(), buf );
  145. */
  146. // Find attribute arrays for times, values and curvetypes
  147. CDmAttribute *pTimes = pElement->GetAttribute( "times" );
  148. CDmAttribute *pCurveTypes = NULL;
  149. // FIX
  150. CDmAttribute *pAttr = pElement->AddAttribute( "usecurvetypes", AT_BOOL );
  151. if ( pAttr->GetValue<bool>() )
  152. {
  153. pCurveTypes = pElement->GetAttribute( "curvetypes" );
  154. }
  155. // Get the default layer (added when the new style log is created)
  156. CDmrElementArray<> layers( pElement->AddAttribute( "layers", AT_ELEMENT_ARRAY ) );
  157. CDmElement *layer = NULL;
  158. if ( layers.Count() == 0 )
  159. {
  160. DmElementHandle_t hElement = g_pDataModel->CreateElement( GetLogLayerType( layerType ), GetLogLayerType( layerType ), pElement->GetFileId() );
  161. layer = g_pDataModel->GetElement( hElement );
  162. layers.AddToTail( layer );
  163. }
  164. else
  165. {
  166. Assert( layers.Count() == 1 );
  167. layer = layers[ 0 ];
  168. }
  169. // Copy data
  170. switch ( layerType )
  171. {
  172. default:
  173. case AT_UNKNOWN:
  174. break;
  175. case AT_FLOAT_ARRAY:
  176. CopyValues< float >( layerType, pElement, layer, pTimes, pCurveTypes );
  177. break;
  178. case AT_INT_ARRAY:
  179. CopyValues< int >( layerType, pElement, layer, pTimes, pCurveTypes );
  180. break;
  181. case AT_BOOL_ARRAY:
  182. CopyValues< bool >( layerType, pElement, layer, pTimes, pCurveTypes );
  183. break;
  184. case AT_COLOR_ARRAY:
  185. CopyValues< Color >( layerType, pElement, layer, pTimes, pCurveTypes );
  186. break;
  187. case AT_VECTOR2_ARRAY:
  188. CopyValues< Vector2D >( layerType, pElement, layer, pTimes, pCurveTypes );
  189. break;
  190. case AT_VECTOR3_ARRAY:
  191. CopyValues< Vector >( layerType, pElement, layer, pTimes, pCurveTypes );
  192. break;
  193. case AT_VECTOR4_ARRAY:
  194. CopyValues< Vector4D >( layerType, pElement, layer, pTimes, pCurveTypes );
  195. break;
  196. case AT_QANGLE_ARRAY:
  197. CopyValues< QAngle >( layerType, pElement, layer, pTimes, pCurveTypes );
  198. break;
  199. case AT_QUATERNION_ARRAY:
  200. CopyValues< Quaternion >( layerType, pElement, layer, pTimes, pCurveTypes );
  201. break;
  202. case AT_VMATRIX_ARRAY:
  203. CopyValues< VMatrix >( layerType, pElement, layer, pTimes, pCurveTypes );
  204. break;
  205. }
  206. // Set the back pointer
  207. CDmAttribute *ownerLog = layer->AddAttribute( "ownerlog", AT_ELEMENT );
  208. Assert( ownerLog );
  209. ownerLog->SetValue( pElement->GetHandle() );
  210. // Delete the base attributes
  211. pElement->RemoveAttribute( "times" );
  212. pElement->RemoveAttribute( "values" );
  213. pElement->RemoveAttribute( "curvetypes" );
  214. }
  215. }
  216. // Fixes up all elements
  217. //-----------------------------------------------------------------------------
  218. void CImportSFMV2::BuildList( CDmElement *pElement, CUtlRBTree< CDmElement *, int >& list )
  219. {
  220. if ( !pElement )
  221. return;
  222. if ( list.Find( pElement ) != list.InvalidIndex() )
  223. return;
  224. list.Insert( pElement );
  225. // Descene to bottom of tree, then do fixup coming back up the tree
  226. for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  227. {
  228. if ( pAttribute->GetType() == AT_ELEMENT )
  229. {
  230. CDmElement *pElementAt = pAttribute->GetValueElement<CDmElement>( );
  231. BuildList( pElementAt, list );
  232. continue;
  233. }
  234. if ( pAttribute->GetType() == AT_ELEMENT_ARRAY )
  235. {
  236. CDmrElementArray<> array( pAttribute );
  237. int nCount = array.Count();
  238. for ( int i = 0; i < nCount; ++i )
  239. {
  240. CDmElement *pChild = array[ i ];
  241. BuildList( pChild, list );
  242. }
  243. continue;
  244. }
  245. }
  246. }
  247. bool CImportSFMV2::DoFixup( CDmElement *pSourceRoot )
  248. {
  249. CUtlRBTree< CDmElement *, int > fixlist( 0, 0, DefLessFunc( CDmElement * ) );
  250. BuildList( pSourceRoot, fixlist );
  251. for ( int i = fixlist.FirstInorder(); i != fixlist.InvalidIndex() ; i = fixlist.NextInorder( i ) )
  252. {
  253. // Search and replace in the entire tree!
  254. FixupElement( fixlist[ i ] );
  255. }
  256. return true;
  257. }