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.

143 lines
4.9 KiB

  1. //===== Copyright � 1996-2008, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #include "studiorendercontext.h"
  9. #include "optimize.h"
  10. #include "tier0/vprof.h"
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include "tier0/memdbgon.h"
  13. void CStudioRenderContext::GetTriangles( const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, GetTriangles_Output_t &out )
  14. {
  15. VPROF( "CStudioRender::GetTriangles");
  16. out.m_MaterialBatches.RemoveAll(); // clear out data.
  17. if( !info.m_pStudioHdr || !info.m_pHardwareData || !info.m_pHardwareData->m_NumLODs || !info.m_pHardwareData->m_pLODs )
  18. return;
  19. int lod = info.m_Lod;
  20. int lastlod = info.m_pHardwareData->m_NumLODs - 1;
  21. lod = lod == USESHADOWLOD ? lastlod : clamp( lod, 0, lastlod );
  22. // clamp to root lod
  23. if ( lod < info.m_pHardwareData->m_RootLOD )
  24. {
  25. lod = info.m_pHardwareData->m_RootLOD;
  26. }
  27. int nSkin = info.m_Skin;
  28. if ( nSkin >= info.m_pStudioHdr->numskinfamilies )
  29. {
  30. nSkin = 0;
  31. }
  32. short *pSkinRef = info.m_pStudioHdr->pSkinref( nSkin * info.m_pStudioHdr->numskinref );
  33. studiomeshdata_t *pStudioMeshes = info.m_pHardwareData->m_pLODs[lod].m_pMeshData;
  34. IMaterial **ppMaterials = info.m_pHardwareData->m_pLODs[lod].ppMaterials;
  35. // Bone to world must be set before calling this function; it uses it here
  36. int boneMask = BONE_USED_BY_VERTEX_AT_LOD(lod);
  37. ComputePoseToWorld( out.m_PoseToWorld, info.m_pStudioHdr, boneMask, m_RC.m_ViewOrigin, pBoneToWorld );
  38. int i;
  39. for ( i=0 ; i < info.m_pStudioHdr->numbodyparts ; i++ )
  40. {
  41. mstudiomodel_t *pModel = NULL;
  42. R_StudioSetupModel( i, info.m_Body, &pModel, info.m_pStudioHdr );
  43. // Iterate over all the meshes.... each mesh is a new material
  44. int k;
  45. for ( k = 0; k < pModel->nummeshes; ++k )
  46. {
  47. GetTriangles_MaterialBatch_t &materialBatch = out.m_MaterialBatches[out.m_MaterialBatches.AddToTail()];
  48. mstudiomesh_t *pMesh = pModel->pMesh(k);
  49. if ( !pModel->CacheVertexData( info.m_pStudioHdr ) )
  50. {
  51. // not available yet
  52. continue;
  53. }
  54. const mstudio_meshvertexdata_t *vertData = pMesh->GetVertexData( info.m_pStudioHdr );
  55. Assert( vertData ); // This can only return NULL on X360 for now
  56. // add the verts from this mesh to the materialBatch
  57. materialBatch.m_Verts.SetCount( pMesh->numvertices );
  58. for ( int vertID = 0; vertID < pMesh->numvertices; vertID++ )
  59. {
  60. GetTriangles_Vertex_t& vert = materialBatch.m_Verts[vertID];
  61. vert.m_Position = *vertData->Position( vertID );
  62. vert.m_Normal = *vertData->Normal( vertID );
  63. vert.m_TexCoord = *vertData->Texcoord( vertID );
  64. if (vertData->HasTangentData())
  65. {
  66. vert.m_TangentS = *vertData->TangentS( vertID );
  67. }
  68. #if _DEBUG
  69. else
  70. {
  71. // ensure any unintended access faults
  72. vert.m_TangentS.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN, VEC_T_NAN );
  73. }
  74. #endif
  75. vert.m_NumBones = vertData->BoneWeights( vertID )->numbones;
  76. int j;
  77. for ( j = 0; j < vert.m_NumBones; j++ )
  78. {
  79. vert.m_BoneWeight[j] = vertData->BoneWeights( vertID )->weight[j];
  80. vert.m_BoneIndex[j] = vertData->BoneWeights( vertID )->bone[j];
  81. }
  82. }
  83. IMaterial *pMaterial = ppMaterials[pSkinRef[pMesh->material]];
  84. Assert( pMaterial );
  85. materialBatch.m_pMaterial = pMaterial;
  86. studiomeshdata_t *pMeshData = &pStudioMeshes[pMesh->meshid];
  87. if ( pMeshData->m_NumGroup == 0 )
  88. continue;
  89. // Clear out indices
  90. materialBatch.m_TriListIndices.SetCount( 0 );
  91. // Iterate over all stripgroups
  92. int stripGroupID;
  93. for ( stripGroupID = 0; stripGroupID < pMeshData->m_NumGroup; stripGroupID++ )
  94. {
  95. studiomeshgroup_t *pMeshGroup = &pMeshData->m_pMeshGroup[stripGroupID];
  96. // bool bIsFlexed = ( pMeshGroup->m_Flags & MESHGROUP_IS_FLEXED ) != 0;
  97. // bool bIsHWSkinned = ( pMeshGroup->m_Flags & MESHGROUP_IS_HWSKINNED ) != 0;
  98. // Iterate over all strips. . . each strip potentially changes bones states.
  99. int stripID;
  100. for ( stripID = 0; stripID < pMeshGroup->m_NumStrips; stripID++ )
  101. {
  102. OptimizedModel::StripHeader_t *pStripData = &pMeshGroup->m_pStripData[stripID];
  103. // int boneID;
  104. // for( boneID = 0; boneID < pStripData->numBoneStateChanges; boneID++ )
  105. // {
  106. // OptimizedModel::BoneStateChangeHeader_t *pBoneStateChange = pStripData->pBoneStateChange( boneID );
  107. // hardwareBoneToGlobalBone[pBoneStateChange->hardwareID] = pBoneStateChange->newBoneID;
  108. // }
  109. // JasonM TODO: check for case where pStripData->flags & OptimizedModel::STRIP_IS_QUADLIST
  110. for ( int i = 0; i < pStripData->numIndices; i += 3 )
  111. {
  112. int idx = pStripData->indexOffset + i;
  113. materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx ) );
  114. materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx + 1 ) );
  115. materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx + 2 ) );
  116. }
  117. }
  118. }
  119. }
  120. }
  121. }