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.

213 lines
5.8 KiB

  1. //===== Copyright � Valve Corporation, All rights reserved. ======//
  2. //
  3. // This is a declaration of an abstraction of data used to generate collision mesh and potentially other physics data
  4. //
  5. #ifndef PHYS_MODEL_SOURCE_HDR
  6. #define PHYS_MODEL_SOURCE_HDR
  7. #include "mathlib/aabb.h"
  8. #include "tier1/utlvector.h"
  9. #include "tier1/utlstringtoken.h"
  10. #include "bitvec.h"
  11. #include "meshutils/mesh.h"
  12. #include "movieobjects/dmemodel.h"
  13. #include "mathlib/transform.h"
  14. class CMesh;
  15. enum VertEnumFlagEnum_t
  16. {
  17. FLAG_ENUMERATE_VERTICES_WITH_SUBTREE = 1 << 0, // enumerate vertices belonging to the given bone and its children
  18. FLAG_ENUMERATE_VERTICES_ALL = 1 << 1
  19. };
  20. void ComputeSubtree( const CDmeModel *pDmeModel, int nSubtreeTipBone, CVarBitVec *pSubtree );
  21. // this is an adaptor class so that we can use render mesh or
  22. class CPhysModelSource
  23. {
  24. class CModel; // Source2 model; not supported in Source1
  25. public:
  26. CPhysModelSource():
  27. m_pRenderModel( NULL ),
  28. m_pDmeModel( NULL )
  29. {
  30. }
  31. CPhysModelSource( const CModel *pModel ):
  32. m_pRenderModel( pModel ),
  33. m_pDmeModel( NULL )
  34. {
  35. }
  36. CPhysModelSource( CDmeModel *pModel ):
  37. m_pRenderModel( NULL ),
  38. m_pDmeModel( pModel )
  39. {
  40. }
  41. CPhysModelSource( const CPhysModelSource &source ):
  42. m_pRenderModel( source.m_pRenderModel ),
  43. m_pDmeModel( source.m_pDmeModel )
  44. {
  45. }
  46. ~CPhysModelSource()
  47. {
  48. Purge();
  49. }
  50. void SetRenderModel ( const CModel *pModel )
  51. {
  52. Purge();
  53. m_pRenderModel = pModel;
  54. }
  55. void SetDmeModel( CDmeModel *pModel )
  56. {
  57. Purge();
  58. m_pDmeModel = pModel;
  59. }
  60. const CModel *const GetRenderModel() const { return m_pRenderModel; }
  61. CDmeModel *GetDmeModel() const { return m_pDmeModel; }
  62. void Purge()
  63. {
  64. m_DmeMeshCache.PurgeAndDeleteElements();
  65. m_pDmeModel = NULL;
  66. m_pRenderModel = NULL;
  67. }
  68. bool IsValid()const
  69. {
  70. return m_pRenderModel || m_pDmeModel;
  71. }
  72. int GetBoneCount()const;
  73. const char *GetBoneNameByIndex( int nIndex )const;
  74. int FindBoneByName( const char *pName )const
  75. {
  76. for ( int i = 0; i < GetBoneCount(); ++i )
  77. {
  78. if ( !V_stricmp( GetBoneNameByIndex( i ), pName ) )
  79. return i;
  80. }
  81. return -1;
  82. }
  83. void GetBoneTriangles( CUtlStringToken joint, uint nFlags, float flMinWeight, CUtlVector<Vector> &arrVertices, CUtlVector<uint> &arrIndices )const;
  84. bool BoneHasMeat( CUtlStringToken joint, uint nFlags, const CTransform &bindPose ) const;
  85. AABB_t GetBoneInfluenceBbox( CUtlStringToken joint, uint nFlags, const CTransform &bindPose, float flMinWeight = 0.5f )const;
  86. static bool IsBitInSet( int nBit, const CVarBitVec &bonesInSubtree )
  87. {
  88. return uint( nBit ) < uint( bonesInSubtree.GetNumBits() ) && bonesInSubtree.IsBitSet( nBit );
  89. }
  90. template <typename Fn>
  91. void EnumerateBoneVerts( CUtlStringToken joint, uint nFlags, Fn functor )const
  92. {
  93. /*
  94. if( GetRenderModel() )
  95. {
  96. ::EnumerateBoneVerts( GetRenderModel(), joint, nFlags, functor );
  97. }
  98. else */if( m_pDmeModel )
  99. {
  100. CreateDmeModelCache();
  101. int nMeshBoneIndex = m_pDmeModel->GetJointIndex( joint );
  102. for( int nMesh = 0; nMesh < m_DmeMeshCache.Count(); ++nMesh )
  103. {
  104. CMesh *pMesh = m_DmeMeshCache[nMesh];
  105. CMesh::SkinningDataFields_t skinData;
  106. CVarBitVec bonesInSubtree( m_pDmeModel->GetJointCount() );
  107. if( nMeshBoneIndex >= 0 )
  108. {
  109. bonesInSubtree.Set( nMeshBoneIndex );
  110. skinData = pMesh->GetSkinningDataFields();
  111. if( nFlags & FLAG_ENUMERATE_VERTICES_WITH_SUBTREE )
  112. {
  113. ComputeSubtree( m_pDmeModel, nMeshBoneIndex, &bonesInSubtree );
  114. }
  115. }
  116. if( ( nFlags & FLAG_ENUMERATE_VERTICES_ALL ) || ( !skinData.HasSkinningData() && IsBitInSet( GetDmeDagIndex( nMesh ), bonesInSubtree ) ) )
  117. {
  118. for( int nVert = 0; nVert < pMesh->VertexCount(); ++nVert )
  119. {
  120. // this vertex belongs to this joint
  121. functor( pMesh->GetVertexPosition( nVert ), 1.0f );
  122. }
  123. }
  124. else if( skinData.HasSkinningData() )
  125. {
  126. for( int nVert = 0; nVert < pMesh->VertexCount(); ++nVert )
  127. {
  128. // this vertex belongs to this joint
  129. float flWeight = pMesh->GetVertexJointSumWeight( skinData, nVert, bonesInSubtree );
  130. functor( pMesh->GetVertexPosition( nVert ), flWeight );
  131. }
  132. }
  133. }
  134. }
  135. }
  136. struct Stats_t
  137. {
  138. int m_nVertCount;
  139. int m_nTriCount;
  140. int m_nMeshCount;
  141. Stats_t()
  142. {
  143. m_nVertCount = 0;
  144. m_nTriCount = 0;
  145. m_nMeshCount = 0;
  146. }
  147. void operator += ( const Stats_t &that )
  148. {
  149. m_nTriCount += that.m_nTriCount;
  150. m_nVertCount += that.m_nVertCount;
  151. m_nMeshCount += that.m_nMeshCount;
  152. }
  153. };
  154. Stats_t GetStats( )const;
  155. int GetParentJoint( int nJoint )const;
  156. void GetBoneSubtree( int nBone, CVarBitVec *pSubtree ) const; // this is O(N) algorithm : starting from the given bone, it finds all (grand)children of that bone and sets corresponding bits in pSubtree; pSubtree must be pre-allocated with the desired number of bones
  157. CTransform GetBindPoseParentTransform( int nJointIndex )const;
  158. void GetBindPoseWorldTransforms( CUtlVector< CTransform > &transforms )const;
  159. bool GetAnimFrame( const char *pAnimName, float flCycle, CUtlVector< CTransform > *pTransformsOut )const;
  160. int GetDmeDagIndex( int nMesh )const;
  161. protected:
  162. void CreateDmeModelCache()const;
  163. protected:
  164. const CModel *m_pRenderModel;
  165. CDmeModel *m_pDmeModel;
  166. mutable CUtlVector< CMesh* > m_DmeMeshCache;
  167. mutable CUtlVector< int > m_DmeDagIndexCache; // for each DmeMesh, this is the index of DmeDag in the Dme Model
  168. };
  169. inline void AdjustLegacyDotaOrientation( CUtlVector< CTransform > &transforms )
  170. {
  171. float sin45 = sqrtf( .5f );
  172. CTransform root( vec3_origin, Quaternion( 0, 0, sin45, sin45 ) * Quaternion( sin45, 0, 0, sin45 ) );
  173. for ( int nBone = 0; nBone < transforms.Count( ); ++nBone )
  174. {
  175. transforms[ nBone ] = ConcatTransforms( root, transforms[ nBone ] );
  176. }
  177. }
  178. //void GetBoneTriangles( const CModel *pModel, CUtlStringToken joint, uint nFlags, float flMinWeight, CUtlVector<Vector> &arrVertices, CUtlVector<uint> &arrIndices );
  179. #endif