18 if ( it->GetNamedAnimation()->GetName() == a_strAnimationName )
30 ANamedAnimationTransition* pTransition = it->GetNamedAnimation()->GetTransitionSet().FindTransition( a_strAnimationName );
35 a_rpTransition = pTransition;
45 : m_pSkeletonInstance(
TNULL )
55 DestroyAnimReferences();
62 m_fTime += a_fDeltaTime;
64 UpdateAnimations( m_llAnimRefs, a_fDeltaTime, a_rEventList );
65 UpdateAnimations( m_llOverlayAnimRefs, a_fDeltaTime, a_rEventList );
67 if ( fOldTime == 0.0f || m_fTime == 0.0f )
94 if ( strAnimationName == strPlayingName )
113 if ( m_llAnimRefs.IsEmpty() || m_llAnimRefs.Begin() ==
TNULL )
117 if ( a_bStartNewAnimation )
122 TBOOL bHasTransition = GetAnimationTransition( m_llAnimRefs, a_strName, pAnimRef, pTransition );
124 if ( bHasTransition )
135 pAnimRef = m_llAnimRefs.Head();
139 m_oAnimTransition.SetManaged( !pCurrentAnimation->
IsFinishManual() );
142 m_oAnimTransition.SetAnimationName( pNamedAnimation->
GetName() );
162 if ( pDestTransition ) fBlendOutTime = pDestTransition->
GetBlendOutTime();
164 TAnimation* pAnimation = m_pSkeletonInstance->AddAnimation( a_pNamedAnimation->
GetSequenceId(), a_fWeight, fBlendInTime );
170 if ( !a_pNamedAnimation->
IsLooped() )
173 a_rAnimationRef.m_pNamedAnimation = a_pNamedAnimation;
174 a_rAnimationRef.m_pTransition =
TNULL;
175 a_rAnimationRef.m_bWasEverUpdated =
TFALSE;
176 a_rAnimationRef.m_iBreakpointIndex = 0;
177 a_rAnimationRef.m_fWeight = a_fWeight;
183void AToshiAnimationInterface::UpdateAnimations( Toshi::T2DList<AToshiAnimationRef>& a_rList,
TFLOAT a_fDeltaTime, AnimEventList& a_rEventList )
185 auto it = a_rList.Begin();
192 if ( it == a_rList.End() )
return;
194 TAnimation* pAnimation = ( !it->GetNamedAnimation() ) ?
TNULL : m_pSkeletonInstance->GetAnimation( it->GetNamedAnimation()->GetSequenceId() );
195 UpdateAnimation( a_fDeltaTime, *it, pAnimation, a_rEventList );
208 AToshiAnimationRef* pAnimRef = it;
213 AnimEvent& animEvent = a_rEventList.Push();
217 if ( pNamedAnimation )
219 ANamedAnimationTransition* pTransition = pAnimRef->
GetTransition();
227 ANamedAnimation* pTransitionAnimation = m_pAnimationSet->GetNamedAnimation( pTransition->
GetAnimationName() );
234 TAnimation* pAnimation = PlayAnimImpl( pTransitionAnimation, pAnimRef->m_fWeight, pTransition, *pAnimRef );
236 a_rList.PushBack( pAnimRef );
242 it = a_rList.Erase( it );
248void AToshiAnimationInterface::UpdateAnimation(
TFLOAT a_fDeltaTime,
AToshiAnimationRef& a_rAnimRef, Toshi::TAnimation* a_pAnimation, AnimEventList& a_rEventList )
253 if ( !a_rAnimRef.m_bWasEverUpdated )
257 AnimEvent& animEvent = a_rEventList.Push();
260 a_rAnimRef.m_bWasEverUpdated =
TTRUE;
264 if ( a_pAnimation && a_pAnimation->GetSpeed() == 0.0f )
268 TBOOL bIsReverse = ( a_pAnimation !=
TNULL && a_pAnimation->GetSpeed() < 0.0f );
273 UpdateAnimationBreakpoints( a_rAnimRef, a_pAnimation, a_rEventList );
278 UpdateAnimationBreakpointsReverse( a_rAnimRef, a_pAnimation, a_rEventList );
282void AToshiAnimationInterface::UpdateAnimationBreakpoints(
AToshiAnimationRef& a_rAnimRef, Toshi::TAnimation* a_pAnimation, AnimEventList& a_rEventList )
287 TINT iCurrentBreakpoint = a_rAnimRef.m_iBreakpointIndex;
289 TAnimation* pAnimation = m_pSkeletonInstance->GetAnimation( pNamedAnimation->
GetSequenceId() );
292 if ( pAnimation && pAnimation->
IsManaged() && a_rAnimRef.m_iBreakpointIndex >= iNumBreakpoints )
293 a_rAnimRef.m_iBreakpointIndex = 0;
295 TFLOAT fCurrentAnimTime = ( !a_pAnimation ) ? pNamedAnimation->
GetDuration() : a_pAnimation->GetSeqTime();
296 TFLOAT fPreviousAnimTime = a_rAnimRef.m_fTime;
298 if ( iCurrentBreakpoint < iNumBreakpoints || ( pAnimation && pAnimation->
IsManaged() ) )
300 TFLOAT fAnimDeltaTime = fCurrentAnimTime - fPreviousAnimTime;
303 if ( fAnimDeltaTime < 0.0f )
306 for (
TINT i = 0; iCurrentBreakpoint < iNumBreakpoints && i < iNumBreakpoints && ( !pAnimation || pAnimation->
IsManaged() ); i++ )
308 AAnimationBreakpoint* pBreakpoint = pNamedAnimation->
GetBreakpoints()[ iCurrentBreakpoint ];
309 TFLOAT fTimeToBreakpoint = fCurrentAnimTime - pBreakpoint->
GetTime();
311 if ( a_pAnimation && fTimeToBreakpoint < 0.0f )
314 if ( !pAnimation || !pAnimation->
IsManaged() || fCurrentAnimTime >= fPreviousAnimTime || fPreviousAnimTime >= pBreakpoint->
GetTime() )
318 fTimeToBreakpoint += pNamedAnimation->
GetDuration();
322 if ( fAnimDeltaTime < fTimeToBreakpoint )
326 AnimEvent& animEvent = a_rEventList.Push();
329 iCurrentBreakpoint++;
330 if ( iCurrentBreakpoint >= iNumBreakpoints )
332 iCurrentBreakpoint = 0;
334 if ( fPreviousAnimTime < fCurrentAnimTime )
339 a_rAnimRef.m_iBreakpointIndex = iCurrentBreakpoint;
342 a_rAnimRef.m_fTime = fCurrentAnimTime;
345void AToshiAnimationInterface::UpdateAnimationBreakpointsReverse(
AToshiAnimationRef& a_rAnimRef, Toshi::TAnimation* a_pAnimation, AnimEventList& a_rEventList )
350 TINT iCurrentBreakpoint = a_rAnimRef.m_iBreakpointIndex;
352 TAnimation* pAnimation = m_pSkeletonInstance->GetAnimation( pNamedAnimation->
GetSequenceId() );
355 if ( pAnimation && pAnimation->
IsManaged() && a_rAnimRef.m_iBreakpointIndex < 0 )
356 a_rAnimRef.m_iBreakpointIndex = iNumBreakpoints - 1;
358 TFLOAT fCurrentAnimTime = ( !a_pAnimation ) ? 0.0f : a_pAnimation->GetSeqTime();
359 TFLOAT fPreviousAnimTime = a_rAnimRef.m_fTime;
361 if ( iCurrentBreakpoint > 0 || ( pAnimation && pAnimation->
IsManaged() ) )
363 TFLOAT fAnimDeltaTime = fPreviousAnimTime - fCurrentAnimTime;
364 TINT iPrevBreakpoint = iCurrentBreakpoint - 1;
367 if ( fAnimDeltaTime < 0.0f )
368 fAnimDeltaTime += pNamedAnimation->GetDuration();
370 TINT iBreakpoint = iPrevBreakpoint;
371 if ( pAnimation && pAnimation->IsManaged() && iPrevBreakpoint <= -1 )
373 iPrevBreakpoint = iNumBreakpoints - 1;
374 iBreakpoint = iPrevBreakpoint;
377 for (
TINT i = 0; i < iNumBreakpoints && iPrevBreakpoint > -1 || ( pAnimation && pAnimation->
IsManaged() ); i++ )
379 iPrevBreakpoint = iCurrentBreakpoint;
381 AAnimationBreakpoint* pBreakpoint = pNamedAnimation->
GetBreakpoints()[ iBreakpoint ];
382 TFLOAT fTimeToBreakpoint = pBreakpoint->
GetTime() - fCurrentAnimTime;
384 if ( pAnimation && fTimeToBreakpoint < 0.0f )
387 if ( !pAnimation || !pAnimation->
IsManaged() || fCurrentAnimTime <= fPreviousAnimTime || fPreviousAnimTime <= pBreakpoint->GetTime() )
391 fTimeToBreakpoint += pNamedAnimation->
GetDuration();
395 if ( fAnimDeltaTime < fTimeToBreakpoint )
399 AnimEvent& animEvent = a_rEventList.Push();
402 iCurrentBreakpoint--;
404 if ( pAnimation && pAnimation->
IsManaged() )
406 if ( iCurrentBreakpoint < 0 )
407 iCurrentBreakpoint = iNumBreakpoints - 1;
409 if ( iPrevBreakpoint == iNumBreakpoints - 1 && fCurrentAnimTime < fPreviousAnimTime )
414 a_rAnimRef.m_iBreakpointIndex = iCurrentBreakpoint;
417 a_rAnimRef.m_fTime = fCurrentAnimTime;
421TBOOL AToshiAnimationInterface::IsAllStatic()
428 if ( it->GetNamedAnimation() && !it->GetNamedAnimation()->IsStatic() )
434 if ( it->GetNamedAnimation() && !it->GetNamedAnimation()->IsStatic() )
445 if ( !pNamedAnimation )
return TFALSE;
448 if ( !pAnimation )
return TFALSE;
485 if ( !pNamedAnimation )
return TFALSE;
503 DestroyAnimReferences();
506 m_pSkeletonInstance->RemoveAllAnimations();
512 a_rAnimationRef.m_pTransition = a_pTransition;
515 if ( pNamedAnimation )
530 return m_pAnimationSet;
537 pAnimRef = GetAnimationRef( m_llAnimRefs, a_strName );
538 if ( !pAnimRef ) pAnimRef = GetAnimationRef( m_llOverlayAnimRefs, a_strName );
546 if ( !GetAnimationRef( m_llAnimRefs, a_pAnimation->
GetName() ) &&
547 !GetAnimationRef( m_llOverlayAnimRefs, a_pAnimation->
GetName() ) &&
551 PlayAnimImpl( a_pAnimation, a_fWeight, a_pTransition, *pAnimRef );
565 GetAnimationTransition( m_llAnimRefs, a_pAnimation->
GetName(), pAnimRef, pTransition );
567 return CreateAnimationRef( m_llOverlayAnimRefs, a_pAnimation, a_fWeight, pTransition );
576void AToshiAnimationInterface::DestroyAnimReferences()
578 while ( !m_llAnimRefs.IsEmpty() )
581 m_llAnimRefs.Erase( itAnimRef );
586 while ( !m_llOverlayAnimRefs.IsEmpty() )
589 m_llOverlayAnimRefs.Erase( itAnimRef );
597 m_pNamedAnimation =
TNULL;
600 m_pTransition =
TNULL;
601 m_bWasEverUpdated =
TFALSE;
602 m_iBreakpointIndex = 0;
#define TOSHI_NAMESPACE_USING
#define T2_FOREACH(vecName, iteratorName)
Toshi::T2ObjectPool< AToshiAnimationRef, 100 > g_oAnimationRefPool
Toshi::TRef< ANamedAnimationSet > ANamedAnimationSetRef
TFORCEINLINE const T & Max(const T &a, const T &b)
TFLOAT GetBlendOutSpeed() const
void ChangeToManaged(TFLOAT a_fBlendOutSpeed)
TBOOL UpdateTime(TFLOAT a_fDeltaTime)
void RemoveAnimation(TFLOAT a_fVal)
TFLOAT SetSpeed(TFLOAT a_fSpeed)
void SetBlendOutSpeed(TFLOAT a_fBlendOutSpeed)
Toshi::T2Iterator< T, Node > Iterator
const Toshi::TPString8 & GetAnimationName()
TFLOAT GetBlendOutTime() const
TFLOAT GetBlendInTime() const
ANamedAnimationTransition * GetDestTransition()
TFLOAT GetDefaultBlendOutTime() const
TBOOL IsFinishManual() const
TINT16 GetSequenceId() const
ANamedAnimationTransitionSet & GetTransitionSet()
const Toshi::TPString8 & GetExportedName() const
TFLOAT GetDuration() const
SortedBreakpointList & GetBreakpoints()
TFLOAT GetDefaultWeight() const
TFLOAT GetDefaultBlendInTime() const
const Toshi::TPString8 & GetName() const
ANamedAnimationTransition * GetTransition() const
void SetWeight(TFLOAT a_fWeight)
TUINT16 GetSequenceId() const
ANamedAnimation * GetNamedAnimation() const
AToshiAnimationRef * FindAnimationRef(const Toshi::TPString8 &a_strName)
Toshi::TAnimation * GetAnimation(const AToshiAnimationRef &a_rAnimRef)
~AToshiAnimationInterface()
TBOOL SetAnimationTransition(AToshiAnimationRef &a_rAnimationRef, ANamedAnimationTransition *a_pTransition)
TBOOL StopAnim(const AToshiAnimationRef &a_rAnimationRef)
AToshiAnimationRef * CreateOverlayAnimationRef(ANamedAnimation *a_pAnimation, TFLOAT a_fWeight)
@ ANIMEVENT_TYPE_BREAKPOINT
void Update(TFLOAT a_fDeltaTime, AnimEventList &a_rEventList)
ANamedAnimationSetRef GetAnimationSet()
AToshiAnimationInterface()
AToshiAnimationRef * CreateAnimationRef(Toshi::T2DList< AToshiAnimationRef > &a_rList, ANamedAnimation *a_pAnimation, TFLOAT a_fWeight, ANamedAnimationTransition *a_pTransition)
AToshiAnimationRef * PlayAnim(const Toshi::TPString8 &a_strName, TFLOAT a_fWeight, TBOOL a_bCreateNewRef)
void SetBreakpointEvent(AAnimationBreakpoint *a_pBreakpoint, TBOOL a_bIsOverlay, const Toshi::TPString8 &a_strAnimationName, TFLOAT a_fTimeToBreakpoint)
TFLOAT fTimeFromBreakpoint
AAnimationBreakpoint * pNextBreakpoint
void SetSimpleEvent(ANIMEVENT_TYPE a_eType, TBOOL a_bIsOverlay, const Toshi::TPString8 &a_strAnimationName, TFLOAT a_fTimeToBreakpoint)
Toshi::TPString8 strAnimationName