void C_BaseAnimatingOverlay::DoAnimationEvents( CStudioHdr *pStudioHdr ) { if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() ) return; MDLCACHE_CRITICAL_SECTION(); int nSequences = pStudioHdr->GetNumSeq(); BaseClass::DoAnimationEvents( pStudioHdr ); bool watch = false; // Q_strstr( hdr->name, "rifle" ) ? true : false; CheckForLayerChanges( pStudioHdr, gpGlobals->curtime ); // !!! int j; for (j = 0; j < m_AnimOverlay.Count(); j++) { if ( m_AnimOverlay[j].m_nSequence >= nSequences ) { continue; } mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[j].m_nSequence ); if ( seqdesc.numevents == 0 ) continue; // stalled? if (m_AnimOverlay[j].m_flCycle == m_flOverlayPrevEventCycle[j]) continue; // check for looping BOOL bLooped = false; if (m_AnimOverlay[j].m_flCycle <= m_flOverlayPrevEventCycle[j]) { if (m_flOverlayPrevEventCycle[j] - m_AnimOverlay[j].m_flCycle > 0.5) { bLooped = true; } else { // things have backed up, which is bad since it'll probably result in a hitch in the animation playback // but, don't play events again for the same time slice return; } } mstudioevent_t *pevent = seqdesc.pEvent( 0 ); // This makes sure events that occur at the end of a sequence occur are // sent before events that occur at the beginning of a sequence. if (bLooped) { for (int i = 0; i < (int)seqdesc.numevents; i++) { // ignore all non-client-side events if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM ) { //TGB: added shared //if ( !( pevent[i].type & AE_TYPE_CLIENT ) ) if ( !( pevent[i].type & AE_TYPE_CLIENT|AE_TYPE_SHARED ) ) continue; } else if ( pevent[i].event < 5000 ) //Adrian - Support the old event system continue; if ( pevent[i].cycle <= m_flOverlayPrevEventCycle[j] ) continue; if ( watch ) { Msg( "%i FE %i Looped cycle %f, prev %f ev %f (time %.3f)\n", gpGlobals->tickcount, pevent[i].event, pevent[i].cycle, m_flOverlayPrevEventCycle[j], m_AnimOverlay[j].m_flCycle, gpGlobals->curtime ); } FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ); } // Necessary to get the next loop working m_flOverlayPrevEventCycle[j] = -0.01; } for (int i = 0; i < (int)seqdesc.numevents; i++) { if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM ) { //TGB: added shared //if ( !( pevent[i].type & AE_TYPE_CLIENT ) ) if ( !( pevent[i].type & AE_TYPE_CLIENT|AE_TYPE_SHARED ) ) continue; } else if ( pevent[i].event < 5000 ) //Adrian - Support the old event system continue; if ( (pevent[i].cycle > m_flOverlayPrevEventCycle[j] && pevent[i].cycle <= m_AnimOverlay[j].m_flCycle) ) { if ( watch ) { Msg( "%i (seq: %d) FE %i Normal cycle %f, prev %f ev %f (time %.3f)\n", gpGlobals->tickcount, m_AnimOverlay[j].m_nSequence, pevent[i].event, pevent[i].cycle, m_flOverlayPrevEventCycle[j], m_AnimOverlay[j].m_flCycle, gpGlobals->curtime ); } FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].event, pevent[ i ].pszOptions() ); } } m_flOverlayPrevEventCycle[j] = m_AnimOverlay[j].m_flCycle; } }
void C_BaseAnimatingOverlay::DoAnimationEvents( CStudioHdr *pStudioHdr ) { MDLCACHE_CRITICAL_SECTION(); if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() ) return; int nSequences = pStudioHdr->GetNumSeq(); BaseClass::DoAnimationEvents( pStudioHdr ); bool watch = false; // Q_strstr( hdr->name, "rifle" ) ? true : false; CheckForLayerChanges( pStudioHdr, gpGlobals->curtime ); // !!! int j; for (j = 0; j < m_AnimOverlay.Count(); j++) { if ( m_AnimOverlay[j].m_nSequence >= nSequences ) { continue; } // Don't bother with 0-weight layers if ( m_AnimOverlay[j].m_flWeight == 0.0f || m_AnimOverlay[j].m_nOrder == MAX_OVERLAYS ) { continue; } mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[j].m_nSequence ); if ( seqdesc.numevents == 0 ) continue; // stalled? if (m_AnimOverlay[j].m_flCycle == m_flOverlayPrevEventCycle[j]) continue; bool bLoopingSequence = IsSequenceLooping( m_AnimOverlay[j].m_nSequence ); bool bLooped = false; //in client code, m_flOverlayPrevEventCycle is set to -1 when we first start an overlay, looping or not if ( bLoopingSequence && m_flOverlayPrevEventCycle[j] > 0.0f && m_AnimOverlay[j].m_flCycle <= m_flOverlayPrevEventCycle[j] ) { if (m_flOverlayPrevEventCycle[j] - m_AnimOverlay[j].m_flCycle > 0.5) { bLooped = true; } else { // things have backed up, which is bad since it'll probably result in a hitch in the animation playback // but, don't play events again for the same time slice return; } } mstudioevent_t *pevent = GetEventIndexForSequence( seqdesc ); // This makes sure events that occur at the end of a sequence occur are // sent before events that occur at the beginning of a sequence. if (bLooped) { for (int i = 0; i < (int)seqdesc.numevents; i++) { // ignore all non-client-side events if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM ) { if ( !(pevent[i].type & AE_TYPE_CLIENT) ) continue; } else if ( pevent[i].Event_OldSystem() < EVENT_CLIENT ) //Adrian - Support the old event system continue; if ( pevent[i].cycle <= m_flOverlayPrevEventCycle[j] ) continue; if ( watch ) { Msg( "%i FE %i Looped cycle %f, prev %f ev %f (time %.3f)\n", gpGlobals->tickcount, pevent[i].Event(), pevent[i].cycle, (float)m_flOverlayPrevEventCycle[j], (float)m_AnimOverlay[j].m_flCycle, gpGlobals->curtime ); } FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].Event(), pevent[ i ].pszOptions() ); } // Necessary to get the next loop working m_flOverlayPrevEventCycle[j] = -0.01; } for (int i = 0; i < (int)seqdesc.numevents; i++) { if ( pevent[i].type & AE_TYPE_NEWEVENTSYSTEM ) { if ( !(pevent[i].type & AE_TYPE_CLIENT) ) continue; } else if ( pevent[i].Event_OldSystem() < EVENT_CLIENT ) //Adrian - Support the old event system continue; bool bStartedSequence = ( m_flOverlayPrevEventCycle[j] > m_AnimOverlay[j].m_flCycle || m_flOverlayPrevEventCycle[j] == 0 ); if ( ( ( pevent[i].cycle > m_flOverlayPrevEventCycle[j] || bStartedSequence && pevent[i].cycle == 0 ) && pevent[i].cycle <= m_AnimOverlay[j].m_flCycle) ) { if ( watch ) { Msg( "%i (seq: %d) FE %i Normal cycle %f, prev %f ev %f (time %.3f)\n", gpGlobals->tickcount, (int)m_AnimOverlay[j].m_nSequence, (int)pevent[i].Event(), (float)pevent[i].cycle, (float)m_flOverlayPrevEventCycle[j], (float)m_AnimOverlay[j].m_flCycle, gpGlobals->curtime ); } FireEvent( GetAbsOrigin(), GetAbsAngles(), pevent[ i ].Event(), pevent[ i ].pszOptions() ); } } m_flOverlayPrevEventCycle[j] = m_AnimOverlay[j].m_flCycle; } }
void C_BaseAnimatingOverlay::AccumulateLayers( CStudioHdr *hdr, Vector pos[], Quaternion q[], float poseparam[], float currentTime, int boneMask ) { BaseClass::AccumulateLayers( hdr, pos, q, poseparam, currentTime, boneMask ); int i; // resort the layers int layer[MAX_OVERLAYS]; for (i = 0; i < MAX_OVERLAYS; i++) { layer[i] = MAX_OVERLAYS; } for (i = 0; i < m_AnimOverlay.Count(); i++) { if (m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS) { /* Assert( layer[m_AnimOverlay[i].m_nOrder] == MAX_OVERLAYS ); layer[m_AnimOverlay[i].m_nOrder] = i; */ // hacky code until initialization of new layers is finished if (layer[m_AnimOverlay[i].m_nOrder] != MAX_OVERLAYS) { m_AnimOverlay[i].m_nOrder = MAX_OVERLAYS; } else { layer[m_AnimOverlay[i].m_nOrder] = i; } } } CheckForLayerChanges( hdr, currentTime ); int nSequences = hdr->GetNumSeq(); // add in the overlay layers int j; for (j = 0; j < MAX_OVERLAYS; j++) { i = layer[ j ]; if (i < m_AnimOverlay.Count()) { if ( m_AnimOverlay[i].m_nSequence >= nSequences ) { continue; } /* DevMsgRT( 1 , "%.3f %.3f %.3f\n", currentTime, fWeight, dadt ); debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -j - 1, 0, "%2d(%s) : %6.2f : %6.2f", m_AnimOverlay[i].m_nSequence, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence )->pszLabel(), m_AnimOverlay[i].m_flCycle, m_AnimOverlay[i].m_flWeight ); */ float fWeight = m_AnimOverlay[i].m_flWeight; if (fWeight > 0) { // check to see if the sequence changed // FIXME: move this to somewhere more reasonable // do a nice spline interpolation of the values // if ( m_AnimOverlay[i].m_nSequence != m_iv_AnimOverlay.GetPrev( i )->nSequence ) float fCycle = m_AnimOverlay[ i ].m_flCycle; fCycle = ClampCycle( fCycle, IsSequenceLooping( m_AnimOverlay[i].m_nSequence ) ); if (fWeight > 1) fWeight = 1; AccumulatePose( hdr, m_pIk, pos, q, m_AnimOverlay[i].m_nSequence, fCycle, poseparam, boneMask, fWeight, currentTime ); #if _DEBUG if (Q_stristr( hdr->pszName(), r_sequence_debug.GetString()) != NULL) { if (1) { DevMsgRT( "%6.2f : %30s : %5.3f : %4.2f : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i ); } else { int iHead, iPrev1, iPrev2; m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 ); // fake up previous cycle values. float t0; C_AnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 ); // reset previous float t1; C_AnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 ); // reset previous previous float t2; C_AnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 ); if ( pHead && pPrev1 && pPrev2 ) { DevMsgRT( "%6.2f : %30s %6.2f (%6.2f:%6.2f:%6.2f) : %6.2f (%6.2f:%6.2f:%6.2f) : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle, fWeight, (float)pPrev2->m_flWeight, (float)pPrev1->m_flWeight, (float)pHead->m_flWeight, i ); } else { DevMsgRT( "%6.2f : %30s %6.2f : %6.2f : %1d\n", currentTime, hdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i ); } } } #endif } } } }
//#define DEBUG_TF2_OVERLAYS void C_BaseAnimatingOverlay::AccumulateLayers( IBoneSetup &boneSetup, Vector pos[], Quaternion q[], float currentTime ) { BaseClass::AccumulateLayers( boneSetup, pos, q, currentTime ); int i; // resort the layers int layer[MAX_OVERLAYS]; for (i = 0; i < MAX_OVERLAYS; i++) { layer[i] = MAX_OVERLAYS; } for (i = 0; i < m_AnimOverlay.Count(); i++) { if (m_AnimOverlay[i].m_nOrder < MAX_OVERLAYS) { /* Assert( layer[m_AnimOverlay[i].m_nOrder] == MAX_OVERLAYS ); layer[m_AnimOverlay[i].m_nOrder] = i; */ // hacky code until initialization of new layers is finished if ( layer[m_AnimOverlay[i].m_nOrder] != MAX_OVERLAYS ) { m_AnimOverlay[i].SetOrder( MAX_OVERLAYS ); } else { layer[m_AnimOverlay[i].m_nOrder] = i; } } } CheckForLayerChanges( boneSetup.GetStudioHdr(), currentTime ); int nSequences = boneSetup.GetStudioHdr()->GetNumSeq(); // add in the overlay layers int j; for (j = 0; j < MAX_OVERLAYS; j++) { i = layer[ j ]; if ( i >= m_AnimOverlay.Count() ) { #if defined( DEBUG_TF2_OVERLAYS ) engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i ); #endif continue; } if ( m_AnimOverlay[i].m_nSequence >= nSequences ) continue; /* DevMsgRT( 1 , "%.3f %.3f %.3f\n", currentTime, fWeight, dadt ); debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), -j - 1, 0, "%2d(%s) : %6.2f : %6.2f", m_AnimOverlay[i].m_nSequence, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence )->pszLabel(), m_AnimOverlay[i].m_flCycle, m_AnimOverlay[i].m_flWeight ); */ float fWeight = m_AnimOverlay[i].m_flWeight; if ( fWeight <= 0.0f ) { #if defined( DEBUG_TF2_OVERLAYS ) engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", " ", 0.f, 0.f, i ); #endif continue; } // check to see if the sequence changed // FIXME: move this to somewhere more reasonable // do a nice spline interpolation of the values // if ( m_AnimOverlay[i].m_nSequence != m_iv_AnimOverlay.GetPrev( i )->nSequence ) float fCycle = m_AnimOverlay[ i ].m_flCycle; fCycle = ClampCycle( fCycle, IsSequenceLooping( m_AnimOverlay[i].m_nSequence ) ); if (fWeight > 1.0f) { fWeight = 1.0f; } boneSetup.AccumulatePose( pos, q, m_AnimOverlay[i].m_nSequence, fCycle, fWeight, currentTime, m_pIk ); #if defined( DEBUG_TF2_OVERLAYS ) engine->Con_NPrintf( 10 + j, "%30s %6.2f : %6.2f : %1d", boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i ); #endif #if 1 // _DEBUG if (r_sequence_debug.GetInt() == entindex()) { if (1) { DevMsgRT( "%8.4f : %30s : %5.3f : %4.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i ); } else { int iHead, iPrev1, iPrev2; m_iv_AnimOverlay[i].GetInterpolationInfo( currentTime, &iHead, &iPrev1, &iPrev2 ); // fake up previous cycle values. float t0; CAnimationLayer *pHead = m_iv_AnimOverlay[i].GetHistoryValue( iHead, t0 ); // reset previous float t1; CAnimationLayer *pPrev1 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev1, t1 ); // reset previous previous float t2; CAnimationLayer *pPrev2 = m_iv_AnimOverlay[i].GetHistoryValue( iPrev2, t2 ); if ( pHead && pPrev1 && pPrev2 ) { DevMsgRT( "%6.2f : %30s %6.2f (%6.2f:%6.2f:%6.2f) : %6.2f (%6.2f:%6.2f:%6.2f) : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, (float)pPrev2->m_flCycle, (float)pPrev1->m_flCycle, (float)pHead->m_flCycle, fWeight, (float)pPrev2->m_flWeight, (float)pPrev1->m_flWeight, (float)pHead->m_flWeight, i ); } else { DevMsgRT( "%6.2f : %30s %6.2f : %6.2f : %1d\n", currentTime, boneSetup.GetStudioHdr()->pSeqdesc( m_AnimOverlay[i].m_nSequence ).pszLabel(), fCycle, fWeight, i ); } } } #endif } }