OpenBarnyard
 
Loading...
Searching...
No Matches
TSkeletonInstance Class Reference

#include <TSkeleton.h>

Classes

struct  BoneCache
 

Public Member Functions

 TSkeletonInstance ()
 
 ~TSkeletonInstance ()
 
TAnimationAddAnimation (TUINT16 a_iSequenceIndex, TFLOAT a_fDestWeight, TFLOAT a_fBlendInSpeed)
 
TAnimationAddAnimationFull (TUINT16 a_iSequenceIndex, TFLOAT a_fDestWeight, TFLOAT a_fBlendInSpeed, TFLOAT a_fBlendOutSpeed, TAnimation::Flags a_eFlags)
 
TAnimationGetAnimation (TUINT16 a_iSeqId)
 
void RemoveAnimation (TAnimation *a_pAnimation, TFLOAT a_fBlendOutSpeed)
 
void RemoveAllAnimations ()
 
void UpdateTime (TFLOAT a_fDeltaTime)
 
void UpdateState (TBOOL a_bForceUpdate)
 
const TMatrix44GetBoneTransformCurrent (TINT a_iBone)
 
TMatrix44GetBoneTransformCurrent (TINT a_iBone, TMatrix44 &a_rOutTransform)
 
void SetStateFromBasePose ()
 
void Delete ()
 
TSkeletonGetSkeleton ()
 
const TSkeletonInstanceBoneGetBones ()
 
const TSkeletonInstanceBoneGetBone (TINT a_uiIndex)
 

Public Attributes

friend TSkeleton
 

Static Public Attributes

static TMatrix44 g_aForwardMatrices [TANIMATION_MAXBONES]
 
static BoneCache g_aBonesCaches [TANIMATION_MAXBONES]
 

Detailed Description

Definition at line 185 of file TSkeleton.h.

Constructor & Destructor Documentation

◆ TSkeletonInstance()

TSkeletonInstance::TSkeletonInstance ( )

Definition at line 551 of file TSkeleton.cpp.

552{
553}

◆ ~TSkeletonInstance()

TSkeletonInstance::~TSkeletonInstance ( )

Definition at line 410 of file TSkeleton.cpp.

411{
412 m_pSkeleton->m_iInstanceCount--;
413}

Member Function Documentation

◆ AddAnimation()

TAnimation * TSkeletonInstance::AddAnimation ( TUINT16 a_iSequenceIndex,
TFLOAT a_fDestWeight,
TFLOAT a_fBlendInSpeed )

Definition at line 540 of file TSkeleton.cpp.

541{
542 return AddAnimationFull( a_iSequenceIndex, a_fDestWeight, a_fBlendInSpeed, 0.0f, 0 );
543}
TAnimation * AddAnimationFull(TUINT16 a_iSequenceIndex, TFLOAT a_fDestWeight, TFLOAT a_fBlendInSpeed, TFLOAT a_fBlendOutSpeed, TAnimation::Flags a_eFlags)

◆ AddAnimationFull()

TAnimation * TSkeletonInstance::AddAnimationFull ( TUINT16 a_iSequenceIndex,
TFLOAT a_fDestWeight,
TFLOAT a_fBlendInSpeed,
TFLOAT a_fBlendOutSpeed,
TAnimation::Flags a_eFlags )

Definition at line 434 of file TSkeleton.cpp.

435{
436 if ( m_pSkeleton->GetSequenceCount() <= a_iSequenceIndex )
437 return TNULL;
438
439 TAnimation* pAnimation = TNULL;
440
441 // Check if this animation is already playing as a base animation
442 for ( auto it = m_BaseAnimations.Begin(); pAnimation != TNULL && it != m_BaseAnimations.End(); ++it )
443 {
444 if ( it->GetSequence() == a_iSequenceIndex )
445 pAnimation = it;
446 }
447
448 // Check if this animation is already playing as an overlay animation
449 for ( auto it = m_BaseAnimations.Begin(); pAnimation != TNULL && it != m_BaseAnimations.End(); ++it )
450 {
451 if ( it->GetSequence() == a_iSequenceIndex )
452 pAnimation = it;
453 }
454
455 const TBOOL bIsNewAnim = pAnimation == TNULL;
456
457 if ( bIsNewAnim )
458 {
459 // Get a free animation from the list
460 pAnimation = m_FreeAnimations.IsEmpty() ? TNULL : m_FreeAnimations.Begin();
461
462 // If the free list is empty, replace the most unimportant animation with it
463 if ( !pAnimation )
464 {
465 TQList<TAnimation>* pIterateList = &m_BaseAnimations;
466
467 // If no base animations are currently playing, get one from the overlay animations list
468 if ( m_BaseAnimations.IsEmpty() )
469 pIterateList = &m_OverlayAnimations;
470
471 TASSERT( !pIterateList->IsEmpty() );
472 pAnimation = pIterateList->Begin();
473
474 // Find an animation that has the most least weight
475 for ( auto it = pIterateList->Begin().Next(); it != pIterateList->End(); it++ )
476 {
477 if ( it->GetWeight() < pAnimation->GetWeight() )
478 pAnimation = it;
479 }
480
481 // Instantly remove the animation
482 if ( TSkeletonInstance* pSkeletonInstance = pAnimation->GetSkeletonInstance() )
483 pSkeletonInstance->RemoveAnimation( pAnimation, 0.0f );
484 }
485
486 // Remove animation from any list
487 pAnimation->TQList<TAnimation>::TNode::Remove();
488
489 if ( m_pSkeleton->GetSequence( a_iSequenceIndex )->IsBase() )
490 {
491 // Base Animation
492 m_BaseAnimations.PushFront( pAnimation );
493 m_iBaseAnimationCount++;
494 }
495 else
496 {
497 // Overlay Animation
498 m_OverlayAnimations.PushFront( pAnimation );
499 m_iOverlayAnimationCount++;
500 }
501 }
502
503 // Clamp values
504 TMath::Clip( a_fDestWeight, 0.0f, 1.0f );
505
506 // Setup animation
507 TVALIDPTR( pAnimation );
508 pAnimation->m_iSeqID = a_iSequenceIndex;
509 pAnimation->m_eFlags = a_eFlags | TAnimation::Flags_Active;
510 pAnimation->m_iUnk3 = 0;
511 pAnimation->m_fSpeed = 1.0f;
512
513 if ( bIsNewAnim ) pAnimation->m_fWeight = 0.0f;
514 TMath::Clip( pAnimation->m_fWeight, 0.0f, 1.0f );
515
516 pAnimation->m_fBlendOutSpeed = a_fBlendOutSpeed;
517 pAnimation->m_fDestWeight = a_fDestWeight;
518 pAnimation->m_fTotalTime = 0.0f;
519 pAnimation->m_fSeqTime = 0.0f;
520 pAnimation->m_fBlendInSpeed = a_fBlendInSpeed;
521
522 if ( a_fBlendInSpeed <= 0.0f )
523 {
524 pAnimation->m_fWeight = a_fDestWeight;
525 pAnimation->m_eState = TAnimation::STATE_PLAYING;
526 }
527 else
528 {
529 pAnimation->m_eState = TAnimation::STATE_BLENDING_IN;
530 }
531
532 // Clear auto bones data
533 TUtil::MemSet( pAnimation->GetBones(), 0, m_pSkeleton->GetAutoBoneCount() * sizeof( TAnimationBone ) );
534
535 pAnimation->m_pSkeletonInstance = this;
536 return pAnimation;
537}
unsigned short TAnimationBone
Definition TAnimation.h:18
#define TASSERT(X,...)
Definition Defines.h:138
#define TVALIDPTR(PTR)
Definition Defines.h:139
#define TNULL
Definition Typedefs.h:23
bool TBOOL
Definition Typedefs.h:6
TFORCEINLINE void Clip(T &rVal, const T &Min, const T &Max)
TSkeletonInstance * GetSkeletonInstance() const
Definition TAnimation.h:66
TAnimationBone * GetBones()
Definition TAnimation.h:75
TFLOAT GetWeight() const
Definition TAnimation.h:70
@ STATE_BLENDING_IN
Definition TAnimation.h:38
TNode::Iterator Begin() const
Definition TQList.h:106
TBOOL IsEmpty() const
Definition TQList.h:129
const TNode * End() const
Definition TQList.h:111
static void MemSet(void *ptr, TINT value, TSIZE size)
Definition TUtil.h:89

◆ Delete()

void TSkeletonInstance::Delete ( )

Definition at line 395 of file TSkeleton.cpp.

396{
397 delete this;
398}

◆ GetAnimation()

TAnimation * TSkeletonInstance::GetAnimation ( TUINT16 a_iSeqId)

Definition at line 416 of file TSkeleton.cpp.

417{
418 T2_FOREACH( m_BaseAnimations, it )
419 {
420 if ( it->GetSequence() == a_iSeqId )
421 return it;
422 }
423
424 T2_FOREACH( m_OverlayAnimations, it )
425 {
426 if ( it->GetSequence() == a_iSeqId )
427 return it;
428 }
429
430 return TNULL;
431}
#define T2_FOREACH(vecName, iteratorName)
Definition T2Iterator.h:4

◆ GetBone()

const TSkeletonInstanceBone & TSkeletonInstance::GetBone ( TINT a_uiIndex)

Definition at line 545 of file TSkeleton.cpp.

546{
547 TASSERT( a_uiIndex < m_pSkeleton->GetAutoBoneCount() );
548 return m_pBones[ a_uiIndex ];
549}

◆ GetBones()

const TSkeletonInstanceBone * TSkeletonInstance::GetBones ( )
inline

Definition at line 217 of file TSkeleton.h.

217{ return m_pBones; }

◆ GetBoneTransformCurrent() [1/2]

const TMatrix44 & TSkeletonInstance::GetBoneTransformCurrent ( TINT a_iBone)

Definition at line 339 of file TSkeleton.cpp.

340{
341 static TMatrix44 s_Transform;
342
343 GetBoneTransformCurrent( a_iBone, s_Transform );
344 return s_Transform;
345}
const TMatrix44 & GetBoneTransformCurrent(TINT a_iBone)

◆ GetBoneTransformCurrent() [2/2]

TMatrix44 & TSkeletonInstance::GetBoneTransformCurrent ( TINT a_iBone,
TMatrix44 & a_rOutTransform )

Definition at line 323 of file TSkeleton.cpp.

324{
325 if ( a_iBone < m_pSkeleton->GetAutoBoneCount() )
326 {
327 auto pBone = m_pSkeleton->GetBone( a_iBone );
328 a_rOutTransform.Multiply( m_pBones[ a_iBone ].m_Transform, pBone->GetTransform() );
329
330 return a_rOutTransform;
331 }
332
333 a_rOutTransform = m_pSkeleton->GetBone( a_iBone )->GetTransform();
334
335 return a_rOutTransform;
336}
void Multiply(const TMatrix44 &a_rLeft, const TMatrix44 &a_rRight)
Definition TMatrix44.cpp:61

◆ GetSkeleton()

TSkeleton * TSkeletonInstance::GetSkeleton ( )
inline

Definition at line 216 of file TSkeleton.h.

216{ return m_pSkeleton; }

◆ RemoveAllAnimations()

void TSkeletonInstance::RemoveAllAnimations ( )

Definition at line 401 of file TSkeleton.cpp.

402{
403 while ( !m_BaseAnimations.IsEmpty() )
404 RemoveAnimation( m_BaseAnimations.Begin(), 0.0f );
405
406 while ( !m_OverlayAnimations.IsEmpty() )
407 RemoveAnimation( m_OverlayAnimations.Begin(), 0.0f );
408}
void RemoveAnimation(TAnimation *a_pAnimation, TFLOAT a_fBlendOutSpeed)

◆ RemoveAnimation()

void TSkeletonInstance::RemoveAnimation ( TAnimation * a_pAnimation,
TFLOAT a_fBlendOutSpeed )

Definition at line 348 of file TSkeleton.cpp.

349{
350 if ( !a_pAnimation )
351 return;
352
353 TASSERT( TTRUE == a_pAnimation->IsActive() );
354
355 if ( a_fBlendOutSpeed > 0.0f )
356 {
357 a_pAnimation->m_fDestWeight = 0.0f;
358 a_pAnimation->m_fBlendOutSpeed = a_fBlendOutSpeed;
359 a_pAnimation->m_eState = TAnimation::STATE_BLENDING_OUT;
360 }
361 else if ( a_pAnimation->m_eFlags & TAnimation::Flags_UpdateStateOnRemove )
362 {
363 a_pAnimation->m_eFlags &= ~TAnimation::Flags_UpdateStateOnRemove;
364 a_pAnimation->m_fDestWeight = 1.0f;
365 a_pAnimation->m_fBlendOutSpeed = 1.0f;
366 a_pAnimation->m_eState = TAnimation::STATE_BLENDING_OUT;
367 m_eFlags |= 1;
368 }
369 else
370 {
371 if ( a_pAnimation->GetSequencePtr()->IsOverlay() )
372 m_iOverlayAnimationCount -= 1;
373 else
374 m_iBaseAnimationCount -= 1;
375
376 a_pAnimation->m_eFlags = TAnimation::Flags_None;
377
378 // Unlink the animation and add it to the list of free animations
379 a_pAnimation->Remove();
380 m_FreeAnimations.PushFront( a_pAnimation );
381 }
382}
#define TTRUE
Definition Typedefs.h:25
@ Flags_UpdateStateOnRemove
Definition TAnimation.h:32
TBOOL IsActive() const
Definition TAnimation.h:60
class TSkeletonSequence * GetSequencePtr() const
@ STATE_BLENDING_OUT
Definition TAnimation.h:40
TBOOL IsOverlay() const
Definition TSkeleton.h:70
void Remove()
Definition TQList.h:47

◆ SetStateFromBasePose()

void TSkeletonInstance::SetStateFromBasePose ( )

Definition at line 385 of file TSkeleton.cpp.

386{
387 for ( TINT i = 0; i < m_pSkeleton->GetAutoBoneCount(); i++ )
388 {
389 m_pBones[ i ].m_Rotation = m_pSkeleton->GetBone( i )->GetRotation();
390 m_pBones[ i ].m_Position = m_pSkeleton->GetBone( i )->GetPosition();
391 m_pBones[ i ].m_Transform.Identity();
392 }
393}
int TINT
Definition Typedefs.h:7

◆ UpdateState()

void TSkeletonInstance::UpdateState ( TBOOL a_bForceUpdate)

Definition at line 148 of file TSkeleton.cpp.

149{
150 if ( ( a_bForceUpdate || m_iLastUpdateStateFrame != g_oSystemManager.GetFrameCount() ) &&
151 m_pSkeleton->GetKeyLibraryInstance().GetLibrary() != TNULL )
152 {
153 m_iLastUpdateStateFrame = g_oSystemManager.GetFrameCount();
154
155 const auto QInterpFn = m_pSkeleton->GetQInterpFn();
156 TFLOAT fOneOverTotalWeight = 1.0f;
157
158 if ( 1.0f < m_fTotalWeight )
159 fOneOverTotalWeight = 1.0f / m_fTotalWeight;
160
161 TASSERT( m_pSkeleton->GetAutoBoneCount() < TANIMATION_MAXBONES );
162
163 for ( TINT i = 0; i < m_pSkeleton->GetAutoBoneCount(); i++ )
164 {
166
167 auto& rBoneCache = g_aBonesCaches[ i ];
168 auto pBone = m_pSkeleton->GetBone( i );
169
170 if ( m_BaseAnimations.IsEmpty() )
171 {
172 rBoneCache.Rotation = pBone->GetRotation();
173 rBoneCache.Position = pBone->GetPosition();
174 }
175 else
176 {
177 TFLOAT fWeightTotalRatio = 0.0f;
178 TBOOL bBoneHasState = TFALSE;
179
180 T2_FOREACH( m_BaseAnimations, it )
181 {
182 auto pSeq = m_pSkeleton->GetSequence( it->GetSequence() );
183 auto pSeqBone = pSeq->GetBone( i );
184
185 TINT iCurrentKeyframePos = TINT( ( it->GetSeqTime() / pSeq->GetDuration() ) * 65535 );
186
187 TUINT16 iLerpFromIndex;
188 TUINT16 iLerpToIndex;
189 TFLOAT fLerpProgress = pSeqBone->GetKeyPair( iCurrentKeyframePos, *it->GetBone( i ), iLerpFromIndex, iLerpToIndex );
190
191 TFLOAT fWeightRatio = it->GetWeight() * fOneOverTotalWeight;
192
193 if ( fWeightRatio > 0.0f && pSeqBone->GetKeyCount() != 0 )
194 {
195 auto pFromKey = pSeqBone->GetKey( iLerpFromIndex );
196 auto pToKey = pSeqBone->GetKey( iLerpToIndex );
197
198 auto& rKeyLibrary = m_pSkeleton->GetKeyLibraryInstance();
199 auto pFromQuat = rKeyLibrary.GetQ( pFromKey[ 1 ] );
200 auto pToQuat = rKeyLibrary.GetQ( pToKey[ 1 ] );
201
202 if ( it == m_BaseAnimations.Head() )
203 {
204 bBoneHasState = TTRUE;
205 fWeightTotalRatio = fWeightRatio;
206 QInterpFn( rBoneCache.Rotation, *pFromQuat, *pToQuat, fLerpProgress );
207
208 if ( pSeqBone->IsTranslateAnimated() )
209 {
210 auto pFromTranslation = rKeyLibrary.GetT( pFromKey[ 2 ] );
211 auto pToTranslation = rKeyLibrary.GetT( pToKey[ 2 ] );
212
213 rBoneCache.Position.Lerp( *pFromTranslation, *pToTranslation, fLerpProgress );
214 }
215 else
216 {
217 rBoneCache.Position = pBone->GetPosition();
218 }
219 }
220 else
221 {
222 TVector4 position;
223 TQuaternion rotation;
224
225 QInterpFn( rotation, *pFromQuat, *pToQuat, fLerpProgress );
226
227 if ( pSeqBone->IsTranslateAnimated() )
228 {
229 auto pFromTranslation = rKeyLibrary.GetT( pFromKey[ 2 ] );
230 auto pToTranslation = rKeyLibrary.GetT( pToKey[ 2 ] );
231
232 position.Lerp3( *pFromTranslation, *pToTranslation, fLerpProgress );
233 }
234
235 fWeightTotalRatio += fWeightRatio;
236 QInterpFn( rBoneCache.Rotation, rBoneCache.Rotation, rotation, fWeightRatio / fWeightTotalRatio );
237
238 const TVector3* pLerpToVec = pSeqBone->IsTranslateAnimated() ? &position.AsVector3() : &pBone->GetPosition();
239 rBoneCache.Position.Lerp( *pLerpToVec, fWeightRatio / fWeightTotalRatio );
240 }
241 }
242 }
243
244 if ( !bBoneHasState )
245 {
246 rBoneCache.Rotation = pBone->GetRotation();
247 rBoneCache.Position = pBone->GetPosition();
248 }
249 }
250
251 T2_FOREACH( m_OverlayAnimations, it )
252 {
253 if ( it->GetWeight() != 0.0f )
254 {
255 auto pSeq = m_pSkeleton->GetSequence( it->GetSequence() );
256 auto pSeqBone = pSeq->GetBone( i );
257
258 if ( !pSeqBone->IsOverlayAnimated() && pSeqBone->GetKeyCount() != 0 )
259 {
260 TINT iCurrentKeyframePos = TINT( ( it->GetSeqTime() / pSeq->GetDuration() ) * 65535 );
261
262 TUINT16 iLerpFromIndex;
263 TUINT16 iLerpToIndex;
264 TFLOAT fLerpProgress = pSeqBone->GetKeyPair( iCurrentKeyframePos, *it->GetBone( i ), iLerpFromIndex, iLerpToIndex );
265
266 auto pFromKey = pSeqBone->GetKey( iLerpFromIndex );
267 auto pToKey = pSeqBone->GetKey( iLerpToIndex );
268
269 auto& rKeyLibrary = m_pSkeleton->GetKeyLibraryInstance();
270 auto pFromQuat = rKeyLibrary.GetQ( pFromKey[ 1 ] );
271 auto pToQuat = rKeyLibrary.GetQ( pToKey[ 1 ] );
272
273 TVector4 position;
274 TQuaternion rotation;
275
276 QInterpFn( rotation, rBoneCache.Rotation, *pToQuat, fLerpProgress );
277 QInterpFn( rBoneCache.Rotation, rBoneCache.Rotation, rotation, it->GetWeight() );
278
279 const TVector3* pLerpToVec;
280 if ( pSeqBone->IsTranslateAnimated() )
281 {
282 auto pFromTranslation = rKeyLibrary.GetT( pFromKey[ 2 ] );
283 auto pToTranslation = rKeyLibrary.GetT( pToKey[ 2 ] );
284
285 position.Lerp3( *pFromTranslation, *pToTranslation, fLerpProgress );
286 pLerpToVec = &position.AsVector3();
287 }
288 else
289 {
290 pLerpToVec = &pBone->GetPosition();
291 }
292
293 rBoneCache.Position.Lerp( *pLerpToVec, it->GetWeight() );
294 }
295 }
296 }
297
298 // Save the transform
299 auto& rMatrix = g_aForwardMatrices[ i ];
300 auto iParentBone = pBone->GetParentBone();
301
302 if ( iParentBone == TBONE_INVALID )
303 {
304 // No parent bone
305 rMatrix.SetFromQuaternion( rBoneCache.Rotation );
306 rMatrix.SetTranslation( rBoneCache.Position );
307 }
308 else
309 {
310 // Has parent bone
311 TMatrix44 boneTransform;
312 boneTransform.SetFromQuaternion( rBoneCache.Rotation );
313 boneTransform.SetTranslation( rBoneCache.Position );
314 rMatrix.Multiply( g_aForwardMatrices[ iParentBone ], boneTransform );
315 }
316
317 m_pBones[ i ].m_Transform.Multiply( rMatrix, pBone->GetTransformInv() );
318 }
319 }
320}
LoadLibrary TOSHI_NAMESPACE_START constexpr TINT TANIMATION_MAXBONES
Definition TAnimation.h:13
#define TBONE_INVALID
Definition TSkeleton.h:9
TSystemManager g_oSystemManager
uint16_t TUINT16
Definition Typedefs.h:15
float TFLOAT
Definition Typedefs.h:4
#define TFALSE
Definition Typedefs.h:24
void SetTranslation(const TVector4 &a_rTranslation)
Definition TMatrix44.h:167
TMatrix44 & SetFromQuaternion(const TQuaternion &a_rQuaternion)
constexpr void Lerp(const TVector3 &finish, float t)
Definition TVector3.h:53
TVector3 & AsVector3()
Definition TVector4.h:321
constexpr void Lerp3(const TVector4 &finish, TFLOAT t)
Definition TVector4.h:231
static TMatrix44 g_aForwardMatrices[TANIMATION_MAXBONES]
Definition TSkeleton.h:221
static BoneCache g_aBonesCaches[TANIMATION_MAXBONES]
Definition TSkeleton.h:222
TUINT32 GetFrameCount() const
Definition TSystem.h:145

◆ UpdateTime()

void TSkeletonInstance::UpdateTime ( TFLOAT a_fDeltaTime)

Definition at line 116 of file TSkeleton.cpp.

117{
118 if ( !m_BaseAnimations.IsEmpty() || ( !m_OverlayAnimations.IsEmpty() && m_iLastUpdateTimeFrame != g_oSystemManager.GetFrameCount() ) )
119 {
120 m_iLastUpdateTimeFrame = g_oSystemManager.GetFrameCount();
121 m_fTotalWeight = 0.0f;
122
123 // Update base animations
124 T2_FOREACH( m_BaseAnimations, pAnim )
125 {
126 if ( pAnim->UpdateTime( a_fDeltaTime ) )
127 {
128 m_fTotalWeight += pAnim->GetWeight();
129 }
130 }
131
132 // Update overlay animations
133 T2_FOREACH( m_OverlayAnimations, pAnim )
134 {
135 pAnim->UpdateTime( a_fDeltaTime );
136 }
137
138 if ( HASANYFLAG( m_eFlags, 1 ) )
139 {
140 m_eFlags &= ~1;
142 }
143 }
144}
#define HASANYFLAG(STATE, FLAG)
Definition Defines.h:5
void UpdateState(TBOOL a_bForceUpdate)

Member Data Documentation

◆ g_aBonesCaches

BoneCache TSkeletonInstance::g_aBonesCaches[TANIMATION_MAXBONES]
inlinestatic

Definition at line 222 of file TSkeleton.h.

◆ g_aForwardMatrices

TMatrix44 TSkeletonInstance::g_aForwardMatrices[TANIMATION_MAXBONES]
inlinestatic

Definition at line 221 of file TSkeleton.h.

◆ TSkeleton

friend TSkeletonInstance::TSkeleton

Definition at line 194 of file TSkeleton.h.


The documentation for this class was generated from the following files: