📄 studio_utils.cpp
字号:
}
void StudioModel::StartBlending( void )
{
// Switch back to old sequence ( this will oscillate between this one and the last one )
SetSequence( m_prevsequence );
}
void StudioModel::SetBlendTime( float blendtime )
{
if ( blendtime > 0.0f )
{
m_blendtime = blendtime;
}
}
float StudioModel::GetTransitionAmount( void )
{
if ( g_viewerSettings.blendSequenceChanges &&
m_sequencetime < m_blendtime && m_prevsequence != m_sequence )
{
float s;
s = ( m_sequencetime / m_blendtime );
return s;
}
return 0.0f;
}
int StudioModel::LookupFlexController( char *szName )
{
if (!m_pstudiohdr)
return false;
for (int iFlex = 0; iFlex < m_pstudiohdr->numflexcontrollers; iFlex++)
{
if (stricmp( szName, m_pstudiohdr->pFlexcontroller( iFlex )->pszName() ) == 0)
{
return iFlex;
}
}
return -1;
}
void StudioModel::SetFlexController( char *szName, float flValue )
{
SetFlexController( LookupFlexController( szName ), flValue );
}
void StudioModel::SetFlexController( int iFlex, float flValue )
{
if ( !m_pstudiohdr )
return;
if (iFlex >= 0 && iFlex < m_pstudiohdr->numflexdesc)
{
mstudioflexcontroller_t *pflex = m_pstudiohdr->pFlexcontroller(iFlex);
if (pflex->min != pflex->max)
{
flValue = (flValue - pflex->min) / (pflex->max - pflex->min);
}
m_flexweight[iFlex] = clamp( flValue, 0.0f, 1.0f );
}
}
float StudioModel::GetFlexController( char *szName )
{
return GetFlexController( LookupFlexController( szName ) );
}
float StudioModel::GetFlexController( int iFlex )
{
if ( !m_pstudiohdr )
return 0.0f;
if (iFlex >= 0 && iFlex < m_pstudiohdr->numflexdesc)
{
mstudioflexcontroller_t *pflex = m_pstudiohdr->pFlexcontroller(iFlex);
float flValue = m_flexweight[iFlex];
if (pflex->min != pflex->max)
{
flValue = flValue * (pflex->max - pflex->min) + pflex->min;
}
return flValue;
}
return 0.0;
}
int StudioModel::GetNumLODs() const
{
return m_pStudioRender->GetNumLODs( m_HardwareData );
}
float StudioModel::GetLODSwitchValue( int lod ) const
{
return m_pStudioRender->GetLODSwitchValue( m_HardwareData, lod );
}
void StudioModel::SetLODSwitchValue( int lod, float switchValue )
{
m_pStudioRender->SetLODSwitchValue( m_HardwareData, lod, switchValue );
}
void StudioModel::ExtractBbox( Vector &mins, Vector &maxs )
{
if ( !m_pstudiohdr )
return;
// look for hull
if (m_pstudiohdr->hull_min.Length() != 0)
{
mins = m_pstudiohdr->hull_min;
maxs = m_pstudiohdr->hull_max;
}
// look for view clip
else if (m_pstudiohdr->view_bbmin.Length() != 0)
{
mins = m_pstudiohdr->view_bbmin;
maxs = m_pstudiohdr->view_bbmax;
}
else
{
mstudioseqdesc_t *pseqdesc = m_pstudiohdr->pSeqdesc( 0 );
mins = pseqdesc[ m_sequence ].bbmin;
maxs = pseqdesc[ m_sequence ].bbmax;
}
}
void StudioModel::GetSequenceInfo( int iSequence, float *pflFrameRate, float *pflGroundSpeed )
{
float t = GetDuration( iSequence );
if (t > 0)
{
*pflFrameRate = 1.0 / t;
*pflGroundSpeed = 0; // sqrt( pseqdesc->linearmovement[0]*pseqdesc->linearmovement[0]+ pseqdesc->linearmovement[1]*pseqdesc->linearmovement[1]+ pseqdesc->linearmovement[2]*pseqdesc->linearmovement[2] );
// *pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1);
}
else
{
*pflFrameRate = 1.0;
*pflGroundSpeed = 0.0;
}
}
void StudioModel::GetSequenceInfo( float *pflFrameRate, float *pflGroundSpeed )
{
GetSequenceInfo( m_sequence, pflFrameRate, pflGroundSpeed );
}
float StudioModel::GetFPS( int iSequence )
{
if ( !m_pstudiohdr )
return 0.0f;
return Studio_FPS( m_pstudiohdr, iSequence, m_poseparameter );
}
float StudioModel::GetFPS( void )
{
return GetFPS( m_sequence );
}
float StudioModel::GetDuration( int iSequence )
{
if ( !m_pstudiohdr )
return 0.0f;
return Studio_Duration( m_pstudiohdr, iSequence, m_poseparameter );
}
static int GetSequenceFlags( studiohdr_t *pstudiohdr, int sequence )
{
if ( !pstudiohdr ||
sequence < 0 ||
sequence >= pstudiohdr->numseq )
{
return 0;
}
mstudioseqdesc_t *pseqdesc = pstudiohdr->pSeqdesc( sequence );
return pseqdesc->flags;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : iSequence -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool StudioModel::GetSequenceLoops( int iSequence )
{
if ( !m_pstudiohdr )
return false;
int flags = GetSequenceFlags( m_pstudiohdr, iSequence );
bool looping = flags & STUDIO_LOOPING ? true : false;
return looping;
}
float StudioModel::GetDuration( )
{
return GetDuration( m_sequence );
}
void StudioModel::GetMovement( float dt, Vector &vecPos, QAngle &vecAngles )
{
float t = GetDuration( );
float flNext = m_cycle + dt / t;
GetMovement( m_cycle, flNext, vecPos, vecAngles );
return;
}
void StudioModel::GetMovement( float prevCycle, float nextCycle, Vector &vecPos, QAngle &vecAngles )
{
if ( !m_pstudiohdr )
{
vecPos.Init();
vecAngles.Init();
return;
}
// FIXME: this doesn't consider layers
Studio_SeqMovement( m_pstudiohdr, m_sequence, prevCycle, nextCycle, m_poseparameter, vecPos, vecAngles );
return;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the ground speed of the current sequence.
//-----------------------------------------------------------------------------
float StudioModel::GetGroundSpeed( void )
{
Vector vecMove;
QAngle vecAngles;
GetMovement( 0, 1, vecMove, vecAngles );
float t = GetDuration();
float flGroundSpeed = 0;
if (t > 0)
{
flGroundSpeed = vecMove.Length() / t;
}
return flGroundSpeed;
}
void StudioModel::GetSeqAnims( int iSequence, mstudioanimdesc_t *panim[4], float *weight )
{
if (!m_pstudiohdr)
return;
Studio_SeqAnims( m_pstudiohdr, iSequence, m_poseparameter, panim, weight );
}
void StudioModel::GetSeqAnims( mstudioanimdesc_t *panim[4], float *weight )
{
GetSeqAnims( m_sequence, panim, weight );
}
float StudioModel::SetController( int iController, float flValue )
{
if (!m_pstudiohdr)
return 0.0f;
return Studio_SetController( m_pstudiohdr, iController, flValue, m_controller[iController] );
}
int StudioModel::LookupPoseParameter( char const *szName )
{
if (!m_pstudiohdr)
return false;
for (int iParameter = 0; iParameter < m_pstudiohdr->numposeparameters; iParameter++)
{
if (stricmp( szName, m_pstudiohdr->pPoseParameter( iParameter )->pszName() ) == 0)
{
return iParameter;
}
}
return -1;
}
float StudioModel::SetPoseParameter( char const *szName, float flValue )
{
return SetPoseParameter( LookupPoseParameter( szName ), flValue );
}
float StudioModel::SetPoseParameter( int iParameter, float flValue )
{
if (!m_pstudiohdr)
return 0.0f;
return Studio_SetPoseParameter( m_pstudiohdr, iParameter, flValue, m_poseparameter[iParameter] );
}
float StudioModel::GetPoseParameter( char const *szName )
{
return GetPoseParameter( LookupPoseParameter( szName ) );
}
float StudioModel::GetPoseParameter( int iParameter )
{
if (!m_pstudiohdr)
return 0.0f;
return Studio_GetPoseParameter( m_pstudiohdr, iParameter, m_poseparameter[iParameter] );
}
bool StudioModel::GetPoseParameterRange( int iParameter, float *pflMin, float *pflMax )
{
*pflMin = 0;
*pflMax = 0;
if (!m_pstudiohdr)
return false;
if (iParameter >= m_pstudiohdr->numposeparameters)
return false;
mstudioposeparamdesc_t *pPose = m_pstudiohdr->pPoseParameter( iParameter );
*pflMin = pPose->start;
*pflMax = pPose->end;
return true;
}
int StudioModel::LookupAttachment( char const *szName )
{
if ( !m_pstudiohdr )
return -1;
for (int i = 0; i < m_pstudiohdr->numattachments; i++)
{
if (stricmp( m_pstudiohdr->pAttachment( i )->pszName(), szName ) == 0)
{
return i;
}
}
return -1;
}
int StudioModel::SetBodygroup( int iGroup, int iValue )
{
if (!m_pstudiohdr)
return 0;
if (iGroup > m_pstudiohdr->numbodyparts)
return -1;
mstudiobodyparts_t *pbodypart = m_pstudiohdr->pBodypart( iGroup );
int iCurrent = (m_bodynum / pbodypart->base) % pbodypart->nummodels;
if (iValue >= pbodypart->nummodels)
return iCurrent;
m_bodynum = (m_bodynum - (iCurrent * pbodypart->base) + (iValue * pbodypart->base));
return iValue;
}
int StudioModel::SetSkin( int iValue )
{
if (!m_pstudiohdr)
return 0;
if (iValue >= m_pstudiohdr->numskinfamilies)
{
return m_skinnum;
}
m_skinnum = iValue;
return iValue;
}
void StudioModel::scaleMeshes (float scale)
{
if (!m_pstudiohdr)
return;
int i, j, k;
// scale verts
int tmp = m_bodynum;
for (i = 0; i < m_pstudiohdr->numbodyparts; i++)
{
mstudiobodyparts_t *pbodypart = m_pstudiohdr->pBodypart( i );
for (j = 0; j < pbodypart->nummodels; j++)
{
SetBodygroup (i, j);
SetupModel (i);
for (k = 0; k < m_pmodel->numvertices; k++)
{
*m_pmodel->Position(k) *= scale;
}
}
}
m_bodynum = tmp;
// scale complex hitboxes
int hitboxset = g_MDLViewer->GetCurrentHitboxSet();
mstudiobbox_t *pbboxes = m_pstudiohdr->pHitbox( 0, hitboxset );
for (i = 0; i < m_pstudiohdr->iHitboxCount( hitboxset ); i++)
{
VectorScale (pbboxes[i].bbmin, scale, pbboxes[i].bbmin);
VectorScale (pbboxes[i].bbmax, scale, pbboxes[i].bbmax);
}
// scale bounding boxes
mstudioseqdesc_t *pseqdesc = m_pstudiohdr->pSeqdesc( 0 );
for (i = 0; i < m_pstudiohdr->numseq; i++)
{
VectorScale (pseqdesc[i].bbmin, scale, pseqdesc[i].bbmin);
VectorScale (pseqdesc[i].bbmax, scale, pseqdesc[i].bbmax);
}
// maybe scale exeposition, pivots, attachments
}
void StudioModel::scaleBones (float scale)
{
if (!m_pstudiohdr)
return;
mstudiobone_t *pbones = m_pstudiohdr->pBone( 0 );
for (int i = 0; i < m_pstudiohdr->numbones; i++)
{
for (int j = 0; j < 3; j++)
{
pbones[i].value[j] *= scale;
pbones[i].scale[j] *= scale;
}
}
}
int StudioModel::Physics_GetBoneCount( void )
{
return m_pPhysics->Count();
}
const char *StudioModel::Physics_GetBoneName( int index )
{
CPhysmesh *pmesh = m_pPhysics->GetMesh( index );
if ( !pmesh )
return NULL;
return pmesh->m_boneName;
}
void StudioModel::Physics_GetData( int boneIndex, hlmvsolid_t *psolid, constraint_ragdollparams_t *pConstraint ) const
{
CPhysmesh *pMesh = m_pPhysics->GetMesh( boneIndex );
if ( !pMesh )
return;
if ( psolid )
{
memcpy( psolid, &pMesh->m_solid, sizeof(*psolid) );
}
if ( pConstraint )
{
*pConstraint = pMesh->m_constraint;
}
}
void StudioModel::Physics_SetData( int boneIndex, const hlmvsolid_t *psolid, const constraint_ragdollparams_t *pConstraint )
{
CPhysmesh *pMesh = m_pPhysics->GetMesh( boneIndex );
if ( !pMesh )
return;
if ( psolid )
{
memcpy( &pMesh->m_solid, psolid, sizeof(*psolid) );
}
if ( pConstraint )
{
pMesh->m_constraint = *pConstraint;
}
}
float StudioModel::Physics_GetMass( void )
{
return m_pPhysics->GetMass();
}
void StudioModel::Physics_SetMass( float mass )
{
m_physMass = mass;
}
char *StudioModel::Physics_DumpQC( void )
{
return m_pPhysics->DumpQC();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -