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.
166 lines
5.4 KiB
166 lines
5.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//===========================================================================// |
|
|
|
#include "studiorendercontext.h" |
|
#include "optimize.h" |
|
#include "tier0/vprof.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
void CStudioRenderContext::GetTriangles( const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, GetTriangles_Output_t &out ) |
|
{ |
|
VPROF( "CStudioRender::GetTriangles"); |
|
|
|
out.m_MaterialBatches.RemoveAll(); // clear out data. |
|
|
|
if( !info.m_pStudioHdr || !info.m_pHardwareData || |
|
!info.m_pHardwareData->m_NumLODs || !info.m_pHardwareData->m_pLODs ) |
|
{ |
|
return; |
|
} |
|
|
|
int lod = info.m_Lod; |
|
int lastlod = info.m_pHardwareData->m_NumLODs - 1; |
|
|
|
if ( lod == USESHADOWLOD ) |
|
{ |
|
lod = lastlod; |
|
} |
|
else |
|
{ |
|
lod = clamp( lod, 0, lastlod ); |
|
} |
|
|
|
// clamp to root lod |
|
if ( lod < info.m_pHardwareData->m_RootLOD) |
|
{ |
|
lod = info.m_pHardwareData->m_RootLOD; |
|
} |
|
|
|
int nSkin = info.m_Skin; |
|
if ( nSkin >= info.m_pStudioHdr->numskinfamilies ) |
|
{ |
|
nSkin = 0; |
|
} |
|
short *pSkinRef = info.m_pStudioHdr->pSkinref( nSkin * info.m_pStudioHdr->numskinref ); |
|
|
|
studiomeshdata_t *pStudioMeshes = info.m_pHardwareData->m_pLODs[lod].m_pMeshData; |
|
IMaterial **ppMaterials = info.m_pHardwareData->m_pLODs[lod].ppMaterials; |
|
|
|
// Bone to world must be set before calling this function; it uses it here |
|
int boneMask = BONE_USED_BY_VERTEX_AT_LOD(lod); |
|
ComputePoseToWorld( out.m_PoseToWorld, info.m_pStudioHdr, boneMask, m_RC.m_ViewOrigin, pBoneToWorld ); |
|
|
|
int i; |
|
for (i=0 ; i < info.m_pStudioHdr->numbodyparts ; i++) |
|
{ |
|
mstudiomodel_t *pModel = NULL; |
|
R_StudioSetupModel( i, info.m_Body, &pModel, info.m_pStudioHdr ); |
|
|
|
// Iterate over all the meshes.... each mesh is a new material |
|
int k; |
|
for ( k = 0; k < pModel->nummeshes; ++k ) |
|
{ |
|
GetTriangles_MaterialBatch_t &materialBatch = out.m_MaterialBatches[out.m_MaterialBatches.AddToTail()]; |
|
mstudiomesh_t *pMesh = pModel->pMesh(k); |
|
|
|
if ( !pModel->CacheVertexData( info.m_pStudioHdr ) ) |
|
{ |
|
// not available yet |
|
continue; |
|
} |
|
const mstudio_meshvertexdata_t *vertData = pMesh->GetVertexData( info.m_pStudioHdr ); |
|
Assert( vertData ); // This can only return NULL on X360 for now |
|
|
|
// add the verts from this mesh to the materialBatch |
|
materialBatch.m_Verts.SetCount( pMesh->numvertices ); |
|
for ( int vertID = 0; vertID < pMesh->numvertices; vertID++ ) |
|
{ |
|
GetTriangles_Vertex_t& vert = materialBatch.m_Verts[vertID]; |
|
|
|
vert.m_Position = *vertData->Position( vertID ); |
|
vert.m_Normal = *vertData->Normal( vertID ); |
|
vert.m_TexCoord = *vertData->Texcoord( vertID ); |
|
|
|
if (vertData->HasTangentData()) |
|
{ |
|
vert.m_TangentS = *vertData->TangentS( vertID ); |
|
} |
|
#if _DEBUG |
|
else |
|
{ |
|
// ensure any unintended access faults |
|
vert.m_TangentS.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); |
|
} |
|
#endif |
|
vert.m_NumBones = vertData->BoneWeights( vertID )->numbones; |
|
int j; |
|
for ( j = 0; j < vert.m_NumBones; j++ ) |
|
{ |
|
vert.m_BoneWeight[j] = vertData->BoneWeights( vertID )->weight[j]; |
|
vert.m_BoneIndex[j] = vertData->BoneWeights( vertID )->bone[j]; |
|
} |
|
} |
|
|
|
IMaterial *pMaterial = ppMaterials[pSkinRef[pMesh->material]]; |
|
Assert( pMaterial ); |
|
materialBatch.m_pMaterial = pMaterial; |
|
studiomeshdata_t *pMeshData = &pStudioMeshes[pMesh->meshid]; |
|
if ( pMeshData->m_NumGroup == 0 ) |
|
continue; |
|
|
|
// Clear out indices |
|
materialBatch.m_TriListIndices.SetCount( 0 ); |
|
|
|
// Iterate over all stripgroups |
|
int stripGroupID; |
|
for ( stripGroupID = 0; stripGroupID < pMeshData->m_NumGroup; stripGroupID++ ) |
|
{ |
|
studiomeshgroup_t *pMeshGroup = &pMeshData->m_pMeshGroup[stripGroupID]; |
|
// bool bIsFlexed = ( pMeshGroup->m_Flags & MESHGROUP_IS_FLEXED ) != 0; |
|
// bool bIsHWSkinned = ( pMeshGroup->m_Flags & MESHGROUP_IS_HWSKINNED ) != 0; |
|
|
|
// Iterate over all strips. . . each strip potentially changes bones states. |
|
int stripID; |
|
for ( stripID = 0; stripID < pMeshGroup->m_NumStrips; stripID++ ) |
|
{ |
|
OptimizedModel::StripHeader_t *pStripData = &pMeshGroup->m_pStripData[stripID]; |
|
// int boneID; |
|
// for( boneID = 0; boneID < pStripData->numBoneStateChanges; boneID++ ) |
|
// { |
|
// OptimizedModel::BoneStateChangeHeader_t *pBoneStateChange = pStripData->pBoneStateChange( boneID ); |
|
// hardwareBoneToGlobalBone[pBoneStateChange->hardwareID] = pBoneStateChange->newBoneID; |
|
// } |
|
if ( pStripData->flags & OptimizedModel::STRIP_IS_TRILIST ) |
|
{ |
|
for ( int i = 0; i < pStripData->numIndices; i += 3 ) |
|
{ |
|
int idx = pStripData->indexOffset + i; |
|
materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx ) ); |
|
materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx + 1 ) ); |
|
materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx + 2 ) ); |
|
} |
|
} |
|
else |
|
{ |
|
Assert( pStripData->flags & OptimizedModel::STRIP_IS_TRISTRIP ); |
|
for (int i = 0; i < pStripData->numIndices - 2; ++i) |
|
{ |
|
int idx = pStripData->indexOffset + i; |
|
bool ccw = (i & 0x1) == 0; |
|
materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx ) ); |
|
materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx + 1 + ccw ) ); |
|
materialBatch.m_TriListIndices.AddToTail( pMeshGroup->MeshIndex( idx + 2 - ccw ) ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
}
|
|
|