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.

351 lines
20 KiB

  1. //========= Copyright � Valve Corporation, All rights reserved. ============//
  2. #include "mathlib/femodeldesc.h"
  3. #include "mathlib/femodel.h"
  4. #include "tier1/heapsort.h"
  5. #include "tier1/fmtstr.h"
  6. template < typename T >
  7. inline CLockedResource< T > CloneArrayWithMarkers( CResourceStream *pStream, const T *pArray, uint nCount, const char *pName )
  8. {
  9. // create the marker for the start of the array
  10. CFmtStr beginMsg( "Begin of %s, %d byte aligned, here: <", pName, VALIGNOF( T ) );
  11. // align the marker so that it ends aligned, right before the array data
  12. int nBeginMsgLength = beginMsg.Length( );
  13. int nPreAlign = ( -int( pStream->GetTotalSize() + nBeginMsgLength ) ) & ( VALIGNOF( T ) - 1 );
  14. V_memset( pStream->AllocateBytes( nPreAlign ), '-', nPreAlign );
  15. void *pPrefixData = pStream->AllocateBytes( nBeginMsgLength );
  16. Assert( !( ( uintp( pPrefixData ) + nBeginMsgLength ) & ( VALIGNOF( T ) - 1 ) ) );
  17. V_memcpy( pPrefixData, beginMsg.Get(), nBeginMsgLength );
  18. // write out the array
  19. CLockedResource< T > result = CloneArray( pStream, pArray, nCount );
  20. // add the end marker
  21. pStream->WriteString( CFmtStr( "> End of %s, %d bytes total.", pName, nCount * sizeof( T ) ) );
  22. return result;
  23. }
  24. #if 0//def _DEBUG
  25. #define CloneArray( STREAM, ARRAY, COUNT ) CloneArrayWithMarkers( (STREAM), (ARRAY), (COUNT), #ARRAY );
  26. #endif
  27. CLockedResource< PhysFeModelDesc_t > Clone( CFeModel *pFeModel, CResourceStream *pStream )
  28. {
  29. CLockedResource< PhysFeModelDesc_t > pFx = pStream->Allocate< PhysFeModelDesc_t >( );
  30. uint nDynamicNodes = pFeModel->m_nNodeCount - pFeModel->m_nStaticNodes;
  31. pFx->m_flLocalForce = pFeModel->m_flLocalForce;
  32. pFx->m_flLocalRotation = pFeModel->m_flLocalRotation;
  33. pFx->m_nStaticNodeFlags = pFeModel->m_nStaticNodeFlags;
  34. pFx->m_nDynamicNodeFlags = pFeModel->m_nDynamicNodeFlags;
  35. pFx->m_nNodeCount = pFeModel->m_nNodeCount;
  36. pFx->m_nStaticNodes = pFeModel->m_nStaticNodes;
  37. pFx->m_nRotLockStaticNodes = pFeModel->m_nRotLockStaticNodes;
  38. pFx->m_nSimdTriCount1 = pFeModel->m_nSimdTriCount[ 1 ];
  39. pFx->m_nSimdTriCount2 = pFeModel->m_nSimdTriCount[ 2 ];
  40. pFx->m_nSimdQuadCount1 = pFeModel->m_nSimdQuadCount[ 1 ];
  41. pFx->m_nSimdQuadCount2 = pFeModel->m_nSimdQuadCount[ 2 ];
  42. pFx->m_nQuadCount1 = pFeModel->m_nQuadCount[ 1 ];
  43. pFx->m_nQuadCount2 = pFeModel->m_nQuadCount[ 2 ];
  44. pFx->m_nFitMatrixCount1 = pFeModel->m_nFitMatrixCount[ 1 ];
  45. pFx->m_nFitMatrixCount2 = pFeModel->m_nFitMatrixCount[ 2 ];
  46. pFx->m_nSimdFitMatrixCount1 = pFeModel->m_nSimdFitMatrixCount[ 1 ];
  47. pFx->m_nSimdFitMatrixCount2 = pFeModel->m_nSimdFitMatrixCount[ 2 ];
  48. pFx->m_nRopeCount = pFeModel->m_nRopeCount;
  49. pFx->m_nTreeDepth = pFeModel->m_nTreeDepth;
  50. pFx->m_flDefaultSurfaceStretch = pFeModel->m_flDefaultSurfaceStretch;
  51. pFx->m_flDefaultThreadStretch = pFeModel->m_flDefaultThreadStretch;
  52. pFx->m_flDefaultGravityScale = pFeModel->m_flDefaultGravityScale;
  53. pFx->m_flDefaultVelAirDrag = pFeModel->m_flDefaultVelAirDrag;
  54. pFx->m_flDefaultExpAirDrag = pFeModel->m_flDefaultExpAirDrag;
  55. pFx->m_flDefaultVelQuadAirDrag = pFeModel->m_flDefaultVelQuadAirDrag;
  56. pFx->m_flDefaultExpQuadAirDrag = pFeModel->m_flDefaultExpQuadAirDrag;
  57. pFx->m_flDefaultVelRodAirDrag = pFeModel->m_flDefaultVelRodAirDrag;
  58. pFx->m_flDefaultExpRodAirDrag = pFeModel->m_flDefaultExpRodAirDrag;
  59. pFx->m_flQuadVelocitySmoothRate = pFeModel->m_flQuadVelocitySmoothRate;
  60. pFx->m_flRodVelocitySmoothRate = pFeModel->m_flRodVelocitySmoothRate;
  61. pFx->m_flAddWorldCollisionRadius = pFeModel->m_flAddWorldCollisionRadius;
  62. pFx->m_nQuadVelocitySmoothIterations = pFeModel->m_nQuadVelocitySmoothIterations;
  63. pFx->m_nRodVelocitySmoothIterations = pFeModel->m_nRodVelocitySmoothIterations;
  64. pFx->m_flDefaultVolumetricSolveAmount = pFeModel->m_flDefaultVolumetricSolveAmount;
  65. pFx->m_flWindage = pFeModel->m_flWindage;
  66. pFx->m_flWindDrag = pFeModel->m_flWindDrag;
  67. pFx->m_SimdQuads = CloneArray( pStream, pFeModel->m_pSimdQuads, pFeModel->m_nSimdQuadCount[ 0 ] );
  68. pFx->m_SimdTris = CloneArray( pStream, pFeModel->m_pSimdTris, pFeModel->m_nSimdTriCount[ 0 ] );
  69. pFx->m_SimdRods = CloneArray( pStream, pFeModel->m_pSimdRods, pFeModel->m_nSimdRodCount );
  70. pFx->m_SimdNodeBases = CloneArray( pStream, pFeModel->m_pSimdNodeBases, pFeModel->m_nSimdNodeBaseCount );
  71. pFx->m_SimdFitMatrices = CloneArray( pStream, pFeModel->m_pSimdFitMatrices, pFeModel->m_nSimdFitMatrixCount[ 0 ] );
  72. pFx->m_FitMatrices = CloneArray( pStream, pFeModel->m_pFitMatrices, pFeModel->m_nFitMatrixCount[ 0 ] );
  73. pFx->m_Quads = CloneArray( pStream, pFeModel->m_pQuads, pFeModel->m_nQuadCount[ 0 ] );
  74. pFx->m_CtrlOffsets = CloneArray( pStream, pFeModel->m_pCtrlOffsets, pFeModel->m_nCtrlOffsets );
  75. pFx->m_CtrlOsOffsets = CloneArray( pStream, pFeModel->m_pCtrlOsOffsets, pFeModel->m_nCtrlOsOffsets );
  76. pFx->m_Rods = CloneArray( pStream, pFeModel->m_pRods, pFeModel->m_nRodCount );
  77. pFx->m_AxialEdges = CloneArray( pStream, pFeModel->m_pAxialEdges, pFeModel->m_nAxialEdgeCount );
  78. pFx->m_Ropes = CloneArray( pStream, pFeModel->m_pRopes, pFeModel->m_nRopeIndexCount );
  79. pFx->m_NodeBases = CloneArray( pStream, pFeModel->m_pNodeBases, pFeModel->m_nNodeBaseCount );
  80. pFx->m_SpringIntegrator = CloneArray( pStream, pFeModel->m_pSpringIntegrator, pFeModel->m_nSpringIntegratorCount );
  81. pFx->m_SimdSpringIntegrator = CloneArray( pStream, pFeModel->m_pSimdSpringIntegrator, pFeModel->m_nSimdSpringIntegratorCount );
  82. pFx->m_InitPose = CloneArray( pStream, pFeModel->m_pInitPose, pFeModel->m_nCtrlCount );
  83. pFx->m_FollowNodes = CloneArray( pStream, pFeModel->m_pFollowNodes, pFeModel->m_nFollowNodeCount );
  84. pFx->m_CollisionSpheres = CloneArray( pStream, pFeModel->m_pCollisionSpheres, pFeModel->m_nCollisionSpheres[ 0 ] );
  85. pFx->m_CollisionPlanes = CloneArray( pStream, pFeModel->m_pCollisionPlanes, pFeModel->m_nCollisionPlanes );
  86. pFx->m_NodeCollisionRadii = CloneArray( pStream, pFeModel->m_pNodeCollisionRadii, nDynamicNodes );
  87. pFx->m_LocalRotation = CloneArray( pStream, pFeModel->m_pLocalRotation, nDynamicNodes );
  88. pFx->m_LocalForce = CloneArray( pStream, pFeModel->m_pLocalForce, nDynamicNodes );
  89. pFx->m_FitWeights = CloneArray( pStream, pFeModel->m_pFitWeights, pFeModel->m_nFitWeightCount );
  90. pFx->m_nCollisionSphereInclusiveCount = pFeModel->m_nCollisionSpheres[ 1 ];
  91. pFx->m_WorldCollisionParams = CloneArray( pStream, pFeModel->m_pWorldCollisionParams, pFeModel->m_nWorldCollisionParamCount );
  92. pFx->m_TaperedCapsuleStretches = CloneArray( pStream, pFeModel->m_pTaperedCapsuleStretches, pFeModel->m_nTaperedCapsuleStretchCount );
  93. pFx->m_TaperedCapsuleRigids = CloneArray( pStream, pFeModel->m_pTaperedCapsuleRigids, pFeModel->m_nTaperedCapsuleRigidCount );
  94. pFx->m_SphereRigids = CloneArray( pStream, pFeModel->m_pSphereRigids, pFeModel->m_nSphereRigidCount );
  95. pFx->m_TreeChildren = CloneArray( pStream, pFeModel->m_pTreeChildren, nDynamicNodes - 1 );
  96. pFx->m_TreeParents = CloneArray( pStream, pFeModel->m_pTreeParents, nDynamicNodes + nDynamicNodes - 1 );
  97. pFx->m_TreeCollisionMasks = CloneArray( pStream, pFeModel->m_pTreeCollisionMasks, nDynamicNodes + nDynamicNodes - 1 );
  98. pFx->m_WorldCollisionNodes = CloneArray( pStream, pFeModel->m_pWorldCollisionNodes, pFeModel->m_nWorldCollisionNodeCount );
  99. pFx->m_FreeNodes = CloneArray( pStream, pFeModel->m_pFreeNodes, pFeModel->m_nFreeNodeCount );
  100. pFx->m_ReverseOffsets = CloneArray( pStream, pFeModel->m_pReverseOffsets, pFeModel->m_nReverseOffsetCount );
  101. if ( pFeModel->m_pLegacyStretchForce )
  102. {
  103. pFx->m_LegacyStretchForce = CloneArray( pStream, pFeModel->m_pLegacyStretchForce, pFeModel->m_nNodeCount );
  104. }
  105. if ( pFeModel->m_pNodeIntegrator )
  106. {
  107. pFx->m_NodeIntegrator = CloneArray( pStream, pFeModel->m_pNodeIntegrator, pFeModel->m_nNodeCount );
  108. }
  109. pFx->m_NodeInvMasses = CloneArray( pStream, pFeModel->m_pNodeInvMasses, pFeModel->m_nNodeCount );
  110. if ( pFeModel->m_pCtrlHash )
  111. {
  112. pFx->m_CtrlHash = CloneArray( pStream, pFeModel->m_pCtrlHash, pFeModel->m_nCtrlCount );
  113. }
  114. if ( pFeModel->m_pCtrlName )
  115. {
  116. pFx->m_CtrlName = pStream->Allocate< CResourceString >( pFeModel->m_nCtrlCount );
  117. for ( uint i = 0; i < pFeModel->m_nCtrlCount; ++i )
  118. {
  119. pFx->m_CtrlName[ i ] = pStream->WriteString( pFeModel->m_pCtrlName[ i ] );
  120. }
  121. }
  122. return pFx;
  123. }
  124. void Clone( const PhysFeModelDesc_t *pFeDesc, intp nOffsetBytes, char **pCtrlNames, CFeModel *pFeModel )
  125. {
  126. pFeModel->m_nDynamicNodeFlags = pFeDesc->m_nDynamicNodeFlags;
  127. pFeModel->m_nStaticNodeFlags = pFeDesc->m_nStaticNodeFlags;
  128. pFeModel->m_flLocalForce = pFeDesc->m_flLocalForce;
  129. pFeModel->m_flLocalRotation = pFeDesc->m_flLocalRotation;
  130. pFeModel->m_nAxialEdgeCount = pFeDesc->m_AxialEdges.Count();
  131. pFeModel->m_nCtrlCount = pFeDesc->m_CtrlHash.Count();
  132. pFeModel->m_nNodeCount = pFeDesc->m_nNodeCount;
  133. pFeModel->m_nStaticNodes = pFeDesc->m_nStaticNodes;
  134. pFeModel->m_nRotLockStaticNodes = pFeDesc->m_nRotLockStaticNodes;
  135. AssertDbg( pFeModel->m_nRotLockStaticNodes <= pFeModel->m_nStaticNodes );
  136. pFeModel->m_nTreeDepth = pFeDesc->m_nTreeDepth;
  137. // no scalar data
  138. pFeModel->m_nQuadCount[ 0 ] = 0;
  139. pFeModel->m_nQuadCount[ 1 ] = 0;
  140. pFeModel->m_nQuadCount[ 2 ] = 0;
  141. pFeModel->m_nTriCount[ 0 ] = 0;
  142. pFeModel->m_nTriCount[ 1 ] = 0;
  143. pFeModel->m_nTriCount[ 2 ] = 0;
  144. pFeModel->m_nSimdQuadCount[ 0 ] = pFeDesc->m_SimdQuads.Count();
  145. pFeModel->m_nSimdQuadCount[ 1 ] = pFeDesc->m_nSimdQuadCount1;
  146. pFeModel->m_nSimdQuadCount[ 2 ] = pFeDesc->m_nSimdQuadCount2;
  147. pFeModel->m_nSimdTriCount[ 0 ] = pFeDesc->m_SimdTris.Count();
  148. pFeModel->m_nSimdTriCount[ 1 ] = pFeDesc->m_nSimdTriCount1;
  149. pFeModel->m_nSimdTriCount[ 2 ] = pFeDesc->m_nSimdTriCount2;
  150. pFeModel->m_nQuadCount[ 0 ] = pFeDesc->m_Quads.Count();
  151. pFeModel->m_nQuadCount[ 1 ] = pFeDesc->m_nQuadCount1;
  152. pFeModel->m_nQuadCount[ 2 ] = pFeDesc->m_nQuadCount2;
  153. pFeModel->m_nFitMatrixCount[ 0 ] = pFeDesc->m_FitMatrices.Count();
  154. pFeModel->m_nFitMatrixCount[ 1 ] = pFeDesc->m_nFitMatrixCount1;
  155. pFeModel->m_nFitMatrixCount[ 2 ] = pFeDesc->m_nFitMatrixCount2;
  156. pFeModel->m_nSimdFitMatrixCount[ 0 ] = pFeDesc->m_SimdFitMatrices.Count();
  157. pFeModel->m_nSimdFitMatrixCount[ 1 ] = pFeDesc->m_nSimdFitMatrixCount1;
  158. pFeModel->m_nSimdFitMatrixCount[ 2 ] = pFeDesc->m_nSimdFitMatrixCount2;
  159. pFeModel->m_flDefaultSurfaceStretch = pFeDesc->m_flDefaultSurfaceStretch;
  160. pFeModel->m_flDefaultThreadStretch = pFeDesc->m_flDefaultThreadStretch;
  161. pFeModel->m_flDefaultGravityScale = pFeDesc->m_flDefaultGravityScale;
  162. pFeModel->m_flDefaultVelAirDrag = pFeDesc->m_flDefaultVelAirDrag;
  163. pFeModel->m_flDefaultExpAirDrag = pFeDesc->m_flDefaultExpAirDrag;
  164. pFeModel->m_flDefaultVelQuadAirDrag = pFeDesc->m_flDefaultVelQuadAirDrag;
  165. pFeModel->m_flDefaultExpQuadAirDrag = pFeDesc->m_flDefaultExpQuadAirDrag;
  166. pFeModel->m_flDefaultVelRodAirDrag = pFeDesc->m_flDefaultVelRodAirDrag;
  167. pFeModel->m_flDefaultExpRodAirDrag = pFeDesc->m_flDefaultExpRodAirDrag;
  168. pFeModel->m_flQuadVelocitySmoothRate = pFeDesc->m_flQuadVelocitySmoothRate;
  169. pFeModel->m_flRodVelocitySmoothRate = pFeDesc->m_flRodVelocitySmoothRate;
  170. pFeModel->m_nQuadVelocitySmoothIterations = pFeDesc->m_nQuadVelocitySmoothIterations;
  171. pFeModel->m_nRodVelocitySmoothIterations = pFeDesc->m_nRodVelocitySmoothIterations;
  172. pFeModel->m_flAddWorldCollisionRadius = pFeDesc->m_flAddWorldCollisionRadius;
  173. pFeModel->m_flDefaultVolumetricSolveAmount = pFeDesc->m_flDefaultVolumetricSolveAmount;
  174. pFeModel->m_nFitWeightCount = pFeDesc->m_FitWeights.Count();
  175. pFeModel->m_nReverseOffsetCount = pFeDesc->m_ReverseOffsets.Count();
  176. pFeModel->m_flWindage = pFeDesc->m_flWindage;
  177. pFeModel->m_flWindDrag = pFeDesc->m_flWindDrag;
  178. pFeModel->m_nRodCount = pFeDesc->m_Rods.Count();
  179. pFeModel->m_nSimdRodCount = pFeDesc->m_SimdRods.Count();
  180. pFeModel->m_nFollowNodeCount = pFeDesc->m_FollowNodes.Count();
  181. pFeModel->m_nCtrlOffsets = pFeDesc->m_CtrlOffsets.Count();
  182. pFeModel->m_nCtrlOsOffsets = pFeDesc->m_CtrlOsOffsets.Count();
  183. pFeModel->m_nSpringIntegratorCount = pFeDesc->m_SpringIntegrator.Count();
  184. pFeModel->m_nSimdSpringIntegratorCount = pFeDesc->m_SimdSpringIntegrator.Count();
  185. pFeModel->m_nWorldCollisionParamCount = pFeDesc->m_WorldCollisionParams.Count();
  186. pFeModel->m_nWorldCollisionNodeCount = pFeDesc->m_WorldCollisionNodes.Count();
  187. pFeModel->m_nFreeNodeCount = pFeDesc->m_FreeNodes.Count();
  188. pFeModel->m_nTaperedCapsuleStretchCount = pFeDesc->m_TaperedCapsuleStretches.Count();
  189. pFeModel->m_nTaperedCapsuleRigidCount = pFeDesc->m_TaperedCapsuleRigids.Count();
  190. pFeModel->m_nSphereRigidCount = pFeDesc->m_SphereRigids.Count();
  191. pFeModel->m_pSimdQuads = ConstCastOffsetPointer( pFeDesc->m_SimdQuads.Base(), nOffsetBytes );
  192. pFeModel->m_pQuads = ConstCastOffsetPointer( pFeDesc->m_Quads.Base(), nOffsetBytes );
  193. pFeModel->m_pSimdTris = ConstCastOffsetPointer( pFeDesc->m_SimdTris.Base(), nOffsetBytes );
  194. pFeModel->m_pTris = NULL;
  195. pFeModel->m_pRods = ConstCastOffsetPointer( pFeDesc->m_Rods.Base(), nOffsetBytes );;
  196. pFeModel->m_pSimdRods = ConstCastOffsetPointer( pFeDesc->m_SimdRods.Base(), nOffsetBytes );
  197. pFeModel->m_pAxialEdges = ConstCastOffsetPointer( pFeDesc->m_AxialEdges.Base(), nOffsetBytes );
  198. pFeModel->m_pNodeToCtrl = NULL;
  199. pFeModel->m_pCtrlToNode = NULL;
  200. pFeModel->m_pCtrlHash = ConstCastOffsetPointer( pFeDesc->m_CtrlHash.Base(), nOffsetBytes );
  201. pFeModel->m_pRopes = ConstCastOffsetPointer( pFeDesc->m_Ropes.Base(), nOffsetBytes );
  202. pFeModel->m_pNodeBases = ConstCastOffsetPointer( pFeDesc->m_NodeBases.Base(), nOffsetBytes );
  203. pFeModel->m_pSimdNodeBases = ConstCastOffsetPointer( pFeDesc->m_SimdNodeBases.Base(), nOffsetBytes );
  204. pFeModel->m_pNodeIntegrator = ConstCastOffsetPointer( pFeDesc->m_NodeIntegrator.Base(), nOffsetBytes );
  205. pFeModel->m_pSpringIntegrator = ConstCastOffsetPointer( pFeDesc->m_SpringIntegrator.Base(), nOffsetBytes );
  206. pFeModel->m_pSimdSpringIntegrator = ConstCastOffsetPointer( pFeDesc->m_SimdSpringIntegrator.Base(), nOffsetBytes );
  207. pFeModel->m_pCtrlOffsets = ConstCastOffsetPointer( pFeDesc->m_CtrlOffsets.Base(), nOffsetBytes );
  208. pFeModel->m_pCtrlOsOffsets = ConstCastOffsetPointer( pFeDesc->m_CtrlOsOffsets.Base(), nOffsetBytes );
  209. pFeModel->m_pFollowNodes = ConstCastOffsetPointer( pFeDesc->m_FollowNodes.Base(), nOffsetBytes );
  210. pFeModel->m_pNodeCollisionRadii = ConstCastOffsetPointer( pFeDesc->m_NodeCollisionRadii.Base(), nOffsetBytes );
  211. pFeModel->m_pLocalRotation = ConstCastOffsetPointer( pFeDesc->m_LocalRotation.Base(), nOffsetBytes );
  212. pFeModel->m_pLocalForce = ConstCastOffsetPointer( pFeDesc->m_LocalForce.Base(), nOffsetBytes );
  213. pFeModel->m_pCollisionSpheres = ConstCastOffsetPointer( pFeDesc->m_CollisionSpheres.Base(), nOffsetBytes );
  214. pFeModel->m_pCollisionPlanes = ConstCastOffsetPointer( pFeDesc->m_CollisionPlanes.Base(), nOffsetBytes );
  215. pFeModel->m_pWorldCollisionNodes = ConstCastOffsetPointer( pFeDesc->m_WorldCollisionNodes.Base(), nOffsetBytes );
  216. pFeModel->m_pWorldCollisionParams = ConstCastOffsetPointer( pFeDesc->m_WorldCollisionParams.Base(), nOffsetBytes );
  217. pFeModel->m_pLegacyStretchForce = ConstCastOffsetPointer( pFeDesc->m_LegacyStretchForce.Base(), nOffsetBytes );
  218. pFeModel->m_pTaperedCapsuleStretches = ConstCastOffsetPointer( pFeDesc->m_TaperedCapsuleStretches.Base(), nOffsetBytes );
  219. pFeModel->m_pTaperedCapsuleRigids = ConstCastOffsetPointer( pFeDesc->m_TaperedCapsuleRigids.Base(), nOffsetBytes );
  220. pFeModel->m_pSphereRigids = ConstCastOffsetPointer( pFeDesc->m_SphereRigids.Base(), nOffsetBytes );
  221. pFeModel->m_pFreeNodes = ConstCastOffsetPointer( pFeDesc->m_FreeNodes.Base(), nOffsetBytes );
  222. pFeModel->m_pFitMatrices = ConstCastOffsetPointer( pFeDesc->m_FitMatrices.Base(), nOffsetBytes );
  223. pFeModel->m_pSimdFitMatrices = ConstCastOffsetPointer( pFeDesc->m_SimdFitMatrices.Base(), nOffsetBytes );
  224. pFeModel->m_pFitWeights = ConstCastOffsetPointer( pFeDesc->m_FitWeights.Base(), nOffsetBytes );
  225. pFeModel->m_pReverseOffsets = ConstCastOffsetPointer( pFeDesc->m_ReverseOffsets.Base(), nOffsetBytes );
  226. AssertDbg( pFeModel->m_pWorldCollisionParams ? pFeModel->m_pWorldCollisionParams[ pFeModel->m_nWorldCollisionParamCount - 1 ].nListEnd == pFeModel->m_nWorldCollisionNodeCount : !pFeModel->m_pWorldCollisionNodes && !pFeModel->m_nWorldCollisionParamCount && !pFeModel->m_nWorldCollisionNodeCount );
  227. pFeModel->m_nRopeCount = pFeDesc->m_nRopeCount;
  228. pFeModel->m_nRopeIndexCount = pFeDesc->m_Ropes.Count();
  229. pFeModel->m_nNodeBaseCount = pFeDesc->m_NodeBases.Count();
  230. pFeModel->m_nSimdNodeBaseCount = pFeDesc->m_SimdNodeBases.Count();
  231. pFeModel->m_nCollisionSpheres[ 0 ] = pFeDesc->m_CollisionSpheres.Count();
  232. pFeModel->m_nCollisionSpheres[ 1 ] = pFeDesc->m_nCollisionSphereInclusiveCount;
  233. pFeModel->m_nCollisionPlanes = pFeDesc->m_CollisionPlanes.Count();
  234. Assert( pFeDesc->m_TreeChildren.Count() == 0 || pFeDesc->m_TreeChildren.Count() == ( int )pFeDesc->GetDynamicNodeCount() - 1 );
  235. pFeModel->m_pTreeChildren = ConstCastOffsetPointer( pFeDesc->m_TreeChildren.Base(), nOffsetBytes );
  236. Assert( pFeDesc->m_TreeParents.Count() == 0 || pFeDesc->m_TreeParents.Count() == 2 * ( int )pFeDesc->GetDynamicNodeCount() - 1 );
  237. pFeModel->m_pTreeParents = ConstCastOffsetPointer( pFeDesc->m_TreeParents.Base(), nOffsetBytes );
  238. Assert( pFeDesc->m_TreeParents.Count() == pFeDesc->m_TreeCollisionMasks.Count() );
  239. pFeModel->m_pTreeCollisionMasks = ConstCastOffsetPointer( pFeDesc->m_TreeCollisionMasks.Base(), nOffsetBytes );
  240. Assert( pFeDesc->m_NodeInvMasses.Count() == 0 || pFeDesc->m_NodeInvMasses.Count() == pFeDesc->m_nNodeCount );
  241. pFeModel->m_pNodeInvMasses = pFeDesc->m_NodeInvMasses.Count() ? ConstCastOffsetPointer( pFeDesc->m_NodeInvMasses.Base(), nOffsetBytes ) : NULL;
  242. if ( pFeDesc->m_CtrlName.IsEmpty() || !pCtrlNames )
  243. {
  244. pFeModel->m_pCtrlName = NULL;
  245. }
  246. else
  247. {
  248. pFeModel->m_pCtrlName = const_cast< const char ** >( pCtrlNames ); //ConstCastOffsetPointer( pFeDesc->m_CtrlName.Base( ), nOffsetBytes );
  249. for ( int i = 0; i < pFeModel->m_nCtrlCount; ++i )
  250. {
  251. const CResourceString &name = pFeDesc->m_CtrlName[ i ];
  252. if ( name.IsNull() )
  253. {
  254. pFeModel->m_pCtrlName[ i ] = "";
  255. }
  256. else
  257. {
  258. pFeModel->m_pCtrlName[ i ] = ConstCastOffsetPointer( name.GetPtr(), nOffsetBytes );
  259. }
  260. }
  261. }
  262. AssertDbg( pFeDesc->m_InitPose.Count() == pFeModel->m_nCtrlCount );
  263. pFeModel->m_pInitPose = ConstCastOffsetPointer( pFeDesc->m_InitPose.Base(), nOffsetBytes );
  264. }
  265. void SetIdentityPerm( CUtlVector< uint > &perm, uint nCount )
  266. {
  267. perm.SetCount( nCount );
  268. for ( uint i = 0; i < nCount; ++i )
  269. perm[ i ] = i;
  270. }
  271. struct CtrlHashFunctor_t
  272. {
  273. const CFeModel *m_pFeModel;
  274. CtrlHashFunctor_t( const CFeModel *pFeModel ) : m_pFeModel( pFeModel ){}
  275. bool operator( )( int nLeft, int nRight ) const
  276. {
  277. return m_pFeModel->m_pCtrlHash[ nLeft ] < m_pFeModel->m_pCtrlHash[ nRight ];
  278. }
  279. };
  280. CFeModelReplaceContext::CFeModelReplaceContext( const CFeModel *pOld, const CFeModel *pNew )
  281. {
  282. m_pOld = pOld;
  283. m_pNew = pNew;
  284. m_OldToNewNode.SetCount( pOld->m_nNodeCount ); m_OldToNewNode.FillWithValue( -1 );
  285. m_OldToNewCtrl.SetCount( pOld->m_nCtrlCount ); m_OldToNewCtrl.FillWithValue( -1 );
  286. m_NewToOldNode.SetCount( pNew->m_nNodeCount ); m_NewToOldNode.FillWithValue( -1 );
  287. m_NewToOldCtrl.SetCount( pNew->m_nCtrlCount ); m_NewToOldCtrl.FillWithValue( -1 );
  288. CUtlVector< uint > oldCtrlIndex, newCtrlIndex;
  289. SetIdentityPerm( oldCtrlIndex, pOld->m_nCtrlCount );
  290. SetIdentityPerm( newCtrlIndex, pNew->m_nCtrlCount );
  291. HeapSort( oldCtrlIndex, CtrlHashFunctor_t( pOld ) );
  292. HeapSort( newCtrlIndex, CtrlHashFunctor_t( pNew ) );
  293. for ( uint nOld = 0, nNew = 0; nOld < pOld->m_nCtrlCount && nNew < pNew->m_nCtrlCount; )
  294. {
  295. uint nOldCtrl = oldCtrlIndex[ nOld ], nNewCtrl = newCtrlIndex[ nNew ];
  296. uint nOldCtrlHash = pOld->m_pCtrlHash[ nOldCtrl ], nNewCtrlHash = pNew->m_pCtrlHash[ nNewCtrl ];
  297. if ( nOldCtrlHash == nNewCtrlHash )
  298. {
  299. // we found a match!
  300. m_OldToNewCtrl[ nOldCtrl ] = nNewCtrl;
  301. m_NewToOldCtrl[ nNewCtrl ] = nOldCtrl;
  302. uint nOldNode = pOld->CtrlToNode( nOldCtrl );
  303. uint nNewNode = pNew->CtrlToNode( nNewCtrl );
  304. if ( nOldNode < pOld->m_nNodeCount && nNewNode < pNew->m_nNodeCount )
  305. {
  306. // there's a match in nodes
  307. m_NewToOldNode[ nNewNode ] = nOldNode;
  308. m_OldToNewNode[ nOldNode ] = nNewNode;
  309. }
  310. nOld++;
  311. nNew++;
  312. }
  313. else if ( nOldCtrlHash < nNewCtrlHash )
  314. {
  315. AssertDbg( m_OldToNewCtrl[ nOldCtrl ] == -1 );
  316. nOld++;
  317. }
  318. else
  319. {
  320. AssertDbg( m_NewToOldCtrl[ nNewCtrl ] == -1 );
  321. nNew++;
  322. }
  323. }
  324. }