Advertisement
Guest User

DAE students unite

a guest
Mar 30th, 2017
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.78 KB | None | 0 0
  1. //Precompiled Header [ALWAYS ON TOP IN CPP]
  2. #include "stdafx.h"
  3.  
  4. #include "ModelAnimator.h"
  5. #include "../Diagnostics/Logger.h"
  6.  
  7.  
  8. ModelAnimator::ModelAnimator(MeshFilter* pMeshFilter) :
  9.     m_pMeshFilter(pMeshFilter),
  10.     m_Transforms(vector<XMFLOAT4X4>()),
  11.     m_IsPlaying(false),
  12.     m_Reversed(false),
  13.     m_ClipSet(false),
  14.     m_TickCount(0),
  15.     m_AnimationSpeed(1.0f)
  16. {
  17.     SetAnimation(0);
  18. }
  19.  
  20.  
  21. ModelAnimator::~ModelAnimator()
  22. {
  23. }
  24.  
  25. void ModelAnimator::SetAnimation(UINT clipNumber)
  26. {
  27.     //Set m_ClipSet to false
  28.     m_ClipSet = false;
  29.     //Check if clipNumber is smaller than the actual m_AnimationClips vector size
  30.     if (clipNumber >= m_pMeshFilter->m_AnimationClips.size() || clipNumber < 0)
  31.     {
  32.         //  Call Reset
  33.         Reset();
  34.         //  Log a warning with an appropriate message
  35.         Logger::LogWarning(L"Could Not Set Animation Clip Number");
  36.         //  return
  37.         return;
  38.     }
  39.     //else
  40.     //  Retrieve the AnimationClip from the m_AnimationClips vector based on the given clipNumber
  41.     //  Call SetAnimation(AnimationClip clip)
  42.     SetAnimation(m_pMeshFilter->m_AnimationClips[clipNumber]);
  43. }
  44.  
  45. void ModelAnimator::SetAnimation(wstring clipName)
  46. {
  47.     //Set m_ClipSet to false
  48.     m_ClipSet = false;
  49.     //Iterate the m_AnimationClips vector and search for an AnimationClip with the given name (clipName)
  50.     auto found = find_if(m_pMeshFilter->m_AnimationClips.begin(), m_pMeshFilter->m_AnimationClips.end(),
  51.         [clipName](AnimationClip a)
  52.     {
  53.         return clipName == a.Name;
  54.     });
  55.     //If found,
  56.     if (found != m_pMeshFilter->m_AnimationClips.end())
  57.     {
  58.         //  Call SetAnimation(Animation Clip) with the found clip
  59.         SetAnimation(*found);
  60.         return;
  61.     }
  62.     //Else
  63.     //  Call Reset
  64.     Reset();
  65.     //  Log a warning with an appropriate message
  66.     Logger::LogWarning(L"Could Not Find Animation Clip With This Name: " + clipName);
  67. }
  68.  
  69. void ModelAnimator::SetAnimation(AnimationClip clip)
  70. {
  71.     //Set m_ClipSet to true
  72.     m_ClipSet = true;
  73.     //Set m_CurrentClip
  74.     m_CurrentClip = clip;
  75.     //Call Reset(false)
  76.     Reset(false);
  77. }
  78.  
  79. void ModelAnimator::Reset(bool pause)
  80. {
  81.     //If pause is true, set m_IsPlaying to false
  82.     if (pause == true)
  83.     {
  84.         m_IsPlaying = false;
  85.     }
  86.     //Set m_TickCount to zero
  87.     m_TickCount = 0;
  88.     //Set m_AnimationSpeed to 1.0f
  89.     m_AnimationSpeed = 1.0f;
  90.  
  91.     //If m_ClipSet is true
  92.     if (m_ClipSet == true)
  93.     {
  94.         //  Retrieve the BoneTransform from the first Key from the current clip (m_CurrentClip)
  95.         auto idk = m_CurrentClip.Keys[0].BoneTransforms;
  96.         //  Refill the m_Transforms vector with the new BoneTransforms (have a look at vector::assign)
  97.         m_Transforms.assign(idk.begin(), idk.end());
  98.     }
  99.     //Else
  100.     else
  101.     {
  102.         //  Create an IdentityMatrix
  103.         //  Refill the m_Transforms vector with this IdenityMatrix (Amount = BoneCount) (have a look at vector::assign)
  104.         XMFLOAT4X4 idm =
  105.         { 1,0,0,0,
  106.         0,1,0,0,
  107.         0,0,1,0,
  108.         0,0,0,1 };
  109.         m_Transforms.assign(m_pMeshFilter->m_BoneCount, idm);
  110.     }
  111. }
  112.  
  113. void ModelAnimator::Update(const GameContext& gameContext)
  114. {
  115.     //We only update the transforms if the animation is running and the clip is set
  116.     if (m_IsPlaying && m_ClipSet)
  117.     {
  118.         //1.
  119.         //Calculate the passedTicks (see the lab document)
  120.         auto passedTicks = gameContext.pGameTime->GetElapsed()* m_CurrentClip.TicksPerSecond * m_AnimationSpeed;
  121.  
  122.         //Make sure that the passedTicks stay between the m_CurrentClip.Duration bounds (fmod)
  123.         passedTicks = fmod(passedTicks, m_CurrentClip.Duration);
  124.  
  125.         //2.
  126.         //IF m_Reversed is true
  127.         if (m_Reversed == true)
  128.         {
  129.             //  Subtract passedTicks from m_TickCount
  130.             m_TickCount -= passedTicks;
  131.             //  If m_TickCount is smaller than zero, add m_CurrentClip.Duration to m_TickCount
  132.             m_TickCount += m_TickCount < 0 ? m_CurrentClip.Duration : 0;
  133.         }
  134.         else //ELSE
  135.         {
  136.             //  Add passedTicks to m_TickCount
  137.             m_TickCount += passedTicks;
  138.             //  if m_TickCount is bigger than the clip duration, subtract the duration from m_TickCount
  139.             m_TickCount -= m_TickCount > m_CurrentClip.Duration ? m_CurrentClip.Duration : 0;
  140.  
  141.         }
  142.         //3.
  143.         //Find the enclosing keys
  144.         AnimationKey keyA = m_CurrentClip.Keys[0], keyB = m_CurrentClip.Keys[0];
  145.         //Iterate all the keys of the clip and find the following keys:
  146.         //keyA > Closest Key with Tick before/smaller than m_TickCount
  147.         //keyB > Closest Key with Tick after/bigger than m_TickCount
  148.         for (size_t i = 0; i < m_CurrentClip.Keys.size(); i++)
  149.         {
  150.             auto curr = m_CurrentClip.Keys[i];
  151.             if (curr.Tick < m_TickCount && curr.Tick > keyA.Tick)
  152.             {
  153.                 keyA = curr;
  154.                 keyB = m_CurrentClip.Keys[i+1];
  155.             }
  156.         }
  157.  
  158.         //4.
  159.         //Interpolate between keys
  160.         //Figure out the BlendFactor (See lab document)
  161.         float blend = (m_TickCount - keyA.Tick) / keyB.Tick;
  162.         //Clear the m_Transforms vector
  163.         m_Transforms.clear();
  164.  
  165.         //FOR every boneTransform in a key (So for every bone)
  166.         auto bones = GetBoneTransforms();
  167.         for (int i = 0; i < keyA.BoneTransforms.size(); ++i)
  168.         {
  169.             //  Retrieve the transform from keyA (transformA)
  170.             auto transformA = keyA.BoneTransforms[i];
  171.             //  Retrieve the transform from keyB (transformB)
  172.             auto transformB = keyB.BoneTransforms[i];
  173.             //  Decompose both transforms
  174.             //  Lerp between all the transformations (Position, Scale, Rotation)
  175.             //  Compose a transformation matrix with the lerp-results
  176.             //  Add the resulting matrix to the m_Transforms vector
  177.             XMVECTOR scaleA, posA, rotA,
  178.                 scaleB, posB, rotB,
  179.                 scaleC, posC, rotC;
  180.             XMMatrixDecompose(&scaleA, &rotA, &posA, XMLoadFloat4x4(&transformA));
  181.             XMMatrixDecompose(&scaleB, &rotB, &posB, XMLoadFloat4x4(&transformB));
  182.             scaleC = XMVectorLerp(scaleA, scaleB, blend);
  183.             posC = XMVectorLerp(posA, posB, blend);
  184.             rotC = XMQuaternionSlerp(rotA, rotB, blend);
  185.             XMFLOAT4X4 mat;
  186.             XMStoreFloat4x4(
  187.                 &mat,
  188.                 XMMatrixScalingFromVector(scaleC)*
  189.                 XMMatrixRotationQuaternion(rotC) *
  190.                 XMMatrixTranslationFromVector(posC)
  191.                 );
  192.  
  193.             m_Transforms.push_back(mat);
  194.         }
  195.     }
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement