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.

314 lines
7.4 KiB

  1. //===== Copyright � Valve Corporation, All rights reserved. ======//
  2. #include "mdlobjects/physmodelsource.h"
  3. #include "meshutils/mesh.h"
  4. #include "movieobjects/dmemodel.h"
  5. #include "dmeutils/dmmeshutils.h"
  6. #include "meshsystem/imeshsystem.h"
  7. #include "mathlib/disjoint_set_forest.h"
  8. #include "meshutils/mesh.h"
  9. #include "bone_setup.h"
  10. void CPhysModelSource::GetBoneTriangles( CUtlStringToken joint, uint nFlags, float flMinWeight, CUtlVector<Vector> &arrVertices, CUtlVector<uint> &arrIndices )const
  11. {
  12. /*
  13. if( m_pRenderModel )
  14. {
  15. ::GetBoneTriangles( m_pRenderModel, joint, nFlags, flMinWeight, arrVertices, arrIndices );
  16. }
  17. else */if( m_pDmeModel )
  18. {
  19. int nMeshBoneIndex = m_pDmeModel->GetJointIndex( joint );
  20. uint isEnumAll = nFlags & FLAG_ENUMERATE_VERTICES_ALL;
  21. int nJointCount = m_pDmeModel->GetJointCount();
  22. CVarBitVec bonesInSubtree( nJointCount );
  23. if( uint( nMeshBoneIndex ) < uint( nJointCount ) )
  24. {
  25. bonesInSubtree.Set( nMeshBoneIndex );
  26. if( nFlags & FLAG_ENUMERATE_VERTICES_WITH_SUBTREE )
  27. {
  28. ComputeSubtree( m_pDmeModel, nMeshBoneIndex, &bonesInSubtree );
  29. }
  30. }
  31. CreateDmeModelCache();
  32. for( int nMesh = 0; nMesh < m_DmeMeshCache.Count() ; ++nMesh )
  33. {
  34. CMesh *pMesh = m_DmeMeshCache[nMesh];
  35. CMesh::SkinningDataFields_t skinData = pMesh->GetSkinningDataFields();
  36. if( isEnumAll || skinData.HasSkinningData() )
  37. {
  38. CUtlVector<int> mapVerts;
  39. mapVerts.SetCount( pMesh->VertexCount() );
  40. mapVerts.FillWithValue( -1 );
  41. for( int nVertex = 0; nVertex < pMesh->VertexCount(); ++nVertex )
  42. {
  43. if( isEnumAll || pMesh->GetVertexJointSumWeight( skinData, nVertex, bonesInSubtree ) > flMinWeight )
  44. {
  45. // this vertex belongs to this joint
  46. mapVerts[nVertex] = arrVertices.AddToTail( pMesh->GetVertexPosition( nVertex ) );
  47. }
  48. }
  49. for( int nTri = 0, nTriCount = pMesh->TriangleCount(); nTri < nTriCount; ++nTri )
  50. {
  51. int v[3];
  52. for( int nTriVertIndex = 0; nTriVertIndex < 3; ++nTriVertIndex )
  53. {
  54. int nIndexInMesh = pMesh->m_pIndices[nTri * 3 + nTriVertIndex ];
  55. v[ nTriVertIndex ] = mapVerts[ nIndexInMesh ];
  56. }
  57. if( v[0] >= 0 && v[1] >= 0 && v[2] >= 0 )
  58. {
  59. // all 3 vertices of this triangle are mapped (i.e. belong to this bone)
  60. arrIndices.AddToTail( v[0] );
  61. arrIndices.AddToTail( v[1] );
  62. arrIndices.AddToTail( v[2] );
  63. }
  64. }
  65. }
  66. }
  67. }
  68. }
  69. void CPhysModelSource::CreateDmeModelCache() const
  70. {
  71. if( m_pDmeModel && m_DmeMeshCache.Count() == 0 )
  72. {
  73. CUtlVector< CDmeDag* > dags;
  74. LoadCollisionMeshes( m_DmeMeshCache, dags, m_pDmeModel, 1.0f );
  75. if( dags.Count() == m_DmeMeshCache.Count() )
  76. {
  77. m_DmeDagIndexCache.SetCount( dags.Count() );
  78. for( int i = 0; i < dags.Count(); ++i )
  79. {
  80. m_DmeDagIndexCache[i] = m_pDmeModel->GetJointIndex( dags[i] );
  81. }
  82. }
  83. }
  84. }
  85. int CPhysModelSource::GetDmeDagIndex( int nMesh )const
  86. {
  87. if( uint( nMesh ) < uint( m_DmeDagIndexCache.Count() ) )
  88. {
  89. return m_DmeDagIndexCache[ nMesh ];
  90. }
  91. return -1;
  92. }
  93. int CPhysModelSource::GetBoneCount()const
  94. {
  95. /*
  96. if( m_pRenderModel )
  97. {
  98. return m_pRenderModel->NumBones();
  99. }
  100. */
  101. if( m_pDmeModel )
  102. {
  103. return m_pDmeModel->GetJointCount();
  104. }
  105. return 0;
  106. }
  107. const char *CPhysModelSource::GetBoneNameByIndex( int nIndex )const
  108. {
  109. /*
  110. if( m_pRenderModel )
  111. {
  112. return m_pRenderModel->MasterSkeleton().GetBoneNameByIndex( nIndex );
  113. }
  114. */
  115. if( m_pDmeModel )
  116. {
  117. return m_pDmeModel->GetJoint( nIndex )->GetName();
  118. }
  119. return NULL;
  120. }
  121. AABB_t CPhysModelSource::GetBoneInfluenceBbox( CUtlStringToken joint, uint nFlags, const CTransform &bindPose, float flMinWeight )const
  122. {
  123. AABB_t bbox;
  124. bbox.MakeInvalid();
  125. EnumerateBoneVerts( joint, nFlags, [&]( const Vector &vGlobal, float w ){
  126. if( ( nFlags & FLAG_ENUMERATE_VERTICES_ALL ) || ( w >= flMinWeight ) )
  127. {
  128. Vector vLocal = bindPose.TransformVectorByInverse( vGlobal );
  129. bbox |= vLocal;
  130. }
  131. });
  132. return bbox;
  133. }
  134. bool CPhysModelSource::BoneHasMeat( CUtlStringToken joint, uint nFlags, const CTransform &bindPose )const
  135. {
  136. AABB_t bbox = GetBoneInfluenceBbox( joint, nFlags, bindPose );
  137. if( bbox.IsEmpty() )
  138. return false;
  139. Vector vDelta = bbox.m_vMaxBounds - bbox.m_vMinBounds;
  140. float flDim = vDelta.SmallestComponentValue();
  141. //float flDim = bbox.LengthOfSmallestDimension( );
  142. // don't accept too flat or degenerate geometries
  143. return flDim > 1.0f;
  144. }
  145. class CDmeModelSubtreeAdaptor
  146. {
  147. public:
  148. CDmeModelSubtreeAdaptor( const CDmeModel *pModel ) : m_pDmeModel ( pModel ){}
  149. int GetParent( int nJoint )const
  150. {
  151. CDmeDag *pParent = m_pDmeModel->GetJoint( nJoint )->GetParent();
  152. if( pParent )
  153. return m_pDmeModel->GetJointIndex( pParent );
  154. return -1;
  155. }
  156. protected:
  157. const CDmeModel *m_pDmeModel;
  158. };
  159. void ComputeSubtree( const CDmeModel *pDmeModel, int nSubtreeTipBone, CVarBitVec *pSubtree )
  160. {
  161. CDmeModelSubtreeAdaptor adaptor( pDmeModel );
  162. ComputeSubtree( &adaptor, nSubtreeTipBone, pSubtree );
  163. }
  164. int CPhysModelSource::GetParentJoint( int nJoint )const
  165. {
  166. if( m_pDmeModel )
  167. {
  168. CDmeDag *pParent = m_pDmeModel->GetJoint( nJoint )->GetParent();
  169. if( pParent )
  170. return m_pDmeModel->GetJointIndex( pParent );
  171. }
  172. /*
  173. if( m_pRenderModel )
  174. {
  175. return m_pRenderModel->MasterSkeleton().GetParent( nJoint );
  176. }
  177. */
  178. return -1;
  179. }
  180. void CPhysModelSource::GetBoneSubtree( int nBone, CVarBitVec *pSubtree ) const
  181. {
  182. /*
  183. if( m_pRenderModel )
  184. {
  185. m_pRenderModel->MasterSkeleton().GetBoneSubtree( nBone, pSubtree );
  186. }
  187. */
  188. if( m_pDmeModel )
  189. {
  190. ComputeSubtree( m_pDmeModel, nBone, pSubtree );
  191. }
  192. }
  193. CTransform CPhysModelSource::GetBindPoseParentTransform( int nJointIndex )const
  194. {
  195. CTransform tm = g_TransformIdentity;
  196. /*
  197. if( m_pRenderModel )
  198. {
  199. m_pRenderModel->MasterSkeleton().GetBindPoseParentTransform( nJointIndex, tm );
  200. }
  201. */
  202. if( m_pDmeModel )
  203. {
  204. matrix3x4_t mat;
  205. m_pDmeModel->GetJoint( nJointIndex )->GetLocalMatrix( mat );
  206. tm = MatrixTransform( mat );
  207. }
  208. return tm;
  209. }
  210. void CPhysModelSource::GetBindPoseWorldTransforms( CUtlVector< CTransform > &transforms )const
  211. {
  212. /*
  213. if( m_pRenderModel )
  214. {
  215. int nBones = m_pRenderModel->NumBones( );
  216. transforms.SetCount( nBones );
  217. m_pRenderModel->MasterSkeleton().GetBindPoseWorldTransforms( g_TransformIdentity, 1.0f, nBones, transforms.Base() );
  218. }
  219. */
  220. if( m_pDmeModel )
  221. {
  222. int nBones = m_pDmeModel->GetJointCount();
  223. transforms.SetCount( nBones );
  224. for( int i = 0; i < nBones; ++i )
  225. {
  226. matrix3x4_t mat;
  227. m_pDmeModel->GetJoint( i )->GetAbsTransform( mat );
  228. transforms[i] = MatrixTransform( mat );
  229. }
  230. }
  231. }
  232. CPhysModelSource::Stats_t CPhysModelSource::GetStats( )const
  233. {
  234. Stats_t stats;
  235. /*
  236. if( GetRenderModel() )
  237. {
  238. for( int nMesh = 0; nMesh < GetRenderModel()->GetNumMeshes(); ++nMesh )
  239. {
  240. HRenderMesh hMesh = GetRenderModel()->GetMesh( nMesh );
  241. const CUtlVector<TraceDataForDraw_t> *pDrawData;
  242. g_pMeshSystem->GetToolsGeometryInfo( hMesh, &pDrawData );
  243. const CRenderMesh *pPermMesh = ResourceHandleToData( hMesh );
  244. if( pDrawData && pPermMesh )
  245. {
  246. stats.m_nMeshCount += pDrawData->Count();
  247. for( int nDrawData = 0; nDrawData < pDrawData->Count(); ++nDrawData )
  248. {
  249. const TraceDataForDraw_t &data = pDrawData->Element( nDrawData );
  250. stats.m_nVertCount += data.m_nTraceVertices;
  251. stats.m_nTriCount += data.m_nTraceTriangles;
  252. }
  253. }
  254. }
  255. }
  256. else
  257. */
  258. {
  259. CreateDmeModelCache();
  260. stats.m_nMeshCount = m_DmeMeshCache.Count();
  261. for( int nMesh = 0; nMesh < stats.m_nMeshCount; ++nMesh )
  262. {
  263. CMesh *pMesh = m_DmeMeshCache[nMesh];
  264. stats.m_nTriCount += pMesh->TriangleCount();
  265. stats.m_nVertCount += pMesh->VertexCount();
  266. }
  267. }
  268. return stats;
  269. }