//----------------------------------------------------------------------------- // Does the dirty deed //----------------------------------------------------------------------------- void CBaseAnimatedTextureProxy::OnBind( void *pEntity ) { Assert ( m_AnimatedTextureVar ); if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE ) { return; } ITexture *pTexture; pTexture = m_AnimatedTextureVar->GetTextureValue(); int numFrames = pTexture->GetNumAnimationFrames(); if ( numFrames <= 0 ) { Assert( !"0 frames in material calling animated texture proxy" ); return; } // NOTE: Must not use relative time based methods here // because the bind proxy can be called many times per frame. // Prevent multiple Wrap callbacks to be sent for no wrap mode float startTime = GetAnimationStartTime(pEntity); float deltaTime = gpGlobals->curtime - startTime; float prevTime = deltaTime - gpGlobals->frametime; // Clamp.. if (deltaTime < 0.0f) deltaTime = 0.0f; if (prevTime < 0.0f) prevTime = 0.0f; float frame = m_FrameRate * deltaTime; float prevFrame = m_FrameRate * prevTime; int intFrame = ((int)frame) % numFrames; int intPrevFrame = ((int)prevFrame) % numFrames; // Report wrap situation... if (intPrevFrame > intFrame) { if (m_WrapAnimation) { AnimationWrapped( pEntity ); } else { // Only sent the wrapped message once. // when we're in non-wrapping mode if (prevFrame < numFrames) AnimationWrapped( pEntity ); intFrame = numFrames - 1; } } m_AnimatedTextureFrameNumVar->SetIntValue( intFrame ); }
void UMovieSceneAnimationSection::GetSnapTimes(TArray<float>& OutSnapTimes, bool bGetSectionBorders) const { Super::GetSnapTimes(OutSnapTimes, bGetSectionBorders); float CurrentTime = GetAnimationStartTime(); while (CurrentTime <= GetEndTime()) { if (CurrentTime >= GetStartTime()) { OutSnapTimes.Add(CurrentTime); } CurrentTime += GetAnimationDuration(); } }
//----------------------------------------------------------------------------- // Does the dirty deed //----------------------------------------------------------------------------- void CMaterialModifyAnimatedProxy::OnBind( void *pEntity ) { assert ( m_AnimatedTextureVar ); if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE ) return; ITexture *pTexture; pTexture = m_AnimatedTextureVar->GetTextureValue(); // Get the modified material vars from the entity input IClientRenderable *pRend = (IClientRenderable *)pEntity; if ( pRend ) { C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity(); if ( pBaseEntity ) { for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() ) { C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild ); if ( !pControl ) continue; if ( !pControl->HasNewAnimationCommands() ) continue; // Read the data from the modify entity materialanimcommands_t sCommands; pControl->GetAnimationCommands( &sCommands ); m_iFrameStart = sCommands.iFrameStart; m_iFrameEnd = sCommands.iFrameEnd; m_bCustomWrap = sCommands.bWrap; m_flCustomFramerate = sCommands.flFrameRate; m_bReachedEnd = false; m_flStartTime = gpGlobals->curtime; pControl->ClearAnimationCommands(); } } } // Init all the vars based on whether we're using the base material settings, // or the custom ones from the entity input. int numFrames; bool bWrapAnimation; float flFrameRate; int iLastFrame; // Do we have a custom frame section from the server? if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET ) { if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET ) { m_iFrameEnd = pTexture->GetNumAnimationFrames(); } numFrames = (m_iFrameEnd - m_iFrameStart) + 1; bWrapAnimation = m_bCustomWrap; flFrameRate = m_flCustomFramerate; iLastFrame = (m_iFrameEnd - 1); } else { numFrames = pTexture->GetNumAnimationFrames(); bWrapAnimation = m_WrapAnimation; flFrameRate = m_FrameRate; iLastFrame = (numFrames - 1); } // Have we already reached the end? If so, stay there. if ( m_bReachedEnd && !bWrapAnimation ) { m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame ); return; } // NOTE: Must not use relative time based methods here // because the bind proxy can be called many times per frame. // Prevent multiple Wrap callbacks to be sent for no wrap mode float startTime; if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET ) { startTime = m_flStartTime; } else { startTime = GetAnimationStartTime(pEntity); } float deltaTime = gpGlobals->curtime - startTime; float prevTime = deltaTime - gpGlobals->frametime; // Clamp.. if (deltaTime < 0.0f) deltaTime = 0.0f; if (prevTime < 0.0f) prevTime = 0.0f; float frame = flFrameRate * deltaTime; float prevFrame = flFrameRate * prevTime; int intFrame = ((int)frame) % numFrames; int intPrevFrame = ((int)prevFrame) % numFrames; if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET ) { intFrame += m_iFrameStart; intPrevFrame += m_iFrameStart; } // Report wrap situation... if (intPrevFrame > intFrame) { m_bReachedEnd = true; if (bWrapAnimation) { AnimationWrapped( pEntity ); } else { // Only sent the wrapped message once. // when we're in non-wrapping mode if (prevFrame < numFrames) AnimationWrapped( pEntity ); intFrame = numFrames - 1; } } m_AnimatedTextureFrameNumVar->SetIntValue( intFrame ); if ( ToolsEnabled() ) { ToolFramework_RecordMaterialParams( GetMaterial() ); } }