BVB Source Codes

CRYENGINE Show AnimActionTriState.cpp Source code

Return Download CRYENGINE: download AnimActionTriState.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. //
  4. ////////////////////////////////////////////////////////////////////////////
  5. #include "StdAfx.h"
  6. #include "AnimationGraph/AnimatedCharacter.h"
  7. #include "AnimActionTriState.h"
  8.  
  9. // ----------------------------------------------------------------------------
  10. const char* ANIMEVENT_ANIMEXIT = "animexit";
  11. const EMovementControlMethod DEFAULT_MCM_HORIZONTAL = eMCM_Entity;
  12. const EMovementControlMethod DEFAULT_MCM_VERTICAL = eMCM_Entity;
  13.  
  14. #define SendTriStateEvent(event)                        \
  15.   {                                                     \
  16.     On ## event();                                      \
  17.                                                         \
  18.     if (m_pListener)                                    \
  19.     {                                                   \
  20.       m_pListener->OnAnimActionTriState ## event(this); \
  21.     }                                                   \
  22.   }
  23.  
  24. // ----------------------------------------------------------------------------
  25. CAnimActionTriState::CAnimActionTriState(int priority, FragmentID fragmentID, IAnimatedCharacter& animChar, bool oneShot, float maxMiddleDuration, bool skipIntro, IAnimActionTriStateListener* pListener)
  26.         : TBase(priority, fragmentID, TAG_STATE_EMPTY, oneShot ? 0 : NoAutoBlendOut)
  27.         , m_animChar(animChar)
  28.         , m_pListener(pListener)
  29.         , m_subState(eSS_None)
  30. #ifndef _RELEASE
  31.         , m_entered(false)
  32. #endif
  33.         , m_triStateFlags((oneShot ? eTSF_OneShot : 0) | (skipIntro ? eTSF_SkippedIntro : 0))
  34.         , m_mcmHorizontal(DEFAULT_MCM_HORIZONTAL)
  35.         , m_mcmVertical(DEFAULT_MCM_VERTICAL)
  36.         , m_mcmHorizontalOld(eMCM_Undefined)
  37.         , m_mcmVerticalOld(eMCM_Undefined)
  38.         , m_maxMiddleDuration(maxMiddleDuration)
  39. {
  40.         CRY_ASSERT(&m_animChar);
  41. }
  42.  
  43. // ----------------------------------------------------------------------------
  44. void CAnimActionTriState::OnInitialise()
  45. {
  46.         if ((m_triStateFlags & eTSF_SkippedIntro) == 0)
  47.         {
  48.                 static uint32 introCRC = CCrc32::ComputeLowercase("intro");
  49.                 const CTagDefinition* pFragTagDef = GetContext().controllerDef.GetFragmentTagDef(m_fragmentID);
  50.                 if (pFragTagDef)
  51.                 {
  52.                         const TagID fragTagID = pFragTagDef->Find(introCRC);
  53.                         if (fragTagID != TAG_ID_INVALID)
  54.                         {
  55.                                 pFragTagDef->Set(m_fragTags, fragTagID, true);
  56.                         }
  57.                 }
  58.         }
  59. }
  60.  
  61. // ----------------------------------------------------------------------------
  62. void CAnimActionTriState::Install()
  63. {
  64.         CRY_ASSERT(m_fragmentID != FRAGMENT_ID_INVALID);
  65.  
  66.         static uint32 introCRC = CCrc32::ComputeLowercase("intro");
  67.         if ((m_triStateFlags & eTSF_SkippedIntro) || !TrySetTransitionFragment(introCRC))
  68.         {
  69.                 m_triStateFlags |= eTSF_SkippedIntro;
  70.                 if (!TrySetTransitionFragment(0))
  71.                 {
  72.                         m_triStateFlags |= eTSF_SkipMiddle;
  73.                         // Note we could exit here in some way, but we still want all events to be sent so I'll just let it go through the regular Enter()->Exit() sequence
  74.                 }
  75.         }
  76.  
  77.         TBase::Install();
  78. }
  79.  
  80. // ----------------------------------------------------------------------------
  81.  
  82. void CAnimActionTriState::OnRequestBlendOut(EPriorityComparison priorityComp)
  83. {
  84.         /*      if (priorityComp == Equal)
  85.            {
  86.             CRY_ASSERT(m_eStatus == Installed);
  87.             CRY_ASSERT(m_subState != eSS_None);
  88.             CRY_ASSERT(m_subState != eSS_Exit);
  89.  
  90.             Stop();
  91.            }*/
  92. }
  93.  
  94. // ----------------------------------------------------------------------------
  95. void CAnimActionTriState::OnAnimationEvent(ICharacterInstance* pCharacter, const AnimEventInstance& event)
  96. {
  97.         CRY_ASSERT(m_eStatus == Installed);
  98.  
  99.         // Are we 100% sure that the animevent we receive here is part of the sequence of the fragment we set last?
  100.  
  101.         static uint32 animExitCRC32 = CCrc32::ComputeLowercase(ANIMEVENT_ANIMEXIT);
  102.         if (event.m_EventNameLowercaseCRC32 == animExitCRC32)
  103.         {
  104.                 TransitionToNextSubState();
  105.         }
  106. }
  107.  
  108. // ----------------------------------------------------------------------------
  109. IAction::EStatus CAnimActionTriState::Update(float timePassed)
  110. {
  111.         TBase::Update(timePassed);
  112.  
  113.         if (m_subState == eSS_Middle)
  114.         {
  115.                 const bool hasMaxMiddleDuration = m_maxMiddleDuration >= 0.0f;
  116.                 if (hasMaxMiddleDuration)
  117.                 {
  118.                         if (gEnv->pTimer->GetFrameStartTime() >= m_middleEndTime)
  119.                         {
  120.                                 Stop();
  121.                         }
  122.                 }
  123.         }
  124.         return m_eStatus;
  125. }
  126.  
  127. // ----------------------------------------------------------------------------
  128. void CAnimActionTriState::Enter()
  129. {
  130.         TBase::Enter();
  131.  
  132.         // --------------------------------------------------------------------------
  133.         // Movement Control Method
  134.  
  135.         const bool runningOnLayerZero = (m_rootScope->GetBaseLayer() == 0);
  136.         if (runningOnLayerZero)
  137.         {
  138.                 m_mcmHorizontalOld = m_animChar.GetMCMH();
  139.                 CRY_ASSERT(m_mcmHorizontalOld != eMCM_Undefined);
  140.                 m_mcmVerticalOld = m_animChar.GetMCMV();
  141.                 CRY_ASSERT(m_mcmVerticalOld != eMCM_Undefined);
  142.  
  143.                 m_animChar.SetMovementControlMethods(m_mcmHorizontal, m_mcmVertical);
  144.         }
  145.  
  146.         // --------------------------------------------------------------------------
  147.         // Collider Mode
  148.  
  149.         // TODO
  150.  
  151.         // --------------------------------------------------------------------------
  152.         // Target Location
  153.  
  154.         if (m_triStateFlags & eTSF_TargetLocation)
  155.         {
  156.                 SetParam("TargetPos", m_targetLocation);
  157.         }
  158.  
  159.         // --------------------------------------------------------------------------
  160.         // Send Events
  161.  
  162.         SendTriStateEvent(Enter);
  163.  
  164.         // --------------------------------------------------------------------------
  165.         // Send Events
  166.  
  167.         CRY_ASSERT(m_subState == eSS_None);
  168.  
  169.         m_subState = eSS_Intro;
  170.         SendTriStateEvent(Intro);
  171.  
  172.         if (m_triStateFlags & eTSF_SkippedIntro)
  173.         {
  174.                 TransitionToNextSubState();
  175.         }
  176.  
  177. #ifndef _RELEASE
  178.         m_entered = true;
  179. #endif
  180. }
  181.  
  182. // ----------------------------------------------------------------------------
  183. void CAnimActionTriState::Exit()
  184. {
  185. #ifndef _RELEASE
  186.         if (!m_entered)
  187.                 CryFatalError("CAnimActionTriState::Exit: Exit without Enter call");
  188. #endif
  189.  
  190.         TBase::Exit();
  191.  
  192.         // --------------------------------------------------------------------------
  193.         // Movement Control Method
  194.  
  195.         const bool runningOnLayerZero = (m_rootScope->GetBaseLayer() == 0);
  196.         if (runningOnLayerZero)
  197.         {
  198.                 CRY_ASSERT(m_mcmHorizontalOld != eMCM_Undefined);
  199.                 CRY_ASSERT(m_mcmVerticalOld != eMCM_Undefined);
  200.                 m_animChar.SetMovementControlMethods(m_mcmHorizontalOld, m_mcmVerticalOld);
  201.         }
  202.  
  203.         // --------------------------------------------------------------------------
  204.         // Collider Mode
  205.  
  206.         // TODO
  207.  
  208.         m_subState = eSS_Exit;
  209.         SendTriStateEvent(Exit);
  210. }
  211.  
  212. // ----------------------------------------------------------------------------
  213. void CAnimActionTriState::UnregisterListener()
  214. {
  215.         CRY_ASSERT(m_pListener);
  216.         m_pListener = NULL;
  217. }
  218.  
  219. // ----------------------------------------------------------------------------
  220. void CAnimActionTriState::InitTargetLocation(const QuatT& targetLocation)
  221. {
  222. #ifndef _RELEASE
  223.         CRY_ASSERT(!m_entered);
  224. #endif
  225.  
  226.         m_targetLocation = targetLocation;
  227.         m_triStateFlags |= eTSF_TargetLocation;
  228. }
  229.  
  230. // ----------------------------------------------------------------------------
  231. void CAnimActionTriState::ClearTargetLocation()
  232. {
  233. #ifndef _RELEASE
  234.         CRY_ASSERT(!m_entered);
  235. #endif
  236.  
  237.         m_triStateFlags &= ~eTSF_TargetLocation;
  238. }
  239.  
  240. // ----------------------------------------------------------------------------
  241. void CAnimActionTriState::InitMovementControlMethods(EMovementControlMethod mcmHorizontal, EMovementControlMethod mcmVertical)
  242. {
  243. #ifndef _RELEASE
  244.         CRY_ASSERT(!m_entered);
  245. #endif
  246.  
  247.         m_mcmHorizontal = (mcmHorizontal == eMCM_Undefined) ? DEFAULT_MCM_HORIZONTAL : mcmHorizontal;
  248.         m_mcmVertical = (mcmVertical == eMCM_Undefined) ? DEFAULT_MCM_VERTICAL : mcmVertical;
  249. }
  250.  
  251. // ----------------------------------------------------------------------------
  252. void CAnimActionTriState::OnSequenceFinished(int layer, uint32 scopeID)
  253. {
  254. #ifndef _RELEASE
  255.         CRY_ASSERT(m_entered);
  256. #endif
  257.  
  258.         if (layer != 0 || GetRootScope().GetID() != scopeID)
  259.         {
  260.                 return;
  261.         }
  262.  
  263.         TransitionToNextSubState();
  264. }
  265.  
  266. // ----------------------------------------------------------------------------
  267. bool CAnimActionTriState::TrySetTransitionFragment(uint32 fragTagCRC)
  268. {
  269.         const IScope& rootScope = GetRootScope();
  270.         const IAnimationDatabase& database = rootScope.GetDatabase();
  271.         const TagState globalTagState = GetContext().state.GetMask();
  272.  
  273.         TagState fragTags = TAG_STATE_EMPTY;
  274.         if (fragTagCRC)
  275.         {
  276.                 const CTagDefinition* pFragTagDef = GetContext().controllerDef.GetFragmentTagDef(m_fragmentID);
  277.                 if (!pFragTagDef)
  278.                 {
  279.                         return false;
  280.                 }
  281.  
  282.                 const TagID fragTagID = pFragTagDef->Find(fragTagCRC);
  283.                 if (fragTagID == TAG_ID_INVALID)
  284.                 {
  285.                         return false;
  286.                 }
  287.  
  288.                 pFragTagDef->Set(fragTags, fragTagID, true);
  289.         }
  290.  
  291.         const TagState scopeAdditionalTags = rootScope.GetAdditionalTags();
  292.         const TagState combinedGlobalTagState = GetContext().controllerDef.m_tags.GetUnion(globalTagState, scopeAdditionalTags);
  293.         const SFragTagState fragTagState(combinedGlobalTagState, fragTags);
  294.  
  295.         SFragTagState matchingTagState;
  296.         const uint32 optionCount = database.FindBestMatchingTag(SFragmentQuery(m_fragmentID, fragTagState), &matchingTagState);
  297.         if (optionCount == 0 || matchingTagState.fragmentTags != fragTagState.fragmentTags)
  298.         {
  299.                 return false;
  300.         }
  301.  
  302.         if (m_fragTags != fragTags)
  303.         {
  304.                 SetFragment(m_fragmentID, fragTags);
  305.         }
  306.  
  307.         return true;
  308. }
  309.  
  310. // ----------------------------------------------------------------------------
  311. void CAnimActionTriState::Stop()
  312. {
  313.         if ((GetStatus() == IAction::None) || (GetStatus() == IAction::Pending))
  314.         {
  315.                 assert(m_subState == eSS_None);
  316.                 TBase::Stop();
  317.         }
  318.         else
  319.         {
  320.                 if (m_subState < eSS_Middle)
  321.                 {
  322.                         m_triStateFlags |= eTSF_SkipMiddle;
  323.                 }
  324.                 else if (m_subState == eSS_Middle)
  325.                 {
  326.                         if (!IsOneShot())
  327.                                 TransitionToNextSubState();
  328.                 }
  329.         }
  330. }
  331.  
  332. // ----------------------------------------------------------------------------
  333. void CAnimActionTriState::TransitionToNextSubState()
  334. {
  335.         switch (m_subState)
  336.         {
  337.         case eSS_Intro:
  338.                 {
  339.                         if (!(m_triStateFlags & eTSF_SkipMiddle))
  340.                         {
  341.                                 if (!TrySetTransitionFragment(0))
  342.                                 {
  343.                                         m_triStateFlags |= eTSF_SkipMiddle;
  344.                                 }
  345.                         }
  346.  
  347.                         m_subState = eSS_Middle;
  348.                         m_middleEndTime = gEnv->pTimer->GetFrameStartTime() + CTimeValue(m_maxMiddleDuration);
  349.                         SendTriStateEvent(Middle);
  350.  
  351.                         if (!(m_triStateFlags & eTSF_SkipMiddle))
  352.                         {
  353.                                 break;
  354.                         }
  355.  
  356.                         // fall-through to Middle sequence finished
  357.                 }
  358.         case eSS_Middle:
  359.                 {
  360.                         static uint32 outroCRC = CCrc32::ComputeLowercase("outro");
  361.                         const bool hasOutro = TrySetTransitionFragment(outroCRC);
  362.                         m_flags &= ~IAction::NoAutoBlendOut;
  363.  
  364.                         m_subState = eSS_Outro;
  365.                         SendTriStateEvent(Outro);
  366.  
  367.                         if (hasOutro)
  368.                         {
  369.                                 break;
  370.                         }
  371.  
  372.                         // fall-through to Outro sequence finished
  373.                 }
  374.         case eSS_Outro:
  375.                 {
  376.                         SendTriStateEvent(OutroEnd);
  377.                         TBase::Stop();
  378.                         break;
  379.                 }
  380.         default:
  381.                 {
  382.                         CRY_ASSERT(false);
  383.                 }
  384.         }
  385. }
  386.  
downloadAnimActionTriState.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