Counter Strike : Global Offensive Source Code
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.

295 lines
8.3 KiB

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