csgo-2018-source/game/shared/sequence_Transitioner.cpp
2021-07-24 21:11:47 -07:00

136 lines
3.6 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "sequence_Transitioner.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#include "studio.h"
// -----------------------------------------------------------------------------
// CSequenceTransitioner implementation.
// -----------------------------------------------------------------------------
void CSequenceTransitioner::CheckForSequenceChange(
CStudioHdr *hdr,
int nCurSequence,
bool bForceNewSequence,
bool bInterpolate )
{
// sequence may be set before model is initialized
if ( hdr == NULL)
return;
// FIXME?: this should detect that what's been asked to be drawn isn't what was expected
// due to not only sequence change, by frame index, rate, or whatever. When that happens,
// it should insert the previous rules.
if (m_animationQueue.Count() == 0)
{
m_animationQueue.AddToTail();
#ifdef CLIENT_DLL
m_animationQueue[0].SetOwner( NULL );
#endif
}
CAnimationLayer *currentblend = &m_animationQueue[m_animationQueue.Count()-1];
if (currentblend->m_flLayerAnimtime &&
(currentblend->GetSequence() != nCurSequence || bForceNewSequence ))
{
if ( nCurSequence < 0 || nCurSequence >= hdr->GetNumSeq() )
{
// remove all entries
m_animationQueue.RemoveAll();
}
else
{
mstudioseqdesc_t &seqdesc = hdr->pSeqdesc( nCurSequence );
// sequence changed
if ((seqdesc.flags & STUDIO_SNAP) || !bInterpolate )
{
// remove all entries
m_animationQueue.RemoveAll();
}
else
{
mstudioseqdesc_t &prevseqdesc = hdr->pSeqdesc( currentblend->GetSequence() );
currentblend->m_flLayerFadeOuttime = MIN( prevseqdesc.fadeouttime, seqdesc.fadeintime );
/*
// clip blends to time remaining
if ( !IsSequenceLooping(hdr, currentblend->GetSequence()) )
{
float length = Studio_Duration( hdr, currentblend->GetSequence(), flPoseParameter ) / currentblend->GetPlaybackRate();
float timeLeft = (1.0 - currentblend->GetCycle()) * length;
if (timeLeft < currentblend->m_flLayerFadeOuttime)
currentblend->m_flLayerFadeOuttime = timeLeft;
}
*/
}
if ( m_animationQueue.Count() > 2 )
m_animationQueue.RemoveMultipleFromHead( 1 );
}
// push previously set sequence
m_animationQueue.AddToTail();
currentblend = &m_animationQueue[m_animationQueue.Count()-1];
#ifdef CLIENT_DLL
currentblend->SetOwner( NULL );
#endif
}
currentblend->SetSequence( -1 );
currentblend->m_flLayerAnimtime = 0.0;
currentblend->m_flLayerFadeOuttime = 0.0;
}
void CSequenceTransitioner::UpdateCurrent(
CStudioHdr *hdr,
int nCurSequence,
float flCurCycle,
float flCurPlaybackRate,
float flCurTime )
{
// sequence may be set before model is initialized
if ( hdr == NULL)
return;
if (m_animationQueue.Count() == 0)
{
m_animationQueue.AddToTail();
#ifdef CLIENT_DLL
m_animationQueue[0].SetOwner( NULL );
#endif
}
CAnimationLayer *currentblend = &m_animationQueue[m_animationQueue.Count()-1];
// keep track of current sequence
currentblend->SetSequence( nCurSequence );
currentblend->m_flLayerAnimtime = flCurTime;
currentblend->SetCycle( flCurCycle );
currentblend->SetPlaybackRate( flCurPlaybackRate );
// calc blending weights for previous sequences
int i;
for (i = 0; i < m_animationQueue.Count() - 1;)
{
float s = m_animationQueue[i].GetFadeout( flCurTime );
if (s > 0)
{
m_animationQueue[i].SetWeight( s );
i++;
}
else
{
m_animationQueue.Remove( i );
}
}
}