214 lines
5.8 KiB
C++
214 lines
5.8 KiB
C++
//===== Copyright © Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// This is a declaration of an abstraction of data used to generate collision mesh and potentially other physics data
|
|
//
|
|
#ifndef PHYS_MODEL_SOURCE_HDR
|
|
#define PHYS_MODEL_SOURCE_HDR
|
|
|
|
#include "mathlib/aabb.h"
|
|
#include "tier1/utlvector.h"
|
|
#include "tier1/utlstringtoken.h"
|
|
#include "bitvec.h"
|
|
#include "meshutils/mesh.h"
|
|
#include "movieobjects/dmemodel.h"
|
|
#include "mathlib/transform.h"
|
|
|
|
class CMesh;
|
|
|
|
enum VertEnumFlagEnum_t
|
|
{
|
|
FLAG_ENUMERATE_VERTICES_WITH_SUBTREE = 1 << 0, // enumerate vertices belonging to the given bone and its children
|
|
FLAG_ENUMERATE_VERTICES_ALL = 1 << 1
|
|
};
|
|
|
|
void ComputeSubtree( const CDmeModel *pDmeModel, int nSubtreeTipBone, CVarBitVec *pSubtree );
|
|
|
|
// this is an adaptor class so that we can use render mesh or
|
|
class CPhysModelSource
|
|
{
|
|
class CModel; // Source2 model; not supported in Source1
|
|
public:
|
|
CPhysModelSource():
|
|
m_pRenderModel( NULL ),
|
|
m_pDmeModel( NULL )
|
|
{
|
|
|
|
}
|
|
CPhysModelSource( const CModel *pModel ):
|
|
m_pRenderModel( pModel ),
|
|
m_pDmeModel( NULL )
|
|
{
|
|
}
|
|
|
|
CPhysModelSource( CDmeModel *pModel ):
|
|
m_pRenderModel( NULL ),
|
|
m_pDmeModel( pModel )
|
|
{
|
|
}
|
|
|
|
CPhysModelSource( const CPhysModelSource &source ):
|
|
m_pRenderModel( source.m_pRenderModel ),
|
|
m_pDmeModel( source.m_pDmeModel )
|
|
{
|
|
|
|
}
|
|
|
|
~CPhysModelSource()
|
|
{
|
|
Purge();
|
|
}
|
|
|
|
void SetRenderModel ( const CModel *pModel )
|
|
{
|
|
Purge();
|
|
m_pRenderModel = pModel;
|
|
}
|
|
|
|
void SetDmeModel( CDmeModel *pModel )
|
|
{
|
|
Purge();
|
|
m_pDmeModel = pModel;
|
|
}
|
|
|
|
const CModel *const GetRenderModel() const { return m_pRenderModel; }
|
|
CDmeModel *GetDmeModel() const { return m_pDmeModel; }
|
|
|
|
void Purge()
|
|
{
|
|
m_DmeMeshCache.PurgeAndDeleteElements();
|
|
m_pDmeModel = NULL;
|
|
m_pRenderModel = NULL;
|
|
}
|
|
|
|
bool IsValid()const
|
|
{
|
|
return m_pRenderModel || m_pDmeModel;
|
|
}
|
|
|
|
int GetBoneCount()const;
|
|
const char *GetBoneNameByIndex( int nIndex )const;
|
|
|
|
int FindBoneByName( const char *pName )const
|
|
{
|
|
for ( int i = 0; i < GetBoneCount(); ++i )
|
|
{
|
|
if ( !V_stricmp( GetBoneNameByIndex( i ), pName ) )
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void GetBoneTriangles( CUtlStringToken joint, uint nFlags, float flMinWeight, CUtlVector<Vector> &arrVertices, CUtlVector<uint> &arrIndices )const;
|
|
bool BoneHasMeat( CUtlStringToken joint, uint nFlags, const CTransform &bindPose ) const;
|
|
AABB_t GetBoneInfluenceBbox( CUtlStringToken joint, uint nFlags, const CTransform &bindPose, float flMinWeight = 0.5f )const;
|
|
|
|
static bool IsBitInSet( int nBit, const CVarBitVec &bonesInSubtree )
|
|
{
|
|
return uint( nBit ) < uint( bonesInSubtree.GetNumBits() ) && bonesInSubtree.IsBitSet( nBit );
|
|
}
|
|
|
|
template <typename Fn>
|
|
void EnumerateBoneVerts( CUtlStringToken joint, uint nFlags, Fn functor )const
|
|
{
|
|
/*
|
|
if( GetRenderModel() )
|
|
{
|
|
::EnumerateBoneVerts( GetRenderModel(), joint, nFlags, functor );
|
|
}
|
|
else */if( m_pDmeModel )
|
|
{
|
|
CreateDmeModelCache();
|
|
int nMeshBoneIndex = m_pDmeModel->GetJointIndex( joint );
|
|
|
|
for( int nMesh = 0; nMesh < m_DmeMeshCache.Count(); ++nMesh )
|
|
{
|
|
CMesh *pMesh = m_DmeMeshCache[nMesh];
|
|
CMesh::SkinningDataFields_t skinData;
|
|
CVarBitVec bonesInSubtree( m_pDmeModel->GetJointCount() );
|
|
if( nMeshBoneIndex >= 0 )
|
|
{
|
|
bonesInSubtree.Set( nMeshBoneIndex );
|
|
skinData = pMesh->GetSkinningDataFields();
|
|
if( nFlags & FLAG_ENUMERATE_VERTICES_WITH_SUBTREE )
|
|
{
|
|
ComputeSubtree( m_pDmeModel, nMeshBoneIndex, &bonesInSubtree );
|
|
}
|
|
}
|
|
|
|
if( ( nFlags & FLAG_ENUMERATE_VERTICES_ALL ) || ( !skinData.HasSkinningData() && IsBitInSet( GetDmeDagIndex( nMesh ), bonesInSubtree ) ) )
|
|
{
|
|
for( int nVert = 0; nVert < pMesh->VertexCount(); ++nVert )
|
|
{
|
|
// this vertex belongs to this joint
|
|
functor( pMesh->GetVertexPosition( nVert ), 1.0f );
|
|
}
|
|
}
|
|
else if( skinData.HasSkinningData() )
|
|
{
|
|
for( int nVert = 0; nVert < pMesh->VertexCount(); ++nVert )
|
|
{
|
|
// this vertex belongs to this joint
|
|
float flWeight = pMesh->GetVertexJointSumWeight( skinData, nVert, bonesInSubtree );
|
|
functor( pMesh->GetVertexPosition( nVert ), flWeight );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct Stats_t
|
|
{
|
|
int m_nVertCount;
|
|
int m_nTriCount;
|
|
int m_nMeshCount;
|
|
|
|
Stats_t()
|
|
{
|
|
m_nVertCount = 0;
|
|
m_nTriCount = 0;
|
|
m_nMeshCount = 0;
|
|
}
|
|
|
|
void operator += ( const Stats_t &that )
|
|
{
|
|
m_nTriCount += that.m_nTriCount;
|
|
m_nVertCount += that.m_nVertCount;
|
|
m_nMeshCount += that.m_nMeshCount;
|
|
}
|
|
};
|
|
Stats_t GetStats( )const;
|
|
|
|
int GetParentJoint( int nJoint )const;
|
|
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
|
|
CTransform GetBindPoseParentTransform( int nJointIndex )const;
|
|
void GetBindPoseWorldTransforms( CUtlVector< CTransform > &transforms )const;
|
|
bool GetAnimFrame( const char *pAnimName, float flCycle, CUtlVector< CTransform > *pTransformsOut )const;
|
|
|
|
int GetDmeDagIndex( int nMesh )const;
|
|
|
|
protected:
|
|
void CreateDmeModelCache()const;
|
|
protected:
|
|
const CModel *m_pRenderModel;
|
|
CDmeModel *m_pDmeModel;
|
|
mutable CUtlVector< CMesh* > m_DmeMeshCache;
|
|
mutable CUtlVector< int > m_DmeDagIndexCache; // for each DmeMesh, this is the index of DmeDag in the Dme Model
|
|
};
|
|
|
|
|
|
inline void AdjustLegacyDotaOrientation( CUtlVector< CTransform > &transforms )
|
|
{
|
|
float sin45 = sqrtf( .5f );
|
|
CTransform root( vec3_origin, Quaternion( 0, 0, sin45, sin45 ) * Quaternion( sin45, 0, 0, sin45 ) );
|
|
for ( int nBone = 0; nBone < transforms.Count( ); ++nBone )
|
|
{
|
|
transforms[ nBone ] = ConcatTransforms( root, transforms[ nBone ] );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//void GetBoneTriangles( const CModel *pModel, CUtlStringToken joint, uint nFlags, float flMinWeight, CUtlVector<Vector> &arrVertices, CUtlVector<uint> &arrIndices );
|
|
|
|
|
|
#endif |