BVB Source Codes

CRYENGINE Show ActionScope.cpp Source code

Return Download CRYENGINE: download ActionScope.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. //
  4. ////////////////////////////////////////////////////////////////////////////
  5.  
  6. #include "StdAfx.h"
  7.  
  8. #include "ActionScope.h"
  9. #include "ActionController.h"
  10.  
  11. #include "AnimationDatabase.h"
  12. #include <CryExtension/CryCreateClassInstance.h>
  13. #include "MannequinDebug.h"
  14.  
  15. CActionScope::CActionScope(const char* _name, uint32 scopeID, CActionController& actionController, SAnimationContext& _context, SScopeContext& _scopeContext, int layer, int numLayers, const TagState& additionalTags)
  16.         : m_name(_name)
  17.         , m_id(scopeID)
  18.         , m_context(_context)
  19.         , m_scopeContext(_scopeContext)
  20.         , m_actionController(actionController)
  21.         , m_layer(layer)
  22.         , m_numLayers(numLayers)
  23.         , m_speedBias(1.f)
  24.         , m_animWeight(1.f)
  25.         , m_timeIncrement(0.0f)
  26.         , m_additionalTags(additionalTags)
  27.         , m_cachedFragmentTags(TAG_STATE_EMPTY)
  28.         , m_cachedContextStateMask(TAG_STATE_EMPTY)
  29.         , m_cachedaaID(FRAGMENT_ID_INVALID)
  30.         , m_cachedTagSetIdx(TAG_SET_IDX_INVALID)
  31.         , m_lastFragmentID(FRAGMENT_ID_INVALID)
  32.         , m_sequenceFlags(0)
  33.         , m_fragmentTime(0.0f)
  34.         , m_fragmentDuration(0.0f)
  35.         , m_transitionOutroDuration(0.0f)
  36.         , m_transitionDuration(0.0f)
  37.         , m_blendOutDuration(0.0f)
  38.         , m_lastNormalisedTime(0.0f)
  39.         , m_normalisedTime(0.0f)
  40.         , m_mutedAnimLayerMask(0)
  41.         , m_mutedProcLayerMask(0)
  42.         , m_isOneShot(false)
  43.         , m_fragmentInstalled(false)
  44. {
  45.         m_layerSequencers = new SSequencer[numLayers];
  46. }
  47.  
  48. CActionScope::~CActionScope()
  49. {
  50.         delete[] m_layerSequencers;
  51. }
  52.  
  53. bool CActionScope::InstallAnimation(int animID, const CryCharAnimationParams& animParams)
  54. {
  55.         ISkeletonAnim& skeletonAnimation = *m_scopeContext.pCharInst->GetISkeletonAnim();
  56.         const bool startAnimationSuccess = skeletonAnimation.StartAnimationById(animID, animParams);
  57.         skeletonAnimation.SetLayerPlaybackScale(animParams.m_nLayerID, m_speedBias);
  58.         skeletonAnimation.SetLayerBlendWeight(animParams.m_nLayerID, m_animWeight);
  59.  
  60.         return startAnimationSuccess;
  61. }
  62.  
  63. void CActionScope::StopAnimationOnLayer(uint32 layer, float blendTime)
  64. {
  65.         CRY_ASSERT_MESSAGE(layer < m_numLayers, "Overrunning scope!");
  66.  
  67.         ISkeletonAnim& skeletonAnimation = *m_scopeContext.pCharInst->GetISkeletonAnim();
  68.         const uint32 actualLayer = layer + m_layer;
  69.         skeletonAnimation.StopAnimationInLayer(actualLayer, blendTime);
  70. }
  71.  
  72. float CActionScope::GetFragmentStartTime() const
  73. {
  74.         return m_transitionDuration - m_fragmentTime;
  75. }
  76.  
  77. float CActionScope::CalculateFragmentTimeRemaining() const
  78. {
  79.         float ret = 0.0f;
  80.         if ((m_numLayers > 0) && m_scopeContext.pCharInst)
  81.         {
  82.                 SSequencer& sequencer = m_layerSequencers[0];
  83.  
  84.                 if (!sequencer.sequence.empty())
  85.                 {
  86.                         const float timeTillInstall = sequencer.installTime;
  87.                         const uint32 numClips = sequencer.sequence.size();
  88.                         ret += max(0.0f, timeTillInstall);
  89.                         for (uint32 clip = sequencer.pos + 1; clip < numClips; clip++)
  90.                         {
  91.                                 SAnimClip& animClip = sequencer.sequence[clip];
  92.                                 ret += animClip.blend.exitTime;
  93.                         }
  94.  
  95.                         if (sequencer.pos < numClips)
  96.                         {
  97.                                 //--- Add on the final clip duration
  98.                                 SAnimClip& animClip = sequencer.sequence[numClips - 1];
  99.                                 ret += animClip.referenceLength;
  100.                         }
  101.  
  102.                         return ret;
  103.                 }
  104.         }
  105.  
  106.         //--- Fallback to the static times
  107.         //--- TODO: Consider updating these values on tick and simplify this function down
  108.         const float totalDuration = m_fragmentDuration + m_transitionDuration + m_transitionOutroDuration;
  109.  
  110.         return totalDuration - m_fragmentTime;
  111.         ;
  112. }
  113.  
  114. float CActionScope::CalculateFragmentDuration(const CFragment& fragment) const
  115. {
  116.         IAnimationSet* pAnimSet = m_scopeContext.pCharInst ? m_scopeContext.pCharInst->GetIAnimationSet() : NULL;
  117.  
  118.         float ret = 0.0f;
  119.         if (pAnimSet)
  120.         {
  121.                 if (fragment.m_animLayers.size() > 0)
  122.                 {
  123.                         const TAnimClipSequence& animClipSeq = fragment.m_animLayers[0];
  124.  
  125.                         uint32 numClips = animClipSeq.size();
  126.                         float lastDuration = 0.0f;
  127.                         for (uint32 i = 0; i < numClips; i++)
  128.                         {
  129.                                 const SAnimClip& animClip = animClipSeq[0];
  130.  
  131.                                 if (i > 0)
  132.                                 {
  133.                                         if (animClip.blend.exitTime >= 0.0f)
  134.                                         {
  135.                                                 ret += animClip.blend.exitTime;
  136.                                         }
  137.                                         else
  138.                                         {
  139.                                                 ret += lastDuration;
  140.                                         }
  141.                                 }
  142.                                 lastDuration = 0.0f;
  143.                                 if (!animClip.animation.IsEmpty() && !(animClip.animation.flags & CA_LOOP_ANIMATION) && (animClip.animation.playbackSpeed > 0.0f))
  144.                                 {
  145.                                         int animID = pAnimSet->GetAnimIDByCRC(animClip.animation.animRef.crc);
  146.                                         if (animID >= 0)
  147.                                         {
  148.                                                 lastDuration = (pAnimSet->GetDuration_sec(animID) / animClip.animation.playbackSpeed);
  149.                                         }
  150.                                 }
  151.                         }
  152.  
  153.                         ret += lastDuration;
  154.                 }
  155.         }
  156.  
  157.         return ret;
  158. }
  159.  
  160. const CAnimation* CActionScope::GetTopAnim(int layer) const
  161. {
  162.         const CAnimation* anim = NULL;
  163.         if (m_scopeContext.pCharInst)
  164.         {
  165.                 ISkeletonAnim& skeletonAnimation = *m_scopeContext.pCharInst->GetISkeletonAnim();
  166.                 int nAnimsInFIFO = skeletonAnimation.GetNumAnimsInFIFO(m_layer + layer);
  167.                 if (nAnimsInFIFO > 0)
  168.                 {
  169.                         anim = &skeletonAnimation.GetAnimFromFIFO(m_layer + layer, nAnimsInFIFO - 1);
  170.                 }
  171.         }
  172.  
  173.         return anim;
  174. }
  175.  
  176. CAnimation* CActionScope::GetTopAnim(int layer)
  177. {
  178.         CAnimation* anim = NULL;
  179.         if (m_scopeContext.pCharInst)
  180.         {
  181.                 ISkeletonAnim& skeletonAnimation = *m_scopeContext.pCharInst->GetISkeletonAnim();
  182.                 int nAnimsInFIFO = skeletonAnimation.GetNumAnimsInFIFO(m_layer + layer);
  183.                 if (nAnimsInFIFO > 0)
  184.                 {
  185.                         anim = &skeletonAnimation.GetAnimFromFIFO(m_layer + layer, nAnimsInFIFO - 1);
  186.                 }
  187.         }
  188.  
  189.         return anim;
  190. }
  191.  
  192. void CActionScope::IncrementTime(float timeDelta)
  193. {
  194.         m_timeIncrement = timeDelta;
  195. }
  196.  
  197. void CActionScope::FillBlendQuery(SBlendQuery& query, FragmentID fragID, const SFragTagState& fragTagState, bool isHigherPriority, float* pLoopDuration) const
  198. {
  199.         query.fragmentFrom = m_lastFragmentID;
  200.         query.fragmentTo = fragID;
  201.         query.fragmentTime = m_fragmentTime;
  202.         query.tagStateFrom = m_lastQueueTagState;
  203.         query.tagStateTo.globalTags = m_context.controllerDef.m_tags.GetUnion(fragTagState.globalTags, m_additionalTags);
  204.         query.tagStateTo.fragmentTags = fragTagState.fragmentTags;
  205.         query.additionalTags = m_additionalTags;
  206.         query.prevNormalisedTime = m_lastNormalisedTime;
  207.         query.normalisedTime = m_normalisedTime;
  208.         query.SetFlag(SBlendQuery::higherPriority, isHigherPriority);
  209.         query.SetFlag(SBlendQuery::fromInstalled, m_fragmentInstalled);
  210.         query.SetFlag(SBlendQuery::toInstalled, true);
  211.         query.SetFlag(SBlendQuery::noTransitions, m_actionController.GetFlag(AC_NoTransitions));
  212.  
  213.         const CAnimation* pAnim = GetTopAnim(0);
  214.         if (pAnim)
  215.         {
  216.                 if (pLoopDuration)
  217.                 {
  218.                         *pLoopDuration = pAnim->GetCurrentSegmentExpectedDurationSeconds();
  219.                 }
  220.                 query.normalisedTime = pAnim->GetCurrentSegmentNormalizedTime();
  221.         }
  222. }
  223.  
  224. bool CActionScope::CanInstall(EPriorityComparison priorityComp, FragmentID fragID, const SFragTagState& fragTagState, bool isRequeue, float& timeRemaining) const
  225. {
  226.         IAction* const pCompareAction = m_pAction ? m_pAction.get() : m_pExitingAction.get();
  227.         if (isRequeue || (pCompareAction && pCompareAction->CanBlendOut(priorityComp)) || (!pCompareAction))
  228.         {
  229.                 const float totalDuration = m_fragmentDuration + m_transitionDuration + m_transitionOutroDuration;
  230.  
  231.                 if ((priorityComp == Higher)
  232.                     || !pCompareAction
  233.                     || (pCompareAction->m_eStatus == IAction::Finished)
  234.                     || (pCompareAction->m_eStatus == IAction::Exiting))
  235.                 {
  236.                         timeRemaining = 0.0f;
  237.                 }
  238.                 else if (m_fragmentTime <= 0.0f)
  239.                 {
  240.                         return false;
  241.                 }
  242.                 else if (m_scopeContext.pDatabase == NULL)
  243.                 {
  244.                         timeRemaining = totalDuration - m_fragmentTime;
  245.                 }
  246.                 else
  247.                 {
  248.                         SBlendQuery query;
  249.                         float loopDuration;
  250.                         FillBlendQuery(query, fragID, fragTagState, false, &loopDuration);
  251.  
  252.                         SBlendQueryResult queryRes1, queryRes2;
  253.                         m_scopeContext.pDatabase->FindBestBlends(query, queryRes1, queryRes2);
  254.                         if (queryRes1.pFragmentBlend)
  255.                         {
  256.                                 float startTime = queryRes1.pFragmentBlend->startTime;
  257.  
  258.                                 if (queryRes1.pFragmentBlend->flags & SFragmentBlend::Cyclic)
  259.                                 {
  260.                                         if (queryRes1.pFragmentBlend->flags & SFragmentBlend::CycleLocked)
  261.                                         {
  262.                                                 float cycleDiff = startTime - m_normalisedTime;
  263.                                                 if ((m_lastNormalisedTime < startTime) || (m_lastNormalisedTime > m_normalisedTime))
  264.                                                 {
  265.                                                         cycleDiff = max(cycleDiff, 0.0f);
  266.                                                 }
  267.                                                 else
  268.                                                 {
  269.                                                         cycleDiff = (float)__fsel(cycleDiff, cycleDiff, 1.0f + cycleDiff);
  270.                                                 }
  271.  
  272.                                                 timeRemaining = loopDuration * cycleDiff;
  273.                                         }
  274.                                         else
  275.                                         {
  276.                                                 timeRemaining = 0.0f;
  277.                                         }
  278.                                 }
  279.                                 else
  280.                                 {
  281.                                         timeRemaining = CalculateFragmentTimeRemaining() + startTime;
  282.                                 }
  283.                         }
  284.                         else
  285.                         {
  286.                                 timeRemaining = CalculateFragmentTimeRemaining();
  287.                         }
  288.                 }
  289.  
  290.                 if (pCompareAction)
  291.                 {
  292.                         pCompareAction->m_flags |= IAction::TransitionPending;
  293.                 }
  294.  
  295.                 return true;
  296.         }
  297.         else
  298.         {
  299.                 return false;
  300.         }
  301. }
  302.  
  303. void CActionScope::InitAnimationParams(const SAnimationEntry& animEntry, const uint32 sequencerLayer, const SAnimBlend& animBlend, CryCharAnimationParams& paramsOut)
  304. {
  305.         CRY_ASSERT_MESSAGE(sequencerLayer < m_numLayers, "Overrunning scope!");
  306.  
  307.         paramsOut.m_fTransTime = animBlend.duration;
  308.         paramsOut.m_nLayerID = m_layer + sequencerLayer;
  309.  
  310.         paramsOut.m_nFlags = animEntry.flags | CA_ALLOW_ANIM_RESTART;
  311.         paramsOut.m_fPlaybackSpeed = animEntry.playbackSpeed;
  312.  
  313.         for (uint32 i = 0; i < MANN_NUMBER_BLEND_CHANNELS; i++)
  314.         {
  315.                 paramsOut.m_fUserData[i] = animEntry.blendChannels[i];
  316.         }
  317.  
  318.         const int animID = m_scopeContext.pCharInst->GetIAnimationSet()->GetAnimIDByCRC(animEntry.animRef.crc);
  319.         const float animDuration = m_scopeContext.pCharInst->GetIAnimationSet()->GetDuration_sec(animID);
  320.         if (0 < animDuration)
  321.         {
  322.                 paramsOut.m_fKeyTime = animBlend.startTime / animDuration;
  323.         }
  324.         paramsOut.m_fPlaybackWeight = animEntry.playbackWeight;
  325. #if defined(USE_PROTOTYPE_ABS_BLENDING)
  326.         if (animEntry.weightList != 0)
  327.         {
  328.                 const uint8 NUM_WEIGHTLISTS = 3;
  329.                 static SJointMask* spJointMask[NUM_WEIGHTLISTS] = { NULL, NULL, NULL };
  330.                 static bool sInitialised = false;
  331.  
  332.                 if (!sInitialised)
  333.                 {
  334.                         sInitialised = true;
  335.  
  336.                         spJointMask[0] = new SJointMask();
  337.                         spJointMask[0]->weightList.push_back(SJointMask::SJointWeight(15, 0.3f));
  338.                         spJointMask[0]->weightList.push_back(SJointMask::SJointWeight(20, 0.6f));
  339.                         spJointMask[0]->weightList.push_back(SJointMask::SJointWeight(22, 1.0f));
  340.  
  341.                         spJointMask[1] = new SJointMask();
  342.                         spJointMask[1]->weightList.push_back(SJointMask::SJointWeight(22, 1.0f));
  343.  
  344.                         spJointMask[2] = new SJointMask();
  345.                         spJointMask[2]->weightList.push_back(SJointMask::SJointWeight(25, 0.5f));
  346.                         spJointMask[2]->weightList.push_back(SJointMask::SJointWeight(37, 1.0f));
  347.                 }
  348.                 int maskidx = min(animEntry.weightList, NUM_WEIGHTLISTS) - 1;
  349.                 paramsOut.m_pJointMask = spJointMask[maskidx];
  350.         }
  351. #endif //!defined(USE_PROTOTYPE_ABS_BLENDING)
  352.         //--- We never want the lower level systems to refuse an install or to pop off something for us
  353.         if ((animEntry.flags & CA_LOOP_ANIMATION) == 0)
  354.         {
  355.                 paramsOut.m_nFlags |= CA_REPEAT_LAST_KEY;
  356.         }
  357.         paramsOut.m_nUserToken = m_userToken;
  358. }
  359.  
  360. bool CActionScope::InstallAnimation(const SAnimationEntry& animEntry, int layer, const SAnimBlend& animBlend)
  361. {
  362.         if ((BIT(layer) & m_mutedAnimLayerMask) == BIT(layer))
  363.         {
  364.                 return false;
  365.         }
  366.  
  367.         if (animEntry.animRef.IsEmpty())
  368.         {
  369.                 StopAnimationOnLayer(layer, animBlend.duration);
  370.                 return true;
  371.         }
  372.         else
  373.         {
  374.                 int animID = m_scopeContext.pCharInst->GetIAnimationSet()->GetAnimIDByCRC(animEntry.animRef.crc);
  375.  
  376.                 if (animID >= 0)
  377.                 {
  378.                         //--- Cleared for install, install across scopes
  379.                         CryCharAnimationParams animParams;
  380.                         InitAnimationParams(animEntry, layer, animBlend, animParams);
  381.                         return InstallAnimation(animID, animParams);
  382.                 }
  383.                 else
  384.                 {
  385.                         CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "Invalid anim ref '%s' on scope '%s' in database '%s'. Skeleton '%s'", animEntry.animRef.c_str(), m_name.c_str(), m_scopeContext.pDatabase->GetFilename(), m_scopeContext.pCharInst->GetIDefaultSkeleton().GetModelFilePath());
  386.  
  387.                         StopAnimationOnLayer(layer, animBlend.duration);
  388.                         return false;
  389.                 }
  390.         }
  391. }
  392.  
  393. void CActionScope::QueueAnimFromSequence(uint32 layer, uint32 pos, bool isPersistent)
  394. {
  395.         CRY_ASSERT_MESSAGE(layer < m_numLayers, "Invalid layer idx");
  396.         SSequencer& sequencer = m_layerSequencers[layer];
  397.  
  398.         if (pos < sequencer.sequence.size())
  399.         {
  400.                 const SAnimClip& animClip = sequencer.sequence[pos];
  401.                 const SAnimBlend& fragmentBlend = animClip.blend;
  402.  
  403.                 sequencer.blend = fragmentBlend;
  404.                 sequencer.installTime = sequencer.blend.exitTime;
  405.                 if (pos > 0)
  406.                 {
  407.                         sequencer.referenceTime = sequencer.sequence[pos - 1].referenceLength;
  408.                 }
  409.                 sequencer.flags |= eSF_Queued;
  410.  
  411.                 CRY_ASSERT_MESSAGE(sequencer.installTime >= 0.0f, "Invalid exit time!");
  412.         }
  413.         else if (!isPersistent)
  414.         {
  415.                 if (pos > 0)
  416.                 {
  417.                         sequencer.referenceTime = sequencer.sequence[pos - 1].referenceLength;
  418.                 }
  419.                 sequencer.installTime = sequencer.referenceTime;
  420.                 sequencer.flags |= eSF_Queued;
  421.         }
  422. }
  423.  
  424. void CActionScope::QueueProcFromSequence(uint32 layer, uint32 pos)
  425. {
  426.         CRY_ASSERT_MESSAGE(layer < m_procSequencers.size(), "Invalid layer idx");
  427.         SProcSequencer& sequencer = m_procSequencers[layer];
  428.  
  429.         if (pos < sequencer.sequence.size())
  430.         {
  431.                 sequencer.blend = sequencer.sequence[pos].blend;
  432.                 sequencer.installTime = sequencer.blend.exitTime;
  433.                 sequencer.flags |= eSF_Queued;
  434.         }
  435. }
  436.  
  437. int CActionScope::GetNumAnimsInSequence(uint32 layer) const
  438. {
  439.         CRY_ASSERT_MESSAGE(layer < m_numLayers, "Invalid layer idx");
  440.         SSequencer& sequencer = m_layerSequencers[layer];
  441.  
  442.         return sequencer.sequence.size();
  443. }
  444.  
  445. void CActionScope::ClipInstalled(uint8 fragPart)
  446. {
  447.         EClipType clipType = m_partTypes[fragPart];
  448.         if (m_pExitingAction && m_pExitingAction->IsTransitioningOut() && (clipType != eCT_TransitionOutro))
  449.         {
  450.                 m_actionController.EndAction(*m_pExitingAction);
  451.                 m_pExitingAction = NULL;
  452.                 if (m_pAction)
  453.                 {
  454.                         m_actionController.StartAction(*m_pAction);
  455.                 }
  456.         }
  457.  
  458.         if (m_pAction && (&m_pAction->GetRootScope() == this))
  459.         {
  460.                 if (clipType == eCT_Transition)
  461.                 {
  462.                         if (!m_pAction->IsTransitioning())
  463.                         {
  464.                                 m_pAction->TransitionStarted();
  465.                         }
  466.                 }
  467.                 else if ((clipType == eCT_Normal) && !m_pAction->IsPlayingFragment())
  468.                 {
  469.                         m_pAction->FragmentStarted();
  470.                 }
  471.         }
  472. }
  473.  
  474. void CActionScope::ApplyAnimWeight(uint32 layer, float weight)
  475. {
  476.         CRY_ASSERT_MESSAGE(layer < GetTotalLayers(), "Invalid layer");
  477.  
  478.         if (layer < GetTotalLayers())
  479.         {
  480.                 SSequencer& sequencer = m_layerSequencers[layer];
  481.  
  482.                 if (sequencer.pos > 0)
  483.                 {
  484.                         CAnimation* pAnimation = GetTopAnim(layer);
  485.  
  486.                         if (pAnimation)
  487.                         {
  488.                                 const SAnimClip& animClip = sequencer.sequence[sequencer.pos - 1];
  489.                                 float baseWeight = animClip.animation.playbackWeight;
  490.  
  491.                                 pAnimation->SetPlaybackWeight(max(0.0f, weight * baseWeight));
  492.                         }
  493.                 }
  494.         }
  495. }
  496.  
  497. bool CActionScope::PlayPendingAnim(uint32 layer, float timePassed)
  498. {
  499.         CRY_ASSERT_MESSAGE(layer < m_numLayers, "Invalid layer idx");
  500.         SSequencer& sequencer = m_layerSequencers[layer];
  501.         IActionPtr pPlayingAction = GetPlayingAction();
  502.  
  503.         const bool isBlendingOut = (sequencer.flags & eSF_BlendingOut) != 0;
  504.  
  505.         sequencer.flags &= ~eSF_Queued;
  506.         sequencer.installTime = 0.0f;
  507.         sequencer.referenceTime = -1.0f;
  508.  
  509.         if ((sequencer.pos < sequencer.sequence.size()) || isBlendingOut)
  510.         {
  511.                 uint8 fragPart = 0;
  512.                 bool isTransition = false;
  513.                 const SAnimationEntry* animation = NULL;
  514.                 SAnimationEntry animNull;
  515.                 animNull.animRef.SetByString(NULL);
  516.                 animNull.flags = 0;
  517.                 animNull.playbackSpeed = 1.0f;
  518.                 animNull.playbackWeight = 1.0f;
  519.                 if (!isBlendingOut)
  520.                 {
  521.                         const SAnimClip& animClip = sequencer.sequence[sequencer.pos];
  522.                         fragPart = animClip.part;
  523.                         animation = &animClip.animation;
  524.                         sequencer.pos++;
  525.                 }
  526.                 else
  527.                 {
  528.                         animation = &animNull;
  529.                         sequencer.flags &= ~eSF_BlendingOut;
  530.                 }
  531.  
  532.                 InstallAnimation(*animation, layer, sequencer.blend);
  533.  
  534.                 if (pPlayingAction && (&pPlayingAction->GetRootScope() == this) && !isBlendingOut)
  535.                 {
  536.                         ClipInstalled(fragPart);
  537.                 }
  538.  
  539.                 QueueAnimFromSequence(layer, sequencer.pos, (animation->flags & CA_LOOP_ANIMATION) != 0);
  540.  
  541.                 return true;
  542.         }
  543.         else
  544.         {
  545.                 //--- Notify action about completion
  546.                 if (pPlayingAction)
  547.                 {
  548.                         pPlayingAction->OnSequenceFinished(layer, m_id);
  549.                 }
  550.  
  551.                 return false;
  552.         }
  553. }
  554.  
  555. bool CActionScope::PlayPendingProc(uint32 layer)
  556. {
  557.         CRY_ASSERT_MESSAGE(layer < m_procSequencers.size(), "Invalid layer idx");
  558.         SProcSequencer& sequencer = m_procSequencers[layer];
  559.  
  560.         sequencer.flags &= ~eSF_Queued;
  561.         const TProcClipSequence& sequence = sequencer.sequence;
  562.         const size_t numSequences = sequence.size();
  563.         const bool bIsBlendOut = ((sequencer.flags & eSF_BlendingOut) != 0);
  564.         if ((sequencer.pos < numSequences) || bIsBlendOut)
  565.         {
  566.                 const bool bPlayingProc = !bIsBlendOut;
  567.                 if (bPlayingProc)
  568.                 {
  569.                         const SProceduralEntry& proceduralEntry = sequence[sequencer.pos];
  570.                         ++sequencer.pos;
  571.                         const float duration = (sequencer.pos < numSequences) ? sequence[sequencer.pos].blend.exitTime : -1.0f;
  572.                         InstallProceduralClip(proceduralEntry, layer, sequencer.blend, duration);
  573.                         ClipInstalled(proceduralEntry.part);
  574.                 }
  575.                 else
  576.                 {
  577.                         SProceduralEntry proc;
  578.                         InstallProceduralClip(proc, layer, sequencer.blend, -1.f);
  579.                         sequencer.flags &= ~eSF_BlendingOut;
  580.                 }
  581.  
  582.                 QueueProcFromSequence(layer, sequencer.pos);
  583.                 return bPlayingProc;
  584.         }
  585.  
  586.         return false;
  587. }
  588.  
  589. bool CActionScope::QueueFragment(FragmentID fragID, const SFragTagState& fragTagState, uint32 optionIdx, float startTime, uint32 userToken, bool isRootScope, bool isHigherPriority, bool principleContext)
  590. {
  591.         if (m_scopeContext.pDatabase == NULL)
  592.         {
  593.                 return false;
  594.         }
  595.  
  596.         SBlendQuery query;
  597.         FillBlendQuery(query, fragID, fragTagState, isHigherPriority, NULL);
  598.         query.SetFlag(SBlendQuery::toInstalled, principleContext);
  599.  
  600.         SFragmentData fragData;
  601.         IAnimationSet* pAnimSet = m_scopeContext.pCharInst ? m_scopeContext.pCharInst->GetIAnimationSet() : NULL;
  602.         m_sequenceFlags = m_scopeContext.pDatabase->Query(fragData, query, optionIdx, pAnimSet, &m_lastFragSelection);
  603.         m_lastQueueTagState = query.tagStateTo;
  604.         m_lastNormalisedTime = m_normalisedTime = 0.0f;
  605.         m_isOneShot = fragData.isOneShot && ((fragID == FRAGMENT_ID_INVALID) || ((m_context.controllerDef.GetFragmentDef(fragID).flags & SFragmentDef::PERSISTENT) == 0));
  606.         m_blendOutDuration = fragData.blendOutDuration;
  607.         m_fragmentInstalled = principleContext;
  608.  
  609.         const bool fragmentInstalled = HasFragment();
  610.  
  611. #if MANNEQUIN_DEBUGGING_ENABLED
  612.         CryStackStringT<char, 128> sTagList = "No Match";
  613.         CryStackStringT<char, 128> sFragTagList;
  614.  
  615.         if (!fragmentInstalled && (m_layer == 0) && (m_numLayers > 0))
  616.         {
  617.                 const char* fragmentName = fragID != FRAGMENT_ID_INVALID ? m_context.controllerDef.m_fragmentIDs.GetTagName(fragID) : "None";
  618.                 m_context.controllerDef.m_tags.FlagsToTagList(fragTagState.globalTags, sTagList);
  619.                 const CTagDefinition* pFragTagDef = (fragID != FRAGMENT_ID_INVALID) ? m_context.controllerDef.GetFragmentTagDef(fragID) : NULL;
  620.                 if (pFragTagDef)
  621.                 {
  622.                         pFragTagDef->FlagsToTagList(fragTagState.fragmentTags, sFragTagList);
  623.                 }
  624.                 MannLog(GetActionController(), "Warning - Missing root level fragment %s(%s)", fragmentName, sTagList.c_str());
  625.         }
  626.         if (m_actionController.DebugFragments(principleContext) && fragmentInstalled)
  627.         {
  628.                 if (HasFragment())
  629.                 {
  630.                         m_context.controllerDef.m_tags.FlagsToTagList(m_lastFragSelection.tagState.globalTags, sTagList);
  631.                         const CTagDefinition* pFragTagDef = m_context.controllerDef.GetFragmentTagDef(fragID);
  632.                         if (pFragTagDef)
  633.                         {
  634.                                 pFragTagDef->FlagsToTagList(m_lastFragSelection.tagState.fragmentTags, sFragTagList);
  635.                         }
  636.                 }
  637.                 const char* fragmentName = fragID != FRAGMENT_ID_INVALID ? m_context.controllerDef.m_fragmentIDs.GetTagName(fragID) : "None";
  638.                 const char* prevFragmentName = query.fragmentFrom != FRAGMENT_ID_INVALID ? m_context.controllerDef.m_fragmentIDs.GetTagName(query.fragmentFrom) : "None";
  639.  
  640.                 MannLog(GetActionController(), "Frag %s (%s,%s) queued on %s for action %s", fragmentName, sTagList.c_str(), sFragTagList.c_str(), m_name.c_str(), m_pAction ? m_pAction->GetName() : "None");
  641.  
  642.                 CryStackStringT<char, 128> sTagStateFrom;
  643.                 CryStackStringT<char, 128> sTagStateTo;
  644.  
  645.                 SBlendQueryResult queryRes1, queryRes2;
  646.                 m_scopeContext.pDatabase->FindBestBlends(query, queryRes1, queryRes2);
  647.  
  648.                 if (queryRes1.pFragmentBlend)
  649.                 {
  650.                         MannLog(GetActionController(), "Transition from (%s -> %s) %s", (queryRes1.fragmentFrom != FRAGMENT_ID_INVALID) ? prevFragmentName : "Any", (queryRes1.fragmentTo != FRAGMENT_ID_INVALID) ? fragmentName : "Any", queryRes1.pFragmentBlend->IsExitTransition() ? "Exit" : "");
  651.  
  652.                         m_actionController.GetContext().controllerDef.m_tags.FlagsToTagList(queryRes1.tagStateFrom.globalTags, sTagStateFrom);
  653.                         m_actionController.GetContext().controllerDef.m_tags.FlagsToTagList(queryRes1.tagStateTo.globalTags, sTagStateTo);
  654.  
  655.                         MannLog(GetActionController(), "Transition tags (%s -> %s)", sTagStateFrom.c_str(), sTagStateTo.c_str());
  656.                 }
  657.                 if (queryRes2.pFragmentBlend)
  658.                 {
  659.                         MannLog(GetActionController(), "And Transition from (%s -> %s) %s", (queryRes2.fragmentFrom != FRAGMENT_ID_INVALID) ? prevFragmentName : "Any", (queryRes2.fragmentTo != FRAGMENT_ID_INVALID) ? fragmentName : "Any", queryRes2.pFragmentBlend->IsExitTransition() ? "Exit" : "");
  660.  
  661.                         m_actionController.GetContext().controllerDef.m_tags.FlagsToTagList(queryRes2.tagStateFrom.globalTags, sTagStateFrom);
  662.                         m_actionController.GetContext().controllerDef.m_tags.FlagsToTagList(queryRes2.tagStateTo.globalTags, sTagStateTo);
  663.  
  664.                         MannLog(GetActionController(), "Transition tags (%s -> %s)", sTagStateFrom.c_str(), sTagStateTo.c_str());
  665.                 }
  666.         }
  667. #endif //MANNEQUIN_DEBUGGING_ENABLED
  668.  
  669.         m_fragmentDuration = m_transitionOutroDuration = m_transitionDuration = 0.0f;
  670.         for (uint32 i = 0; i < SFragmentData::PART_TOTAL; i++)
  671.         {
  672.                 m_partTypes[i] = fragData.transitionType[i];
  673.                 switch (fragData.transitionType[i])
  674.                 {
  675.                 case eCT_Normal:
  676.                         m_fragmentDuration += fragData.duration[i];
  677.                         break;
  678.                 case eCT_Transition:
  679.                         m_transitionDuration += fragData.duration[i];
  680.                         break;
  681.                 case eCT_TransitionOutro:
  682.                         m_transitionOutroDuration += fragData.duration[i];
  683.                         break;
  684.                 }
  685.         }
  686.         if (!isRootScope)
  687.         {
  688.                 if (m_sequenceFlags & (eSF_Transition | eSF_TransitionOutro))
  689.                 {
  690.                         startTime = 0.0f;
  691.                 }
  692.                 else
  693.                 {
  694.                         startTime = max(startTime - (m_transitionOutroDuration + m_transitionDuration), 0.0f);
  695.                 }
  696.         }
  697.         m_lastFragmentID = fragID;
  698.         m_fragmentTime = -startTime;
  699.  
  700.         const uint32 numAnimLayers = fragData.animLayers.size();
  701.         const uint32 numScopeLayers = m_numLayers;
  702.         const uint32 numLayers = min(numAnimLayers, numScopeLayers);
  703.  
  704.         CRY_ASSERT_MESSAGE(numLayers <= m_numLayers, "Invalid layer count");
  705.  
  706.         m_userToken = userToken;
  707.  
  708.         uint32 nLayer = 0;
  709.         for (nLayer = 0; nLayer < numLayers; nLayer++)
  710.         {
  711.                 const bool hasClips = fragData.animLayers[nLayer].size() > 0;
  712.                 SSequencer& sequencer = m_layerSequencers[nLayer];
  713.  
  714.                 sequencer.pos = 0;
  715.                 sequencer.referenceTime = -1.0f;
  716.  
  717.                 if (hasClips)
  718.                 {
  719.                         sequencer.sequence = fragData.animLayers[nLayer];
  720.                         sequencer.blend = sequencer.sequence[0].blend;
  721.                         sequencer.installTime = startTime + sequencer.blend.exitTime;
  722.                         sequencer.flags = eSF_Queued;
  723.                 }
  724.                 else
  725.                 {
  726.                         sequencer.sequence.resize(0);
  727.  
  728.                         sequencer.blend = SAnimBlend();
  729.                         sequencer.installTime = startTime;
  730.                         sequencer.flags = eSF_Queued | eSF_BlendingOut;
  731.                 }
  732.         }
  733.  
  734.         for (; nLayer < numScopeLayers; nLayer++)
  735.         {
  736.                 //--- Layers that are not touched by the new fragment blend out using default blends
  737.                 SSequencer& sequencer = m_layerSequencers[nLayer];
  738.                 sequencer.sequence.resize(0);
  739.                 sequencer.pos = 0;
  740.  
  741.                 sequencer.blend = SAnimBlend();
  742.                 sequencer.installTime = startTime;
  743.                 sequencer.flags = eSF_Queued | eSF_BlendingOut;
  744.         }
  745.  
  746.         const size_t numProcSequencers = fragData.procLayers.size();
  747.         const size_t totNumProcSequencers = max(numProcSequencers, m_procSequencers.size());
  748.         m_procSequencers.resize(totNumProcSequencers);
  749.         for (nLayer = 0; nLayer < numProcSequencers; nLayer++)
  750.         {
  751.                 const bool hasClips = fragData.procLayers[nLayer].size() > 0;
  752.                 SProcSequencer& sequencerPush = m_procSequencers[nLayer];
  753.                 sequencerPush.pos = 0;
  754.  
  755.                 if (hasClips)
  756.                 {
  757.                         sequencerPush.sequence = fragData.procLayers[nLayer];
  758.  
  759.                         const float layerBlendTime = sequencerPush.sequence[0].blend.exitTime;
  760.                         sequencerPush.installTime = startTime;
  761.                         sequencerPush.blend = sequencerPush.sequence[0].blend;
  762.                         sequencerPush.flags = eSF_Queued;
  763.                         if (layerBlendTime > 0.0f)
  764.                         {
  765.                                 sequencerPush.blend = SAnimBlend();
  766.                                 sequencerPush.flags |= eSF_BlendingOut;
  767.                         }
  768.                 }
  769.                 else
  770.                 {
  771.                         sequencerPush.sequence.resize(0);
  772.  
  773.                         sequencerPush.blend = SAnimBlend();
  774.                         sequencerPush.installTime = startTime;
  775.                         sequencerPush.flags = eSF_Queued | eSF_BlendingOut;
  776.                 }
  777.         }
  778.         for (; nLayer < totNumProcSequencers; nLayer++)
  779.         {
  780.                 SProcSequencer& sequencerPush = m_procSequencers[nLayer];
  781.  
  782.                 sequencerPush.sequence.resize(0);
  783.                 sequencerPush.pos = 0;
  784.  
  785.                 sequencerPush.blend = SAnimBlend();
  786.                 sequencerPush.installTime = startTime;
  787.                 sequencerPush.flags = eSF_Queued | eSF_BlendingOut;
  788.         }
  789.  
  790.         return fragmentInstalled;
  791. }
  792.  
  793. bool CActionScope::IsDifferent(const FragmentID aaID, const TagState& fragmentTags, const TagID subContext /*= TAG_ID_INVALID*/) const
  794. {
  795.         if (m_lastFragmentID != aaID)
  796.         {
  797.                 return true;
  798.         }
  799.         else
  800.         {
  801.                 uint32 tagSetIdx;
  802.                 if (aaID == m_cachedaaID &&
  803.                     fragmentTags == m_cachedFragmentTags &&
  804.                     m_context.state.GetMask() == m_cachedContextStateMask)
  805.                 {
  806.                         tagSetIdx = m_cachedTagSetIdx;
  807.                 }
  808.                 else
  809.                 {
  810.                         SFragmentQuery fragQuery(aaID, SFragTagState(m_context.state.GetMask(), fragmentTags));
  811.                         if (subContext != TAG_ID_INVALID)
  812.                         {
  813.                                 const SSubContext subContextDef = m_context.controllerDef.m_subContext[subContext];
  814.                                 fragQuery.tagState.globalTags = m_context.controllerDef.m_tags.GetUnion(fragQuery.tagState.globalTags, m_context.subStates[subContext].GetMask());
  815.                                 fragQuery.tagState.globalTags = m_context.controllerDef.m_tags.GetUnion(fragQuery.tagState.globalTags, subContextDef.additionalTags);
  816.                         }
  817.                         fragQuery.tagState.globalTags = m_context.controllerDef.m_tags.GetUnion(fragQuery.tagState.globalTags, m_additionalTags);
  818.                         fragQuery.requiredTags = m_additionalTags;
  819.  
  820.                         // the database may not exist in case of full enslavement
  821.                         if (!m_scopeContext.pDatabase)
  822.                         {
  823.                                 return false;
  824.                         }
  825.                         GetDatabase().FindBestMatchingTag(fragQuery, NULL, &tagSetIdx);
  826.  
  827.                         //--- Store cache
  828.                         m_cachedaaID = aaID;
  829.                         m_cachedFragmentTags = fragmentTags;
  830.                         m_cachedContextStateMask = m_context.state.GetMask();
  831.                         m_cachedTagSetIdx = tagSetIdx;
  832.                 }
  833.  
  834.                 return tagSetIdx != m_lastFragSelection.tagSetIdx;
  835.         }
  836.  
  837.         return false;
  838. }
  839.  
  840. void CActionScope::InstallProceduralClip(const SProceduralEntry& proc, int layer, const SAnimBlend& blend, float duration)
  841. {
  842.         if ((BIT(layer) & m_mutedProcLayerMask) == BIT(layer))
  843.         {
  844.                 return;
  845.         }
  846.  
  847.         SProcSequencer& procSeq = m_procSequencers[layer];
  848.         if (procSeq.proceduralClip)
  849.         {
  850.                 procSeq.proceduralClip->OnExit(blend.duration);
  851.                 procSeq.proceduralClip.reset();
  852.         }
  853.  
  854.         const bool isNone = proc.IsNoneType();
  855.         if (!isNone)
  856.         {
  857.                 CRY_ASSERT(gEnv && gEnv->pGameFramework);
  858.                 static IProceduralClipFactory& s_proceduralClipFactory = gEnv->pGameFramework->GetMannequinInterface().GetProceduralClipFactory();
  859.  
  860.                 procSeq.proceduralClip = s_proceduralClipFactory.CreateProceduralClip(proc.typeNameHash);
  861.  
  862.                 if (procSeq.proceduralClip)
  863.                 {
  864.                         const char* contextName = procSeq.proceduralClip->GetContextName();
  865.  
  866.                         if (contextName)
  867.                         {
  868.                                 IProceduralContext* context = m_actionController.FindOrCreateProceduralContext(contextName);
  869.                                 procSeq.proceduralClip->SetContext(context);
  870.                         }
  871.  
  872.                         IEntity* pEntity = gEnv->pEntitySystem->GetEntity(GetEntityId()); // TODO: Handle invalid entity!
  873.                         procSeq.proceduralClip->Initialise(*pEntity, *GetCharInst(), *this, *m_pAction);
  874.                         procSeq.proceduralClip->INTERNAL_OnEnter(blend.duration, duration, proc.pProceduralParams);
  875.                 }
  876.         }
  877. }
  878.  
  879. void CActionScope::UpdateSequencers(float timePassed)
  880. {
  881.         ISkeletonAnim* pSkelAnim = m_scopeContext.pCharInst ? m_scopeContext.pCharInst->GetISkeletonAnim() : NULL;
  882.  
  883.         const bool hasIncrement = (m_timeIncrement != 0.0f);
  884.         timePassed += m_timeIncrement;
  885.         m_timeIncrement = 0.0f;
  886.  
  887.         const int k_MAX_INCREMENTS = 5;
  888.         float queuedIncrements[k_MAX_INCREMENTS];
  889.         int numQueued = 0;
  890.  
  891.         if (pSkelAnim)
  892.         {
  893.                 const CAnimation* pRootAnim = GetTopAnim(0);
  894.                 if (pRootAnim)
  895.                 {
  896.                         m_lastNormalisedTime = m_normalisedTime;
  897.                         m_normalisedTime = pRootAnim->GetCurrentSegmentNormalizedTime();
  898.                 }
  899.  
  900.                 for (uint32 i = 0; i < m_numLayers; i++)
  901.                 {
  902.                         SSequencer& sequencer = m_layerSequencers[i];
  903.                         float timeLeft = timePassed;
  904.                         while ((sequencer.flags & eSF_Queued) != 0)
  905.                         {
  906.                                 const float timeTillInstall = sequencer.installTime;
  907.                                 if (timeLeft >= timeTillInstall)
  908.                                 {
  909.                                         if (PlayPendingAnim(i, timeLeft - timeTillInstall))
  910.                                         {
  911.                                                 timeLeft -= timeTillInstall;
  912.  
  913.                                                 if (numQueued < k_MAX_INCREMENTS)
  914.                                                 {
  915.                                                         queuedIncrements[numQueued++] = timeLeft;
  916.                                                 }
  917.  
  918.                                                 if (sequencer.pos >= sequencer.sequence.size())
  919.                                                         break;
  920.                                         }
  921.                                 }
  922.                                 else
  923.                                 {
  924.                                         sequencer.installTime -= timeLeft;
  925.                                         break;
  926.                                 }
  927.                         }
  928.  
  929.                         if (hasIncrement)
  930.                         {
  931.                                 uint32 layer = m_layer + i;
  932.                                 uint32 numAnims = pSkelAnim->GetNumAnimsInFIFO(layer);
  933.                                 if (numAnims > 0)
  934.                                 {
  935.                                         for (uint32 anm = 0; anm < numAnims; anm++)
  936.                                         {
  937.                                                 int timeIncID = (anm + numQueued) - numAnims;
  938.                                                 float timeIncrement = (timeIncID >= 0) ? queuedIncrements[timeIncID] : timePassed;
  939.  
  940.                                                 if (timeIncrement > 0.0f)
  941.                                                 {
  942.                                                         CAnimation& anim = pSkelAnim->GetAnimFromFIFO(layer, anm);
  943.                                                         float segDuration = m_scopeContext.pCharInst->GetIAnimationSet()->GetDuration_sec(anim.GetAnimationId());
  944.                                                         if (segDuration > 0.0f)
  945.                                                         {
  946.                                                                 const float segNormTime = anim.GetCurrentSegmentNormalizedTime();
  947.                                                                 const float newTime = (segNormTime * segDuration) + (timeIncrement * anim.GetPlaybackScale());
  948.                                                                 float newSegNormTime = newTime / segDuration;
  949.                                                                 if (!anim.HasStaticFlag(CA_LOOP_ANIMATION))
  950.                                                                 {
  951.                                                                         newSegNormTime = min(newSegNormTime, 1.0f);
  952.                                                                 }
  953.                                                                 else
  954.                                                                 {
  955.                                                                         newSegNormTime = newSegNormTime - (float)((int)(newSegNormTime));
  956.                                                                 }
  957.                                                                 anim.SetCurrentSegmentNormalizedTime(newSegNormTime);
  958.                                                         }
  959.  
  960.                                                         float transitionPriority = 0.0f;
  961.                                                         const float transitionTime = anim.GetTransitionTime();
  962.                                                         if ((transitionTime == 0.0f) || (anm < numAnims - 1))
  963.                                                         {
  964.                                                                 transitionPriority = 1.0f;
  965.                                                         }
  966.                                                         else
  967.                                                         {
  968.                                                                 transitionPriority = min(anim.GetTransitionPriority() + (timeIncrement / transitionTime), 1.0f);
  969.                                                         }
  970.                                                         anim.SetTransitionPriority(transitionPriority);
  971.                                                 }
  972.                                         }
  973.                                 }
  974.                         }
  975.                 }
  976.         }
  977.  
  978.         const uint32 numProcSequencers = m_procSequencers.size();
  979.         for (uint32 i = 0; i < numProcSequencers; i++)
  980.         {
  981.                 SProcSequencer& sequencer = m_procSequencers[i];
  982.                 float timeLeft = timePassed;
  983.                 while ((sequencer.flags & eSF_Queued) != 0)
  984.                 {
  985.                         if (timeLeft >= sequencer.installTime)
  986.                         {
  987.                                 timeLeft -= sequencer.installTime;
  988.                                 sequencer.installTime = -1.0f;
  989.                                 PlayPendingProc(i);
  990.                         }
  991.                         else
  992.                         {
  993.                                 sequencer.installTime -= timeLeft;
  994.                                 break;
  995.                         }
  996.                 }
  997.  
  998.                 if (sequencer.proceduralClip)
  999.                 {
  1000.                         sequencer.proceduralClip->Update(timeLeft);
  1001.                 }
  1002.         }
  1003. }
  1004.  
  1005. void CActionScope::Update(float timePassed)
  1006. {
  1007.         IAction* const pPlayingAction = GetPlayingAction().get();
  1008.         if (pPlayingAction)
  1009.         {
  1010.                 ISkeletonAnim* pSkelAnim = m_scopeContext.pCharInst ? m_scopeContext.pCharInst->GetISkeletonAnim() : NULL;
  1011.  
  1012.                 const float newSpeedBias = pPlayingAction->GetSpeedBias();
  1013.                 const float newAnimWeight = pPlayingAction->GetAnimWeight();
  1014.  
  1015.                 if (m_speedBias != newSpeedBias)
  1016.                 {
  1017.                         m_speedBias = newSpeedBias;
  1018.  
  1019.                         if (pSkelAnim)
  1020.                         {
  1021.                                 for (uint32 layer = 0; layer < m_numLayers; layer++)
  1022.                                 {
  1023.                                         pSkelAnim->SetLayerPlaybackScale(m_layer + layer, newSpeedBias);
  1024.                                 }
  1025.                         }
  1026.                 }
  1027.  
  1028.                 if (m_animWeight != newAnimWeight)
  1029.                 {
  1030.                         m_animWeight = newAnimWeight;
  1031.  
  1032.                         if (pSkelAnim)
  1033.                         {
  1034.                                 for (uint32 layer = 0; layer < m_numLayers; layer++)
  1035.                                 {
  1036.                                         pSkelAnim->SetLayerBlendWeight(m_layer + layer, newAnimWeight);
  1037.                                 }
  1038.                         }
  1039.                 }
  1040.  
  1041.                 timePassed *= m_speedBias;
  1042.  
  1043.                 m_fragmentTime += timePassed + m_timeIncrement;
  1044.         }
  1045.  
  1046.         UpdateSequencers(timePassed);
  1047. }
  1048.  
  1049. void CActionScope::BlendOutFragments()
  1050. {
  1051.         QueueFragment(FRAGMENT_ID_INVALID, SFragTagState(m_context.state.GetMask()), OPTION_IDX_RANDOM, 0.0f, m_userToken);
  1052. }
  1053.  
  1054. void CActionScope::ClearSequencers()
  1055. {
  1056.         for (uint32 i = 0; i < m_numLayers; i++)
  1057.         {
  1058.                 SSequencer& sequencer = m_layerSequencers[i];
  1059.                 sequencer.sequence.resize(0);
  1060.                 sequencer.installTime = -1.0f;
  1061.                 sequencer.pos = 0;
  1062.                 sequencer.flags = 0;
  1063.         }
  1064.         const uint32 numProcClips = m_procSequencers.size();
  1065.         for (uint32 i = 0; i < numProcClips; i++)
  1066.         {
  1067.                 SProcSequencer& sequencer = m_procSequencers[i];
  1068.                 sequencer.sequence.resize(0);
  1069.                 sequencer.installTime = -1.0f;
  1070.                 sequencer.pos = 0;
  1071.                 sequencer.flags = 0;
  1072.         }
  1073. }
  1074.  
  1075. void CActionScope::Flush(EFlushMethod flushMethod)
  1076. {
  1077.         ISkeletonAnim* pSkelAnim = m_scopeContext.pCharInst.get() ? m_scopeContext.pCharInst->GetISkeletonAnim() : NULL;
  1078.  
  1079.         for (uint32 i = 0; i < m_numLayers; i++)
  1080.         {
  1081.                 SSequencer& sequencer = m_layerSequencers[i];
  1082.                 //const uint32 numAnims = sequencer.sequence.size();
  1083.                 sequencer.sequence.resize(0);
  1084.                 sequencer.installTime = -1.0f;
  1085.                 sequencer.pos = 0;
  1086.                 sequencer.flags = 0;
  1087.  
  1088.                 //clear FIFO regardless of whether actionscope believes it has animations in the sequence or not
  1089.                 //fixes issue where clearing a scope context wouldn't clear all animations because an empty fragment gets queued first clearing the sequencer
  1090.                 if (/*(numAnims > 0) &&*/ pSkelAnim && (flushMethod != FM_NormalLeaveAnimations))
  1091.                 {
  1092.                         pSkelAnim->ClearFIFOLayer(m_layer + i);
  1093.                 }
  1094.         }
  1095.         const int numProcs = m_procSequencers.size();
  1096.         for (uint32 i = 0; i < numProcs; i++)
  1097.         {
  1098.                 SProcSequencer& procSeq = m_procSequencers[i];
  1099.                 if (procSeq.proceduralClip)
  1100.                 {
  1101.                         switch (flushMethod)
  1102.                         {
  1103.                         case FM_Normal:
  1104.                         case FM_NormalLeaveAnimations:
  1105.                                 procSeq.proceduralClip->OnExit(0.0f);
  1106.                                 break;
  1107.                         case FM_Failure:
  1108.                                 procSeq.proceduralClip->OnFail();
  1109.                                 break;
  1110.                         default:
  1111.                                 CRY_ASSERT(false);
  1112.                         }
  1113.                 }
  1114.         }
  1115.         m_procSequencers.resize(0);
  1116.  
  1117.         m_lastFragmentID = FRAGMENT_ID_INVALID;
  1118.         m_fragmentTime = 0.0f;
  1119.         m_lastFragSelection = SFragmentSelection();
  1120.         m_lastQueueTagState = SFragTagState();
  1121.         m_sequenceFlags = 0;
  1122. }
  1123.  
  1124. void CActionScope::Pause()
  1125. {
  1126.         if (!m_scopeContext.pCharInst)
  1127.         {
  1128.                 return;
  1129.         }
  1130.  
  1131.         ISkeletonAnim& skeletonAnimation = *m_scopeContext.pCharInst->GetISkeletonAnim();
  1132.  
  1133.         for (int i = 0; i < m_numLayers; ++i)
  1134.         {
  1135.                 SSequencer& sequencer = m_layerSequencers[i];
  1136.  
  1137.                 const int animationLayer = m_layer + i;
  1138.  
  1139.                 const int animationsInLayer = skeletonAnimation.GetNumAnimsInFIFO(animationLayer);
  1140.                 if (animationsInLayer == 0)
  1141.                 {
  1142.                         sequencer.savedAnimNormalisedTime = -1;
  1143.                 }
  1144.                 else
  1145.                 {
  1146.                         const int lastAnimationIndex = animationsInLayer - 1;
  1147.                         const CAnimation& animation = skeletonAnimation.GetAnimFromFIFO(animationLayer, lastAnimationIndex);
  1148.                         sequencer.savedAnimNormalisedTime = skeletonAnimation.GetAnimationNormalizedTime(&animation);
  1149.                 }
  1150.         }
  1151. }
  1152.  
  1153. void CActionScope::Resume(float forcedBlendTime, uint32 resumeFlags)
  1154. {
  1155.         if (!m_scopeContext.pCharInst)
  1156.         {
  1157.                 return;
  1158.         }
  1159.  
  1160.         IAnimationSet* pAnimSet = m_scopeContext.pCharInst->GetIAnimationSet();
  1161.         if (!pAnimSet)
  1162.         {
  1163.                 return;
  1164.         }
  1165.  
  1166.         ISkeletonAnim& skeletonAnimation = *m_scopeContext.pCharInst->GetISkeletonAnim();
  1167.  
  1168.         const bool useDefaultBlendTime = (forcedBlendTime < 0);
  1169.  
  1170.         for (int i = 0; i < m_numLayers; ++i)
  1171.         {
  1172.                 SSequencer& sequencer = m_layerSequencers[i];
  1173.  
  1174.                 const int animationLayer = m_layer + i;
  1175.                 const float blendTime = useDefaultBlendTime ? sequencer.blend.duration : forcedBlendTime;
  1176.  
  1177.                 if (sequencer.savedAnimNormalisedTime < 0)
  1178.                 {
  1179.                         skeletonAnimation.StopAnimationInLayer(animationLayer, blendTime);
  1180.                 }
  1181.                 else
  1182.                 {
  1183.                         const uint32 pos = sequencer.pos - 1;
  1184.                         if (pos < sequencer.sequence.size())
  1185.                         {
  1186.                                 SAnimClip& clip = sequencer.sequence[pos];
  1187.                                 const int animID = pAnimSet->GetAnimIDByCRC(clip.animation.animRef.crc);
  1188.                                 if (0 <= animID)
  1189.                                 {
  1190.                                         CryCharAnimationParams params;
  1191.                                         InitAnimationParams(clip.animation, i, clip.blend, params);
  1192.                                         const bool installAnimationSuccess = InstallAnimation(animID, params);
  1193.                                         if (installAnimationSuccess)
  1194.                                         {
  1195.                                                 const int animationsInLayer = skeletonAnimation.GetNumAnimsInFIFO(animationLayer);
  1196.                                                 CRY_ASSERT(1 <= animationsInLayer);
  1197.  
  1198.                                                 const bool loopingAnimation = ((clip.animation.flags & CA_LOOP_ANIMATION) != 0);
  1199.                                                 const uint32 restoreAnimationTimeFlagToCheck = loopingAnimation ? IActionController::ERF_RestoreLoopingAnimationTime : IActionController::ERF_RestoreNonLoopingAnimationTime;
  1200.                                                 const bool restoreAnimationTime = ((restoreAnimationTimeFlagToCheck & resumeFlags) != 0);
  1201.                                                 if (restoreAnimationTime)
  1202.                                                 {
  1203.                                                         const int lastAnimationIndex = animationsInLayer - 1;
  1204.                                                         CAnimation& animation = skeletonAnimation.GetAnimFromFIFO(animationLayer, lastAnimationIndex);
  1205.                                                         skeletonAnimation.SetAnimationNormalizedTime(&animation, sequencer.savedAnimNormalisedTime);
  1206.                                                 }
  1207.                                         }
  1208.                                 }
  1209.                         }
  1210.                 }
  1211.         }
  1212. }
  1213.  
  1214. void CActionScope::MuteLayers(uint32 mutedAnimLayerMask, uint32 mutedProcLayerMask)
  1215. {
  1216.         m_mutedAnimLayerMask = mutedAnimLayerMask;
  1217.         m_mutedProcLayerMask = mutedProcLayerMask;
  1218. }
  1219.  
  1220. bool SScopeContext::HasInvalidCharInst() const
  1221. {
  1222.         return pCharInst && (pCharInst->GetRefCount() <= 1);
  1223. }
  1224.  
  1225. bool SScopeContext::HasInvalidEntity() const
  1226. {
  1227.         IEntity* pExpectedEntity = gEnv->pEntitySystem->GetEntity(entityId);
  1228.         return (pExpectedEntity != pCachedEntity);
  1229. }
  1230.  
downloadActionScope.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top