BVB Source Codes

CRYENGINE Show MannequinAGState.cpp Source code

Return Download CRYENGINE: download MannequinAGState.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 "MannequinAGState.h"
  7. #include "CryAction.h"
  8. #include "AnimationGraph/AnimatedCharacter.h"
  9. #include "MannequinAGExistanceQuery.h"
  10.  
  11. // TODO: Go over all calls to AG_SEND_EVENT in AnimationGraphState
  12. // TODO: Check whether the Release() & dtor is always called, because animchar has a rather 'interesting' way of calling Release()
  13.  
  14. // ============================================================================
  15. // ============================================================================
  16.  
  17. namespace MannequinAG
  18. {
  19.  
  20. // ============================================================================
  21. // ============================================================================
  22.  
  23. #define AG_SEND_EVENT(func)                                                                                                                                       \
  24.   {                                                                                                                                                               \
  25.     m_callingListeners = m_listeners;                                                                                                                             \
  26.     for (std::vector<SListener>::reverse_iterator agSendEventIter = m_callingListeners.rbegin(); agSendEventIter != m_callingListeners.rend(); ++agSendEventIter) \
  27.       agSendEventIter->pListener->func;                                                                                                                           \
  28.   }
  29.  
  30. // ============================================================================
  31. // ============================================================================
  32.  
  33. TAnimationGraphQueryID CMannequinAGState::s_lastQueryID = TAnimationGraphQueryID(0);
  34.  
  35. // ============================================================================
  36. // ============================================================================
  37.  
  38. // ----------------------------------------------------------------------------
  39. CMannequinAGState::CMannequinAGState()
  40.         :
  41.         m_pauseState(0),
  42.         m_pAnimatedCharacter(NULL)
  43. {
  44.         for (size_t i = 0; i < eSIID_COUNT; i++)
  45.         {
  46.                 m_queryChangedInputIDs[i] = 0;
  47.         }
  48.  
  49.         ResetInputValues();
  50. }
  51.  
  52. // ----------------------------------------------------------------------------
  53. CMannequinAGState::~CMannequinAGState()
  54. {
  55.         AG_SEND_EVENT(DestroyedState(this));
  56.  
  57.         Reset();
  58. }
  59.  
  60. // ============================================================================
  61. // ============================================================================
  62.  
  63. // ----------------------------------------------------------------------------
  64. void CMannequinAGState::SetAnimatedCharacter(class CAnimatedCharacter* animatedCharacter, int layerIndex, IAnimationGraphState* parentLayerState)
  65. {
  66.         // TODO: What to do with the controller?
  67.  
  68.         m_pAnimatedCharacter = animatedCharacter;
  69. }
  70.  
  71. // ----------------------------------------------------------------------------
  72. bool CMannequinAGState::SetInput(InputID iid, const char* value, TAnimationGraphQueryID* pQueryID /*= 0 */)
  73. {
  74.         return SetInputInternal(iid, value, pQueryID, false);
  75. }
  76.  
  77. // ----------------------------------------------------------------------------
  78. bool CMannequinAGState::SetInputOptional(InputID iid, const char* value, TAnimationGraphQueryID* pQueryID /*= 0 */)
  79. {
  80.         return SetInputInternal(iid, value, pQueryID, true);
  81. }
  82.  
  83. // ----------------------------------------------------------------------------
  84. void CMannequinAGState::GetInput(InputID iid, char* value) const
  85. {
  86.         GetInput(iid, value, 0);
  87. }
  88.  
  89. // ----------------------------------------------------------------------------
  90. void CMannequinAGState::GetInput(InputID iid, char* value, int layerIndex) const
  91. {
  92.         value[0] = '\0';
  93.  
  94.         CRY_ASSERT(layerIndex == 0);
  95.         if (layerIndex != 0)
  96.                 return;
  97.  
  98.         switch (iid)
  99.         {
  100.         case eSIID_Action:
  101.                 strcpy(value, m_actionValue.c_str());
  102.                 break;
  103.         case eSIID_Signal:
  104.                 strcpy(value, m_signalValue.c_str());
  105.                 break;
  106.         default:
  107.                 break;
  108.         }
  109.         ;
  110. }
  111.  
  112. // ----------------------------------------------------------------------------
  113. bool CMannequinAGState::IsDefaultInputValue(InputID iid) const
  114. {
  115.         switch (iid)
  116.         {
  117.         case eSIID_Action:
  118.                 return (m_actionValue == "idle");
  119.         case eSIID_Signal:
  120.                 // Can be called from within CAnimationGraphStates when QueryComplete is called
  121.                 return (m_signalValue == "none");
  122.         default:
  123.                 return true;
  124.         }
  125.         ;
  126. }
  127.  
  128. // ----------------------------------------------------------------------------
  129. const char* CMannequinAGState::GetInputName(InputID iid) const
  130. {
  131.         // Only called from CAnimationGraphStates::RebindInputs
  132.         switch (iid)
  133.         {
  134.         case eSIID_Action:
  135.                 return "Action";
  136.         case eSIID_Signal:
  137.                 return "Signal";
  138.         default:
  139.                 return NULL;
  140.         }
  141.         ;
  142. }
  143.  
  144. // ----------------------------------------------------------------------------
  145. const char* CMannequinAGState::GetVariationInputName(InputID) const
  146. {
  147.         // Only called from CAnimationGraphStates::RebindInputs
  148.         return NULL;
  149. }
  150.  
  151. // ----------------------------------------------------------------------------
  152. // When QueryID of SetInput (reached queried state) is emitted this function is called by the outside, by convention(verify!).
  153. // Remember which layers supported the SetInput query and emit QueryLeaveState QueryComplete when all those layers have left those states.
  154. void CMannequinAGState::QueryLeaveState(TAnimationGraphQueryID* pQueryID)
  155. {
  156.         _smart_ptr<CAnimActionAGAction> pCallerAction = m_pCallerOfSendEvent;
  157.  
  158.         // If this was not called from within an action, which is not really supported by the AG
  159.         // we use some random heuristics to try to figure out which action to use as 'callerAction'
  160.         if (!pCallerAction)
  161.         {
  162.                 if (m_pOneShotAction && m_pOneShotAction->IsPendingOrInstalled())
  163.                 {
  164.                         pCallerAction = m_pOneShotAction;
  165.                 }
  166.                 else if (m_pLoopingAction && m_pLoopingAction->IsPendingOrInstalled())
  167.                 {
  168.                         pCallerAction = m_pLoopingAction;
  169.                 }
  170.         }
  171.  
  172.         *pQueryID = GenerateQueryID();
  173.  
  174.         if (!pCallerAction)
  175.         {
  176.                 CRY_ASSERT(false);
  177.                 // I considered sending the event here, but as the AG didn't call this event
  178.                 // directly, I cannot assume the calling code is written in a way that can
  179.                 // safely handle this case.
  180.                 // AG_SEND_EVENT(QueryComplete(*pQueryID, false));
  181.         }
  182.         else
  183.         {
  184.                 pCallerAction->AddLeaveQueryID(*pQueryID);
  185.         }
  186. }
  187.  
  188. // ----------------------------------------------------------------------------
  189. // assert all equal, forward to all layers, complete when all have changed once (trivial, since all change at once via SetInput).
  190. // (except for signalled, forward only to layers which currently are not default, complete when all those have changed).
  191. void CMannequinAGState::QueryChangeInput(InputID iid, TAnimationGraphQueryID* pQuery)
  192. {
  193.         CRY_ASSERT(pQuery);
  194.         *pQuery = 0;
  195.         if (iid >= eSIID_COUNT)
  196.                 return;
  197.         m_queryChangedInputIDs[iid] = *pQuery = GenerateQueryID();
  198. }
  199.  
  200. // ----------------------------------------------------------------------------
  201. void CMannequinAGState::AddListener(const char* name, IAnimationGraphStateListener* pListener)
  202. {
  203.         SListener listener;
  204.         cry_strcpy(listener.name, name);
  205.         listener.pListener = pListener;
  206.         stl::push_back_unique(m_listeners, listener);
  207. }
  208.  
  209. // ----------------------------------------------------------------------------
  210. void CMannequinAGState::RemoveListener(IAnimationGraphStateListener* pListener)
  211. {
  212.         SListener listener;
  213.         listener.name[0] = 0;
  214.         listener.pListener = pListener;
  215.         stl::find_and_erase(m_listeners, listener);
  216. }
  217.  
  218. // ----------------------------------------------------------------------------
  219. void CMannequinAGState::Release()
  220. {
  221.         delete this;
  222. }
  223.  
  224. // ----------------------------------------------------------------------------
  225. void CMannequinAGState::ForceTeleportToQueriedState()
  226. {
  227.         Hurry();
  228. }
  229.  
  230. // ----------------------------------------------------------------------------
  231. AnimationGraphInputID CMannequinAGState::GetInputId(const char* input)
  232. {
  233.         if (0 == strcmp(input, "Action"))
  234.                 return eSIID_Action;
  235.         else if (0 == strcmp(input, "Signal"))
  236.                 return eSIID_Signal;
  237.         else
  238.         {
  239.                 CRY_ASSERT(false);
  240.                 return InputID(-1);
  241.         }
  242. }
  243.  
  244. // ----------------------------------------------------------------------------
  245. AnimationGraphInputID CMannequinAGState::GetVariationInputId(const char* variationInputName) const
  246. {
  247.         CRY_ASSERT(false);
  248.         return InputID(-1);
  249. }
  250.  
  251. // ----------------------------------------------------------------------------
  252. void CMannequinAGState::Serialize(TSerialize ser)
  253. {
  254.         // TODO: Serialize?  What about our back-pointers?
  255.  
  256.         if (ser.GetSerializationTarget() == eST_SaveGame)
  257.         {
  258.                 if (ser.IsReading())
  259.                         Reset();
  260.  
  261.                 //ser.Value("action", m_actionValue);
  262.                 //ser.Value("signal", m_signalValue);
  263.  
  264.                 // TODO: Start actions based on the serialized value?  Or just not serialize at all?
  265.         }
  266. }
  267.  
  268. // ----------------------------------------------------------------------------
  269. const char* CMannequinAGState::GetCurrentStateName()
  270. {
  271.         const char* result = "<unknown>";
  272.  
  273.         // Figure out something which could pose as a 'state name'
  274.         // Currently it's the name of the first fragmentID I can find on the scopes
  275.         IActionController* pActionController = GetActionController();
  276.         if (!pActionController)
  277.                 return result;
  278.  
  279.         for (int scopeIndex = 0; scopeIndex < pActionController->GetTotalScopes(); ++scopeIndex)
  280.         {
  281.                 IScope* pScope = pActionController->GetScope(scopeIndex);
  282.                 FragmentID fragmentID = pScope->GetLastFragmentID();
  283.                 if (fragmentID != FRAGMENT_ID_INVALID)
  284.                 {
  285.                         result = pActionController->GetContext().controllerDef.m_fragmentIDs.GetTagName(fragmentID);
  286.                         break;
  287.                 }
  288.         }
  289.  
  290.         return result;
  291. }
  292.  
  293. // ----------------------------------------------------------------------------
  294. void CMannequinAGState::Pause(bool pause, EAnimationGraphPauser pauser, float fOverrideTransTime /*= -1.0f */)
  295. {
  296.         bool bWasPaused = IsPaused();
  297.  
  298.         if (pause)
  299.                 m_pauseState |= (1 << pauser);
  300.         else
  301.                 m_pauseState &= ~(1 << pauser);
  302.  
  303.         if (bWasPaused != IsPaused())
  304.         {
  305.                 // TODO: do something here?
  306.         }
  307. }
  308.  
  309. // ----------------------------------------------------------------------------
  310. IAnimationGraphExistanceQuery* CMannequinAGState::CreateExistanceQuery()
  311. {
  312.         return new CMannequinAGExistanceQuery(this);
  313. }
  314.  
  315. // ----------------------------------------------------------------------------
  316. IAnimationGraphExistanceQuery* CMannequinAGState::CreateExistanceQuery(int layer)
  317. {
  318.         CRY_ASSERT(layer == 0);
  319.         if (layer != 0)
  320.                 return NULL;
  321.  
  322.         return CreateExistanceQuery();
  323. }
  324.  
  325. // ----------------------------------------------------------------------------
  326. void CMannequinAGState::Reset()
  327. {
  328.         // TODO: what exactly do we want to 'reset'?
  329.         //   This is called from the outside AND from within our destructor
  330.         //m_pLoopingAction = NULL;
  331.         //m_pOneShotAction = NULL;
  332.  
  333.         ResetInputValues(); // TODO: don't call from dtor?
  334. }
  335.  
  336. // ----------------------------------------------------------------------------
  337. void CMannequinAGState::Hurry()
  338. {
  339.         // first check whether we have anything that is still pending, if not, we have nothing to hurry
  340.         const bool oneShotActionIsPending = (m_pOneShotAction && (m_pOneShotAction->GetStatus() == IAction::Pending));
  341.         const bool loopingActionIsPending = (m_pLoopingAction && (m_pLoopingAction->GetStatus() == IAction::Pending));
  342.  
  343.         if (!oneShotActionIsPending && !loopingActionIsPending)
  344.                 return;
  345.  
  346.         IActionController* pActionController = GetActionController();
  347.         if (!pActionController)
  348.                 return;
  349.  
  350.         // TODO: How do we mimic Hurry?  Somehow we need to, in a clean way, end all actions on all scopes
  351.         //   (without screwing up the pending ones, properly moving interruptable ones to the queue,
  352.         //    calling Exit() when needed, etc)
  353. }
  354.  
  355. // ----------------------------------------------------------------------------
  356. void CMannequinAGState::GetMemoryUsage(ICrySizer* s) const
  357. {
  358.         s->Add(*this);
  359.         s->AddObject(m_listeners);
  360.         s->AddObject(m_callingListeners);
  361. }
  362.  
  363. // ----------------------------------------------------------------------------
  364. bool CMannequinAGState::IsSignalledInput(InputID iid) const
  365. {
  366.         return (iid == eSIID_Signal);
  367. }
  368.  
  369. // ============================================================================
  370. // ============================================================================
  371.  
  372. // ----------------------------------------------------------------------------
  373. bool CMannequinAGState::SetInputInternal(InputID iid, const char* value, TAnimationGraphQueryID* pQueryID, bool optional)
  374. {
  375.         switch (iid)
  376.         {
  377.         case eSIID_Action:
  378.                 {
  379.                         static const uint32 idleCRC = CCrc32::ComputeLowercase("idle");
  380.                         return SetActionOrSignalInput(m_pLoopingAction, m_actionValue, iid, EAT_Looping, "idle", idleCRC, value, pQueryID, optional);
  381.                 }
  382.         case eSIID_Signal:
  383.                 {
  384.                         static const uint32 noneCRC = CCrc32::ComputeLowercase("none");
  385.                         return SetActionOrSignalInput(m_pOneShotAction, m_signalValue, iid, EAT_OneShot, "none", noneCRC, value, pQueryID, optional);
  386.                 }
  387.         case InputID(-1):
  388.                 {
  389.                         return false;
  390.                 }
  391.         default:
  392.                 {
  393.                         CRY_ASSERT(false); // trying to set input with non-existing input id
  394.                         return false;
  395.                 }
  396.         }
  397.         ;
  398. }
  399.  
  400. // ----------------------------------------------------------------------------
  401. bool CMannequinAGState::SetActionOrSignalInput(_smart_ptr<CAnimActionAGAction>& pAction, TKeyValue& currentValue, InputID inputID, EAIActionType actionType, const char* defaultValue, uint32 defaultValueCRC, const char* value, TAnimationGraphQueryID* pQueryID, bool optional)
  402. {
  403.         IActionController* pActionController = GetActionController();
  404.         if (!pActionController)
  405.                 return false;
  406.  
  407.         // TODO Where to get the priorities from?
  408.         const int MANNEQUIN_PRIORITY = 2; // currently equal to PP_Action, just above movement, but underneath urgent actions, hit death, etc.
  409.  
  410.         TAnimationGraphQueryID queryID = 0;
  411.         if (pQueryID)
  412.                 queryID = *pQueryID = GenerateQueryID();
  413.  
  414.         const uint32 valueCRC = CCrc32::ComputeLowercase(value);
  415.  
  416.         static uint32 idleCRC = CCrc32::ComputeLowercase("idle");
  417.         static uint32 noneCRC = CCrc32::ComputeLowercase("none");
  418.         const bool isUnsupportedFragmentID = ((valueCRC == idleCRC) || (valueCRC == noneCRC));
  419.         const FragmentID fragmentID = isUnsupportedFragmentID ? FRAGMENT_ID_INVALID : pActionController->GetContext().controllerDef.m_fragmentIDs.Find(valueCRC);
  420.  
  421.         const bool isDefaultValue = (valueCRC == defaultValueCRC);
  422.  
  423.         const bool somethingIsPendingOrInstalled = pAction && pAction->IsPendingOrInstalled();
  424.  
  425.         if (isDefaultValue)
  426.         {
  427.                 if (actionType == EAT_Looping)
  428.                 {
  429.                         StopAnyLoopingExactPositioningAction();
  430.                 }
  431.  
  432.                 const bool isPendingOrInstalled = !somethingIsPendingOrInstalled; // the fake action 'idle' isPendingOrInstalled if something else is NOT pending or installed
  433.                 if (isPendingOrInstalled)
  434.                 {
  435.                         // In the old sense: the current requested 'value' did not change, we were already 'idle'
  436.                         SendEvent_Entered(NULL, queryID, true);
  437.                 }
  438.                 else
  439.                 {
  440.                         currentValue = defaultValue;
  441.  
  442.                         if (pAction)
  443.                         {
  444.                                 pAction->Stop(); // this will eventually call Entered(..,false) of the user that was waiting on Entered()
  445.                                 pAction = NULL;
  446.                         }
  447.  
  448.                         // TODO: This is not entirely correct. The Entered() event for the idle action should only
  449.                         //   be called when you exactly "go back to idle". But this is not well defined in mannequin,
  450.                         //   so I just send it right away...
  451.                         SendEvent_Entered(NULL, queryID, true);
  452.  
  453.                         SendEvent_ChangedInput(inputID, true); // tell whoever is listening to the input that it changed
  454.                 }
  455.  
  456.                 return true;
  457.         }
  458.         else if (fragmentID != FRAGMENT_ID_INVALID)
  459.         {
  460.                 const bool isPendingOrInstalled =
  461.                   somethingIsPendingOrInstalled &&
  462.                   (pAction->GetValueCRC() == valueCRC);
  463.                 if (isPendingOrInstalled)
  464.                 {
  465.                         // In the old sense: the current requested 'value' did not change
  466.  
  467.                         // reuse the old queryid, if there is one, otherwise set the new one
  468.                         if (pAction->GetQueryID())
  469.                         {
  470.                                 queryID = pAction->GetQueryID();
  471.                                 if (pQueryID)
  472.                                         *pQueryID = queryID;
  473.                         }
  474.                         else
  475.                         {
  476.                                 if (queryID)
  477.                                         pAction->SetQueryID(queryID);
  478.                         }
  479.  
  480.                         if (pAction->GetStatus() == IAction::Installed)
  481.                         {
  482.                                 // The other system is already playing the same action.
  483.                                 // Send the 'entered' event immediately
  484.                                 // (afai can see the AG only did this for signals for some reason??)
  485.                                 SendEvent_Entered(pAction, pAction->GetQueryID(), true);
  486.                         }
  487.                 }
  488.                 else
  489.                 {
  490.                         currentValue = value;
  491.  
  492.                         pAction = new CAnimActionAGAction(MANNEQUIN_PRIORITY, fragmentID, *this, actionType, value, valueCRC, queryID);
  493.                         pActionController->Queue(*pAction.get());
  494.  
  495.                         SendEvent_ChangedInput(inputID, true); // tell whoever is listening the input that it changed
  496.                 }
  497.  
  498.                 return true;
  499.         }
  500.         else if (!optional)
  501.         {
  502.                 // 'not optional' means invalid values get translated into the default value
  503.                 // (so we always set a value, hence the setting of values is 'not optional')
  504.                 // Recurse and pass the defaultValue as value:
  505.                 return SetActionOrSignalInput(pAction, currentValue, inputID, actionType, defaultValue, defaultValueCRC, defaultValue, NULL, true);
  506.         }
  507.         else
  508.         {
  509. #ifndef _RELEASE
  510.                 if (!isUnsupportedFragmentID)
  511.                 {
  512.                         CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "CMannequinAGState::SetInput: Unable to find animation '%s'", value);
  513.                 }
  514. #endif //#ifndef _RELEASE
  515.                 return false;
  516.         }
  517. }
  518.  
  519. // ----------------------------------------------------------------------------
  520. void CMannequinAGState::SendEvent_ChangedInput(InputID iid, bool success)
  521. {
  522.         TAnimationGraphQueryID temp = m_queryChangedInputIDs[iid];
  523.         if (temp)
  524.         {
  525.                 m_queryChangedInputIDs[iid] = 0;
  526.                 AG_SEND_EVENT(QueryComplete(temp, success));
  527.         }
  528. }
  529.  
  530. // ----------------------------------------------------------------------------
  531. void CMannequinAGState::SendEvent_Entered(_smart_ptr<CAnimActionAGAction> pCaller, TAnimationGraphQueryID queryID, bool success)
  532. {
  533.         CRY_ASSERT(m_pCallerOfSendEvent == NULL); // paranoia: check for weird re-entry case
  534.         if (m_pCallerOfSendEvent != NULL)
  535.                 return;
  536.  
  537.         if (!queryID)
  538.                 return;
  539.  
  540.         m_pCallerOfSendEvent = pCaller;
  541.  
  542.         AG_SEND_EVENT(QueryComplete(queryID, success))
  543.  
  544.         m_pCallerOfSendEvent = NULL;
  545. }
  546.  
  547. // ----------------------------------------------------------------------------
  548. void CMannequinAGState::SendEvent_Left(TAnimationGraphQueryID queryID, bool success)
  549. {
  550.         if (!queryID)
  551.                 return;
  552.  
  553.         AG_SEND_EVENT(QueryComplete(queryID, success))
  554. }
  555.  
  556. // ----------------------------------------------------------------------------
  557. void CMannequinAGState::ResetInputValues()
  558. {
  559.         m_actionValue = "idle";
  560.         m_signalValue = "none";
  561.  
  562.         for (size_t i = 0; i < eSIID_COUNT; i++)
  563.         {
  564.                 SendEvent_ChangedInput(static_cast<MannequinAG::CMannequinAGState::InputID>(i), false);
  565.         }
  566.  
  567.         // TODO: Did the actioncontroller send the proper Enter/Exit events?
  568. }
  569.  
  570. // ----------------------------------------------------------------------------
  571. IActionController* CMannequinAGState::GetActionController()
  572. {
  573.         if (!m_pAnimatedCharacter)
  574.                 return NULL;
  575.  
  576.         return m_pAnimatedCharacter->GetActionController();
  577. }
  578.  
  579. // ----------------------------------------------------------------------------
  580. void CMannequinAGState::StopAnyLoopingExactPositioningAction()
  581. {
  582.         //if ( m_pExactPositioning.get() )
  583.         //{
  584.         //      m_pExactPositioning->StopAnyLoopingExactPositioningAction();
  585.         //}
  586.         // TODO!!!!
  587. }
  588.  
  589. // ----------------------------------------------------------------------------
  590. void CMannequinAGState::OnReload()
  591. {
  592.  
  593. }
  594.  
  595. // ============================================================================
  596. // ============================================================================
  597.  
  598. // ----------------------------------------------------------------------------
  599. CAnimActionAGAction::CAnimActionAGAction(int priority, FragmentID fragmentID, CMannequinAGState& mannequinAGState, EAIActionType type, const string& value, uint32 valueCRC, TAnimationGraphQueryID queryID, bool skipIntro)
  600.         : TBase(priority, fragmentID, *mannequinAGState.m_pAnimatedCharacter, skipIntro)
  601.         , m_type(type)
  602.         , m_value(value)
  603.         , m_valueCRC(valueCRC)
  604.         , m_queryID(queryID)
  605.         , m_mannequinAGState(mannequinAGState)
  606. {
  607.         InitMovementControlMethods(eMCM_AnimationHCollision, eMCM_Entity);
  608. }
  609.  
  610. // ----------------------------------------------------------------------------
  611. void CAnimActionAGAction::OnEnter()
  612. {
  613.         m_mannequinAGState.SendEvent_Entered(this, m_queryID, true);
  614.         m_queryID = 0;
  615. }
  616.  
  617. // ----------------------------------------------------------------------------
  618. void CAnimActionAGAction::OnExit()
  619. {
  620.         for (int i = 0; i < m_leaveQueryIDs.size(); ++i)
  621.         {
  622.                 m_mannequinAGState.SendEvent_Left(m_leaveQueryIDs[i], true);
  623.                 m_leaveQueryIDs[i] = 0;
  624.         }
  625. }
  626.  
  627. // ----------------------------------------------------------------------------
  628. void CAnimActionAGAction::AddLeaveQueryID(TAnimationGraphQueryID leaveQueryID)
  629. {
  630.         if (m_leaveQueryIDs.isfull())
  631.         {
  632.                 CRY_ASSERT(false);
  633.                 return;
  634.         }
  635.  
  636.         m_leaveQueryIDs.push_back(leaveQueryID);
  637. }
  638.  
  639. // ============================================================================
  640. // ============================================================================
  641.  
  642. } // MannequinAG
  643.  
downloadMannequinAGState.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