BVB Source Codes

CRYENGINE Show CooperativeAnimation.cpp Source code

Return Download CRYENGINE: download CooperativeAnimation.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4.    -------------------------------------------------------------------------
  5.    $Id$
  6.    $DateTime$
  7.    Description: synchronized animation playing on multiple actors
  8.    including exact positioning and sliding the actors into position
  9.    -------------------------------------------------------------------------
  10.    History:
  11.    - August 5th, 2008: Created by Michelle Martin
  12.    - February 5th, 2009: Moved to CryAction by David Ramos
  13. *************************************************************************/
  14.  
  15. #include "StdAfx.h"
  16. #include "CooperativeAnimation.h"
  17. #include "CooperativeAnimationManager.h"
  18. #include "CryActionCVars.h"
  19. #include "IAnimatedCharacter.h"
  20. #include <CryGame/IGameFramework.h>
  21.  
  22. const static char* COOP_ANIM_NAME = "CoopAnimation";
  23. const static int MY_ANIM = 54545;
  24.  
  25. CCooperativeAnimation::CCooperativeAnimation()
  26.         : m_isInitialized(false)
  27.         , m_bPauseAG(false)
  28.         , m_activeState(eCS_PlayAndSlide)
  29.         , m_refPoint(ZERO)
  30.         , m_generalParams()
  31.         , m_firstActorStartPosition(ZERO)
  32.         , m_firstActorStartDirection(ZERO)
  33.         , m_firstActorTargetPosition(ZERO)
  34.         , m_firstActorTargetDirection(ZERO)
  35.         , m_firstActorPushedDistance(0.0f)
  36. {}
  37.  
  38. CCooperativeAnimation::~CCooperativeAnimation()
  39. {
  40.         //Remove any remaining entity listeners
  41.         TCharacterParams::const_iterator itParamsEnd = m_paramsList.end();
  42.         for (TCharacterParams::const_iterator itParams = m_paramsList.begin(); itParams != itParamsEnd; ++itParams)
  43.         {
  44.                 IAnimatedCharacter* pAnimatedChar = itParams->pActor;
  45.                 if (pAnimatedChar)
  46.                 {
  47.                         gEnv->pEntitySystem->RemoveEntityEventListener(pAnimatedChar->GetEntityId(), ENTITY_EVENT_DONE, this);
  48.                 }
  49.         }
  50.  
  51.         if (m_activeState != eCS_ForceStopping)
  52.         {
  53.                 // Delete the params from the vector
  54.                 TCharacterParams::iterator it = m_paramsList.begin();
  55.                 TCharacterParams::iterator iend = m_paramsList.end();
  56.  
  57.                 for (; it != iend; ++it)
  58.                 {
  59.                         if (!(*it).bAnimationPlaying)
  60.                                 CleanupForFinishedCharacter((*it));
  61.                 }
  62.         }
  63.  
  64.         m_paramsList.clear();
  65. }
  66.  
  67. bool CCooperativeAnimation::IsUsingActor(const EntityId entID) const
  68. {
  69.         if (!m_isInitialized)
  70.                 return false;
  71.  
  72.         if (m_activeState == eCS_ForceStopping)
  73.                 return false;
  74.  
  75.         // Return true if the actor is in one of the params (and still needed)
  76.         TCharacterParams::const_iterator it = m_paramsList.begin();
  77.         TCharacterParams::const_iterator iend = m_paramsList.end();
  78.  
  79.         for (; it != iend; ++it)
  80.         {
  81.                 // Check if this character is used AND if he is actually still
  82.                 // playing the animation (if he has finished, the character isn't needed anymore) AND
  83.                 // not being rough aligned or sliding (bAnimationPlaying is FALSE then, but you're
  84.                 // using the actor)
  85.                 if ((*it).pActor->GetEntityId() == entID &&
  86.                     ((*it).bAnimationPlaying || (m_activeState == eCS_PlayAndSlide)))
  87.                         return true;
  88.         }
  89.  
  90.         return false;
  91. }
  92.  
  93. bool CCooperativeAnimation::AreActorsAlive()
  94. {
  95.         if (!m_isInitialized)
  96.                 return false;
  97.  
  98.         // Return true if all actors have health above zero
  99.         TCharacterParams::iterator it = m_paramsList.begin();
  100.         TCharacterParams::iterator iend = m_paramsList.end();
  101.  
  102.         for (; it != iend; ++it)
  103.         {
  104.                 IActor* pActor = gEnv->pGameFramework->GetIActorSystem()->GetActor(it->pActor->GetEntityId());
  105.                 CRY_ASSERT(pActor);
  106.                 if (pActor)
  107.                 {
  108.                         if (pActor->IsDead())
  109.                                 return false;
  110.                 }
  111.         }
  112.  
  113.         return true;
  114. }
  115.  
  116. bool CCooperativeAnimation::AreActorsValid() const
  117. {
  118.         if (!m_isInitialized)
  119.                 return false;
  120.  
  121.         TCharacterParams::const_iterator itEnd = m_paramsList.end();
  122.         TCharacterParams::const_iterator it = std::find_if(m_paramsList.begin(), itEnd,
  123.                                                            std::not1(std::mem_fun_ref(&SCharacterParams::IsActorValid)));
  124.  
  125.         return (it == itEnd);
  126. }
  127.  
  128. bool CCooperativeAnimation::Update(float dt)
  129. {
  130.         if (!m_isInitialized)
  131.                 return false;
  132.  
  133.         if (!AreActorsValid())
  134.         {
  135.                 Stop();
  136.                 return false;
  137.         }
  138.  
  139.         if (!m_generalParams.bIgnoreCharacterDeath && !AreActorsAlive())
  140.         {
  141.                 Stop();
  142.                 return false;
  143.         }
  144.  
  145.         switch (m_activeState)
  146.         {
  147.         case eCS_PlayAndSlide:
  148.                 {
  149.                         bool bAnimFailure, bAllStarted, bAllDone;
  150.                         PlayAndSlideCharacters(dt, bAnimFailure, bAllStarted, bAllDone);
  151.  
  152.                         if (bAnimFailure)
  153.                         {
  154.                                 Stop();
  155.                                 return false;
  156.                         }
  157.  
  158.                         if (!bAllStarted)
  159.                                 break;
  160.  
  161.                         if (bAllDone)
  162.                                 m_activeState = eCS_WaitForAnimationFinish;
  163.                 }
  164.  
  165.         // no break, so the next case gets executed as well
  166.         case eCS_WaitForAnimationFinish:
  167.                 if (AnimationsFinished())
  168.                 {
  169.                         return false;
  170.                 }
  171.                 break;
  172.  
  173.         case eCS_ForceStopping:
  174.                 return false;
  175.                 break;
  176.         }
  177.         ;
  178.  
  179.         // DEBUG OUTPUT
  180.         if (CCryActionCVars::Get().co_coopAnimDebug)
  181.         {
  182.                 IRenderAuxGeom* pRenderAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
  183.                 pRenderAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);
  184.  
  185.                 // the debug output is different depending on the alignment type
  186.                 if (m_generalParams.eAlignment == eAF_FirstActorPosition)
  187.                 {
  188.                         // draw start position
  189.                         pRenderAuxGeom->DrawSphere(m_firstActorStartPosition, 0.1f, ColorB(255, 0, 255));
  190.                         // draw start direction
  191.                         pRenderAuxGeom->DrawLine(m_firstActorStartPosition + Vec3(0, 0, 0.2f), ColorB(255, 0, 255), m_firstActorStartPosition + m_firstActorStartDirection + Vec3(0, 0, 0.2f), ColorB(255, 0, 255));
  192.                         // draw target position
  193.                         pRenderAuxGeom->DrawSphere(m_firstActorTargetPosition, 0.1f, ColorB(255, 0, 255));
  194.                         // draw target direction
  195.                         pRenderAuxGeom->DrawLine(m_firstActorTargetPosition + Vec3(0, 0, 0.2f), ColorB(0, 255, 0), m_firstActorTargetPosition + m_firstActorTargetDirection + Vec3(0, 0, 0.2f), ColorB(0, 255, 0));
  196.  
  197.                         // draw the pushed distance
  198.                         Vec3 pushDirection = (m_firstActorTargetPosition - m_firstActorStartPosition).GetNormalized();
  199.                         pRenderAuxGeom->DrawLine(m_firstActorStartPosition + Vec3(0, 0, 0.05f), ColorB(255, 255, 0), m_firstActorStartPosition + Vec3(0, 0, 0.05f) + pushDirection * m_firstActorPushedDistance, ColorB(255, 255, 0));
  200.                 }
  201.                 else
  202.                 {
  203.                         // Draw reference point
  204.                         pRenderAuxGeom->DrawSphere(m_refPoint.t, 0.2f, ColorB(255, 0, 0));
  205.  
  206.                         // Draw targets and current entity pos
  207.                         TCharacterParams::const_iterator itEnd = m_paramsList.end();
  208.                         for (TCharacterParams::const_iterator it = m_paramsList.begin(); it != itEnd; ++it)
  209.                         {
  210.                                 // Target
  211.                                 pRenderAuxGeom->DrawSphere(it->qTarget.t, 0.2f, ColorB(255, 0, 255));
  212.  
  213.                                 // Pos
  214.                                 pRenderAuxGeom->DrawSphere(it->pActor->GetEntity()->GetWorldPos(), 0.2f, ColorB(0, 0, 255));
  215.                         }
  216.                 }
  217.         } // end of DEBUG OUTPUT
  218.  
  219.         return true;
  220. }
  221.  
  222. void CCooperativeAnimation::Stop()
  223. {
  224.         m_activeState = eCS_ForceStopping;
  225.  
  226.         TCharacterParams::iterator it = m_paramsList.begin();
  227.         TCharacterParams::iterator iend = m_paramsList.end();
  228.  
  229.         for (; it != iend; ++it)
  230.         {
  231.                 // Don't check if the animation is currently playing, because we want
  232.                 // to clean up the current animations to make way for the next ones
  233.                 CleanupForFinishedCharacter((*it));
  234.         }
  235. }
  236.  
  237. int MovementCallback(ICharacterInstance* pCharacter, void* pEntity)
  238. {
  239.         IEntity* pEnt = static_cast<IEntity*>(pEntity);
  240.         ISkeletonAnim* pISkeletonAnim = pEnt->GetCharacter(0)->GetISkeletonAnim();
  241.  
  242.         // this is the kinematic update
  243.         const QuatT& relmove = pISkeletonAnim->GetRelMovement();
  244.  
  245.         QuatT chrLoc;
  246.         chrLoc.q = pEnt->GetWorldRotation();
  247.         chrLoc.t = pEnt->GetWorldPos();
  248.         chrLoc = chrLoc * relmove;
  249.         chrLoc.q.NormalizeSafe();
  250.  
  251.         pEnt->SetWorldTM(Matrix34(chrLoc));
  252.  
  253.         // Vec3 dir = chrLoc.q * FORWARD_DIRECTION; <- ??
  254.  
  255.         return 0;
  256. }
  257.  
  258. bool CCooperativeAnimation::Init(TCharacterParams& characterParams, const SCooperativeAnimParams& generalParams)
  259. {
  260.         if (m_isInitialized)
  261.                 return true;
  262.  
  263.         m_paramsList = characterParams;
  264.         m_generalParams = generalParams;
  265.  
  266.         m_bPauseAG = generalParams.bLooping || (CCryActionCVars::Get().co_usenewcoopanimsystem != 0); // false will use an old AG based method which needs special setup in each character's AG
  267.  
  268.         // sanity check parameters
  269.         TCharacterParams::iterator it = m_paramsList.begin();
  270.         TCharacterParams::iterator iend = m_paramsList.end();
  271.         for (; it != iend; ++it)
  272.         {
  273.                 SCharacterParams& chrParams = *it;
  274.  
  275.                 if (!chrParams.IsActorValid())
  276.                 {
  277.                         CryLogAlways("Cooperative Animation Manager was passed an invalid actor");
  278.                         return false;
  279.                 }
  280.  
  281.                 if (chrParams.sSignalName == "")
  282.                 {
  283.                         CryLogAlways("Cooperative Animation Manager was not passed a correct signal name");
  284.                         return false;
  285.                 }
  286.  
  287.                 if (m_bPauseAG)
  288.                 {
  289.                         IAnimatedCharacter* pAnimChar = chrParams.pActor;
  290.                         CRY_ASSERT(pAnimChar && pAnimChar->GetEntity());
  291.  
  292.                         ICharacterInstance* pICharacter = pAnimChar->GetEntity()->GetCharacter(0);
  293.                         CRY_ASSERT(pICharacter);
  294.  
  295.                         IAnimationSet* pAnimSet = pICharacter->GetIAnimationSet();
  296.                         const int animId = pAnimSet->GetAnimIDByName(chrParams.sSignalName.c_str());
  297.                         if (animId < 0)
  298.                         {
  299.                                 GameWarning("Cooperative Animation Manager was passed a non-existing anim (%s) for actor %s", chrParams.sSignalName.c_str(), chrParams.pActor->GetEntity()->GetName());
  300.                                 return false;
  301.                         }
  302.  
  303.                         // Cache FilePathCRC of this anim for efficient streaming queries
  304.                         chrParams.animFilepathCRC = pAnimSet->GetFilePathCRCByAnimID(animId);
  305.                         CRY_ASSERT(chrParams.animFilepathCRC != 0);
  306.                 }
  307.         }
  308.  
  309.         // Calculate the reference point and calculate the target
  310.         // position and orientation of every character relative to this.
  311.         DetermineReferencePositionAndCalculateTargets();
  312.  
  313.         if (CCryActionCVars::Get().co_slideWhileStreaming)
  314.         {
  315.                 // Gather the location offset information before the animation moves the character
  316.                 it = m_paramsList.begin();
  317.                 for (; it != iend; ++it)
  318.                 {
  319.                         SCharacterParams& params = *it;
  320.                         GatherSlidingInformation(params);
  321.                 }
  322.         }
  323.  
  324.         //update the passed in params so the instigating code can get information about target positions etc.
  325.         characterParams = m_paramsList;
  326.  
  327.         // After all parameters are checked,
  328.         // determine the type of needed character alignment
  329.         m_activeState = eCS_PlayAndSlide;
  330.  
  331.         //Register to listen to the entities involved - if one gets deleted we want to NULL the pActor pointer
  332.         TCharacterParams::const_iterator itParamsEnd = characterParams.end();
  333.         for (TCharacterParams::const_iterator itParams = characterParams.begin(); itParams != itParamsEnd; ++itParams)
  334.         {
  335.                 gEnv->pEntitySystem->AddEntityEventListener(itParams->pActor->GetEntityId(), ENTITY_EVENT_DONE, this);
  336.         }
  337.  
  338.         m_isInitialized = true;
  339.         return true;
  340. }
  341.  
  342. bool CCooperativeAnimation::Init(SCharacterParams& params1, SCharacterParams& params2, const SCooperativeAnimParams& generalParams)
  343. {
  344.         TCharacterParams characterParams;
  345.         characterParams.push_back(params1);
  346.         characterParams.push_back(params2);
  347.  
  348.         return Init(characterParams, generalParams);
  349. }
  350.  
  351. bool CCooperativeAnimation::InitForOne(const SCharacterParams& params, const SCooperativeAnimParams& generalParams)
  352. {
  353.         if (m_isInitialized)
  354.                 return true;
  355.  
  356.         TCharacterParams::iterator it = m_paramsList.push_back(params);
  357.         m_generalParams = generalParams;
  358.         m_bPauseAG = generalParams.bLooping || (CCryActionCVars::Get().co_usenewcoopanimsystem != 0); // false will use an old AG based method which needs special setup in each character's AG
  359.  
  360.         // sanity check parameters
  361.         if (!params.IsActorValid())
  362.         {
  363.                 CryLogAlways("Cooperative Animation Manager was passed an invalid actor");
  364.                 return false;
  365.         }
  366.  
  367.         if (params.sSignalName == "")
  368.         {
  369.                 CryLogAlways("Cooperative Animation Manager was not passed a correct animation or signal name");
  370.                 return false;
  371.         }
  372.  
  373.         if (m_bPauseAG)
  374.         {
  375.                 SCharacterParams& characterParams = *it;
  376.  
  377.                 IAnimatedCharacter* pAnimChar = characterParams.pActor;
  378.                 CRY_ASSERT(pAnimChar && pAnimChar->GetEntity());
  379.  
  380.                 ICharacterInstance* pICharacter = pAnimChar->GetEntity()->GetCharacter(0);
  381.                 CRY_ASSERT(pICharacter);
  382.  
  383.                 IAnimationSet* pAnimSet = pICharacter->GetIAnimationSet();
  384.                 const int animId = pAnimSet->GetAnimIDByName(characterParams.sSignalName.c_str());
  385.                 if (animId < 0)
  386.                 {
  387.                         GameWarning("Cooperative Animation Manager was passed a non-existing anim (%s) for actor %s", characterParams.sSignalName.c_str(), characterParams.pActor->GetEntity()->GetName());
  388.                         return false;
  389.                 }
  390.  
  391.                 // Cache FilePathCRC of this anim for efficient streaming queries
  392.                 characterParams.animFilepathCRC = pAnimSet->GetFilePathCRCByAnimID(animId);
  393.                 CRY_ASSERT(characterParams.animFilepathCRC != 0);
  394.         }
  395.  
  396.         // Sanity check the alignment type - not all make sense for a single character
  397.         if (generalParams.eAlignment == eAF_WildMatch || generalParams.eAlignment == eAF_FirstActor)
  398.                 m_generalParams.eAlignment = eAF_FirstActorNoRot;
  399.  
  400.         // Calculate the reference point and calculate the target
  401.         // position and orientation of every character relative to this.
  402.         DetermineReferencePositionAndCalculateTargets();
  403.  
  404.         // After all parameters are checked,
  405.         // determine the type of needed character alignment
  406.         m_activeState = eCS_PlayAndSlide;
  407.  
  408.         m_isInitialized = true;
  409.         return true;
  410. }
  411.  
  412. bool CCooperativeAnimation::StartAnimations()
  413. {
  414.         // start animations for all characters
  415.         TCharacterParams::iterator it = m_paramsList.begin();
  416.         TCharacterParams::iterator iend = m_paramsList.end();
  417.         SCharacterParams* params;
  418.         for (int i = 0; it != iend; ++it, ++i)
  419.         {
  420.                 // cast into the correct class
  421.                 params = &(*it);  // looks overly complicated, but is needed to compile for console
  422.  
  423.                 if (!StartAnimation(*params, i))
  424.                         return false;
  425.         }
  426.  
  427.         return true;
  428. }
  429.  
  430. bool CCooperativeAnimation::StartAnimation(SCharacterParams& params, int characterIndex)
  431. {
  432.         CRY_ASSERT(params.pActor);
  433.         IAnimatedCharacter* pAnimChar = params.pActor;
  434.         CRY_ASSERT(pAnimChar);
  435.  
  436.         IAnimationGraphState* pGraphState = pAnimChar->GetAnimationGraphState();
  437.         CRY_ASSERT_MESSAGE(pGraphState, "Cannot retrieve animation graph state");
  438.         if (!pGraphState)
  439.                 return false;
  440.  
  441.         if (!CCryActionCVars::Get().co_slideWhileStreaming)
  442.         {
  443.                 // Gather the location offset information before the animation moves the character
  444.                 GatherSlidingInformation(params);
  445.         }
  446.  
  447.         if (m_bPauseAG)
  448.         {
  449.                 CAnimationPlayerProxy* pAnimProxy = pAnimChar->GetAnimationPlayerProxy(eAnimationGraphLayer_FullBody);
  450.                 CRY_ASSERT(pAnimProxy);
  451.                 CryCharAnimationParams AParams;
  452.  
  453.                 // prepare animation parameters
  454.                 string sAnimName = params.sSignalName;
  455.  
  456.                 AParams.m_nLayerID = 0;
  457.                 AParams.m_fPlaybackSpeed = 1.0f;
  458.                 AParams.m_fTransTime = 0.25f;
  459.                 AParams.m_fAllowMultilayerAnim = 0;
  460.  
  461.                 AParams.m_nFlags |= CA_REPEAT_LAST_KEY | CA_FORCE_SKELETON_UPDATE | CA_FULL_ROOT_PRIORITY | CA_DISABLE_MULTILAYER;
  462.                 if (m_generalParams.bForceStart)
  463.                         AParams.m_nFlags |= CA_FORCE_TRANSITION_TO_ANIM;
  464.                 if (m_generalParams.bLooping)
  465.                         AParams.m_nFlags |= CA_LOOP_ANIMATION;
  466.  
  467.                 AParams.m_nUserToken = MY_ANIM;
  468.  
  469.                 bool bAnimStarted = pAnimProxy->StartAnimation(params.pActor->GetEntity(), sAnimName.c_str(), /*0,*/ AParams);
  470.                 if (bAnimStarted)
  471.                 {
  472.                         CRY_ASSERT(bAnimStarted);
  473.  
  474.                         //              if (characterIndex != 0)  // do not stop the graph for the master (if started from AG, not FG)
  475.                         pGraphState->Pause(true, eAGP_PlayAnimationNode);
  476.                 }
  477.                 else
  478.                 {
  479.                         return false;
  480.                 }
  481.         }
  482.         else
  483.         {
  484.                 // If we're currently in a coop anim, we need to check which of the two states we're in and
  485.                 // switch to the other one so we can blend nicely into the next anim
  486.                 const char* cSignal = "coopanimation";
  487.                 const char* cOutPut = pGraphState->QueryOutput("CoopAnim");
  488.                 if (cOutPut && cOutPut[0] == '1')
  489.                 {
  490.                         cSignal = "coopanimation2";
  491.                 }
  492.  
  493.                 // Set the signal (the "optional" prevents inputs to be set to defaults when the value doesn't
  494.                 // exist. Therefore, running animations won't be interrupted if this fails.
  495.                 if (!pGraphState->SetInputOptional("Signal", cSignal))
  496.                 {
  497.                         CRY_ASSERT_MESSAGE(0, "Could not set animation graph input 'coopanimation'.");
  498.                         CryLogAlways("Cooperative Animation start failed - animation graph not prepared?");
  499.                         return false;
  500.                 }
  501.  
  502.                 // Set the variation
  503.                 if (!pGraphState->SetVariationInput("CoopAnimation", params.sSignalName))
  504.                 {
  505.                         CRY_ASSERT_MESSAGE(0, "Could not set animation graph variation 'CoopAnimation'.");
  506.                         CryLogAlways("Cooperative Animation start failed - animation graph not prepared?");
  507.                         return false;
  508.                 }
  509.  
  510.                 // Note: This would cause the animation currently in layer1 to be removed, whether
  511.                 // or not RepeatLastKey is set to "1" in the template of the prev state.
  512.                 // So instead an update will have the same effect, since the template has
  513.                 // the property interruptCurrAnim set to "1".
  514.                 // In rare cases this might not cause the anim graph to jump to the desired state -
  515.                 // in this case it can be enforced. (see below)
  516.                 //params.pActor->GetAnimationGraphState()->ForceTeleportToQueriedState();
  517.  
  518.                 //double check that the teleport worked
  519.                 pGraphState->Update();
  520.  
  521.                 cOutPut = pGraphState->QueryOutput("CoopAnim");
  522.                 if (!cOutPut || cOutPut[0] == '\0')
  523.                 {
  524.                         CRY_ASSERT_MESSAGE(0, "Could not retrieve correct output from AG");
  525.                         CryLogAlways("Cooperative Animation - state teleport failed? (Could not retrieve correct output from AG graph state %s)", pGraphState->GetCurrentStateName());
  526.  
  527.                         if (m_generalParams.bForceStart)
  528.                         {
  529.                                 // if the animation should force start anyway, the new state can be teleported to,
  530.                                 // but this will result in a snap.
  531.                                 pGraphState->ForceTeleportToQueriedState();
  532.                         }
  533.                         else
  534.                         {
  535.                                 return false;
  536.                         }
  537.                 }
  538.         }  // old system
  539.  
  540.         params.bAnimationPlaying = true;
  541.         params.pActor->SetNoMovementOverride(true);
  542.         //IEntity * pEnt = params.pActor->GetEntity();
  543.         //pEnt->GetCharacter(0)->GetISkeletonAnim()->SetLocomotionMacroCallback(MovementCallback, pEnt);
  544.         SetColliderModeAndMCM(&params);
  545.  
  546.         return true;
  547. }
  548.  
  549. bool CCooperativeAnimation::IsAnimationPlaying(const ISkeletonAnim* pISkeletonAnim, const CAnimation* pAnim)
  550. {
  551.         if (m_generalParams.bLooping)
  552.         {
  553.                 return true;
  554.         }
  555.  
  556.         const float ANIMATION_END_THRESHOLD = 0.0f;
  557.         const float fTimeRemaining = (1.f - pISkeletonAnim->GetAnimationNormalizedTime(pAnim)) * pAnim->GetExpectedTotalDurationSeconds();
  558.         if (fTimeRemaining > ANIMATION_END_THRESHOLD)
  559.                 return true;
  560.  
  561.         return false;
  562. }
  563.  
  564. bool CCooperativeAnimation::AnimationsFinished()
  565. {
  566.         // Checks if all characters have finished playing their animation and return true, if they have
  567.  
  568.         TCharacterParams::iterator it = m_paramsList.begin();
  569.         TCharacterParams::iterator iend = m_paramsList.end();
  570.         SCharacterParams* params;
  571.         int finishedCount = m_paramsList.size();
  572.         for (; it != iend; ++it)
  573.         {
  574.                 // cast into the correct class
  575.                 params = &(*it);  // looks overly complicated, but is needed to compile for console
  576.  
  577.                 bool animationPlaying = false;
  578.  
  579.                 if (m_bPauseAG)
  580.                 {
  581.                         ICharacterInstance* pICharacterInstance = params->pActor->GetEntity()->GetCharacter(0);
  582.                         CRY_ASSERT(pICharacterInstance);
  583.                         ISkeletonAnim* rISkeletonAnim = pICharacterInstance->GetISkeletonAnim();
  584.                         CRY_ASSERT(rISkeletonAnim);
  585.  
  586.                         CAnimation* pAnim = rISkeletonAnim->FindAnimInFIFO(MY_ANIM, 0);
  587.                         if (pAnim)
  588.                                 animationPlaying = IsAnimationPlaying(rISkeletonAnim, pAnim);
  589.                 }
  590.                 else
  591.                 {
  592.                         if (params->pActor->GetAnimationGraphState())
  593.                         {
  594.                                 const char* stateName = params->pActor->GetAnimationGraphState()->GetCurrentStateName();
  595.                                 if (!strnicmp(stateName, "x_coopAnimation", 10))   //this will match to x_coopAnimation2 as well
  596.                                         animationPlaying = true;
  597.                         }
  598.                 }
  599.  
  600.                 if (!params->bAnimationPlaying || !animationPlaying)
  601.                 {
  602.                         --finishedCount;
  603.                         if (params->bAnimationPlaying)
  604.                         {
  605.                                 params->bAnimationPlaying = false;
  606.                                 CleanupForFinishedCharacter(*params);
  607.                         }
  608.                 }
  609.                 else
  610.                 {
  611.                         SetColliderModeAndMCM(params);
  612.                 }
  613.         }
  614.  
  615.         if (finishedCount <= 0)
  616.                 return true;
  617.  
  618.         return false;
  619. }
  620.  
  621. void CCooperativeAnimation::GatherSlidingInformation(SCharacterParams& params) const
  622. {
  623.         // figures out how much the characters still need to slide
  624.  
  625.         // get difference in position and rotation from current position to target position
  626.         Quat pRot;
  627.         Vec3 pPos;
  628.  
  629.         // get current position and rotation
  630.         IEntity* pEnt = params.pActor->GetEntity();
  631.         CRY_ASSERT(pEnt);
  632.         pRot = pEnt->GetWorldRotation();
  633.         pPos = pEnt->GetWorldPos();
  634.  
  635.         params.currPos.t = pPos;
  636.         params.currPos.q = pRot;
  637.  
  638.         // save the remaining differences to the target pos and orientation
  639.         params.qSlideOffset.t = params.qTarget.t - pPos;
  640.         params.qSlideOffset.q = params.qTarget.q * (!pRot);
  641.         params.qSlideOffset.q.NormalizeSafe();
  642.  
  643.         // Note: After this, the target position (qTarget) in the params can no longer be
  644.         // be used as reference. The animations will most likely move and rotate the locator.
  645. }
  646.  
  647. void CCooperativeAnimation::PlayAndSlideCharacters(float dt, bool& bAnimFailure, bool& bAllStarted, bool& bAllDone)
  648. {
  649.         // Slide characters into position quickly and return true when done
  650.         bAllStarted = true;
  651.         bAllDone = true;
  652.         bAnimFailure = false;
  653.         bool bAllAnimsReady = true;
  654.  
  655.         // Streaming handling
  656.         if (m_bPauseAG)
  657.         {
  658.                 bAllAnimsReady = UpdateAnimationsStreaming();
  659.                 if (!bAllAnimsReady)
  660.                 {
  661.                         bAllDone = bAllStarted = false;
  662.  
  663.                         if (!CCryActionCVars::Get().co_slideWhileStreaming)
  664.                                 return;
  665.                 }
  666.         }
  667.  
  668.         TCharacterParams::iterator it = m_paramsList.begin();
  669.         TCharacterParams::iterator iend = m_paramsList.end();
  670.         SCharacterParams* params;
  671.         IEntity* pEnt = NULL;
  672.         IAnimatedCharacter* pAC = NULL;
  673.         Quat pRot;
  674.         Vec3 pPos;
  675.         for (int i = 0; it != iend; ++it, ++i)
  676.         {
  677.                 // cast into the correct class
  678.                 params = &(*it);  // looks overly complicated, but is needed to compile for console
  679.                 pEnt = params->pActor->GetEntity();
  680.                 pAC = params->pActor;
  681.                 CRY_ASSERT(pEnt && pAC);
  682.                 bool animJustStarted = false;
  683.  
  684.                 if (!params->bAnimationPlaying)
  685.                 {
  686.                         // Delayed start handling
  687.                         if (params->fStartDelay > 0.0f)
  688.                         {
  689.                                 params->fStartDelayTimer += dt;
  690.                                 if (params->fStartDelayTimer < params->fStartDelay)
  691.                                 {
  692.                                         bAllStarted = bAllDone = false;
  693.                                         continue; // Skip any more processing of this character until start delay is up
  694.                                 }
  695.                         }
  696.  
  697.                         if (bAllAnimsReady)
  698.                         {
  699.                                 if (!StartAnimation(*params, i))
  700.                                 {
  701.                                         bAnimFailure = true; // tell the calling function to abort the cooperative animation
  702.                                         bAllStarted = bAllDone = false;
  703.                                         return;
  704.                                 }
  705.                                 else
  706.                                 {
  707.                                         animJustStarted = true;
  708.                                 }
  709.                         }
  710.                 }
  711.  
  712.                 /*
  713.                     // This commented code will teleport the characters to their target positions directly
  714.                     // and is useful for debugging this system.
  715.  
  716.                     pEnt->SetPos(params->qTarget.t);
  717.                     pEnt->SetRotation(params->qTarget.q);
  718.                     params->pActor->GetAnimatedCharacter()->SetNoMovementOverride(false);
  719.                     continue;
  720.                  */
  721.  
  722.                 // check if this character still needs to slide or is already done
  723.                 if (params->fSlidingTimer >= params->fSlidingDuration)
  724.                 {
  725.                         pAC->SetNoMovementOverride(false);
  726.                         //pEnt->GetCharacter(0)->GetISkeletonAnim()->SetLocomotionMacroCallback(MovementCallback, pEnt);
  727.                         continue;
  728.                 }
  729.  
  730.                 // calculate the amount of movement that needs to be done this frame
  731.                 float slideAmount = dt;
  732.  
  733.                 // check if this is the last step for this character
  734.                 if (params->fSlidingTimer + dt >= params->fSlidingDuration)
  735.                 {
  736.                         slideAmount = params->fSlidingDuration - params->fSlidingTimer;
  737.                         pAC->SetNoMovementOverride(false);
  738.                         //pEnt->GetCharacter(0)->GetISkeletonAnim()->SetLocomotionMacroCallback(MovementCallback, pEnt);
  739.                 }
  740.                 else
  741.                 {
  742.                         // there are more steps necessary
  743.                         bAllDone = false;
  744.                 }
  745.  
  746.                 // Calculate new character position and rotation
  747.                 slideAmount = slideAmount / params->fSlidingDuration;
  748.                 pRot = pEnt->GetWorldRotation();
  749.                 pPos = pEnt->GetWorldPos();
  750.  
  751.                 /*
  752.                    pPos += slideAmount * params->qSlideOffset.t;
  753.                    pRot = pRot * params->qSlideOffset.q.CreateSlerp(Quat(IDENTITY), params->qSlideOffset.q, slideAmount);
  754.                    pEnt->SetPos(pPos);
  755.                    pEnt->SetRotation(pRot);
  756.                  */
  757.  
  758.                 QuatT testQuat(IDENTITY);
  759.                 testQuat = params->currPos;
  760.                 Vec3 dist;
  761.                 dist = params->qSlideOffset.t;
  762.                 dist = dist * slideAmount;
  763.                 testQuat.t += dist;
  764.  
  765.                 testQuat.q = testQuat.q * params->qSlideOffset.q.CreateSlerp(Quat(IDENTITY), params->qSlideOffset.q, slideAmount);
  766.                 testQuat.q.NormalizeSafe();
  767.                 params->currPos = testQuat;
  768.  
  769.                 if (!animJustStarted || CCryActionCVars::Get().co_slideWhileStreaming)
  770.                 {
  771.                         // consider locator movement in the animation (don't do this if the anim just started because the rel movement won't be from this animation)
  772.                         ICharacterInstance* pCharacterInstance = pEnt->GetCharacter(0);
  773.                         const QuatT& animRelMovement = pCharacterInstance ? pCharacterInstance->GetISkeletonAnim()->GetRelMovement() : QuatT(IDENTITY);
  774.                         params->deltaLocatorMovement = params->deltaLocatorMovement * animRelMovement;
  775.  
  776.                         testQuat = testQuat * params->deltaLocatorMovement;
  777.  
  778.                         // Safety check to guarantee character will not fall through ground
  779.                         if (m_generalParams.bPreventFallingThroughTerrain)
  780.                                 testQuat.t.z = max(testQuat.t.z, gEnv->p3DEngine->GetTerrainElevation(testQuat.t.x, testQuat.t.y));
  781.  
  782.                         pEnt->SetPos(testQuat.t);
  783.                         pEnt->SetRotation(testQuat.q);
  784.                 }
  785.  
  786.                 // increase the sliding timer for this character
  787.                 params->fSlidingTimer += dt;
  788.  
  789.                 // DEBUG OUTPUT
  790.                 if (CCryActionCVars::Get().co_coopAnimDebug)
  791.                 {
  792.                         IRenderAuxGeom* pRenderAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom();
  793.                         pRenderAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags);
  794.  
  795.                         // draw an indication that this character is being sled
  796.                         pRenderAuxGeom->DrawSphere(pPos + Vec3(0, 0, 2.0f), 0.1f, ColorB(255, 255, 0));
  797.  
  798.                         // add to the amount that this character has already been moved
  799.                         if (it == m_paramsList.begin())
  800.                                 m_firstActorPushedDistance += (slideAmount * params->qSlideOffset.t).GetLength();
  801.                 } // end of DEBUG OUTPUT
  802.         }
  803.  
  804.         return;
  805. }
  806.  
  807. void CCooperativeAnimation::DetermineReferencePositionAndCalculateTargets()
  808. {
  809.         // Right now, only the reference type FirstCharacter is supported
  810.         SCharacterParams* params;
  811.  
  812.         // Depending on the chosen alignment type the position and orientation of the reference
  813.         // position is determined quite differently.
  814.         switch (m_generalParams.eAlignment)
  815.         {
  816.         case eAF_Location:
  817.                 {
  818.                         // the actual reference position and orientation has been specified.
  819.  
  820.                         m_refPoint = m_generalParams.qLocation;
  821.                 }
  822.                 break;
  823.         case eAF_FirstActorPosition:
  824.                 {
  825.                         // the position and orientation for the first actor has been specified and
  826.                         // all must adjust accordingly
  827.  
  828.                         // Reference Point is target position of the first character minus
  829.                         // the relative location of his start location
  830.                         params = &(*(m_paramsList.begin()));  // looks overly complicated, but is needed to compile for console
  831.                         QuatT relativeOffset = GetStartOffset(*params);
  832.                         IEntity* pEnt = params->pActor->GetEntity();
  833.                         m_refPoint.q = m_generalParams.qLocation.q;
  834.  
  835.                         // rotating the actor rotation backwards with the rotation from the animation
  836.                         m_refPoint.q = m_refPoint.q * (!relativeOffset.q);
  837.  
  838.                         // now get the correct world space vector that point from the actor to the
  839.                         // ref point (also in world space)
  840.                         Vec3 chartoRef = m_refPoint.q * (-relativeOffset.t);
  841.                         m_refPoint.t = m_generalParams.qLocation.t + chartoRef;
  842.  
  843.                         // DEBUG OUTPUT
  844.                         // Set all the values
  845.                         if (CCryActionCVars::Get().co_coopAnimDebug)
  846.                         {
  847.                                 Matrix34 firstActorMat = pEnt->GetWorldTM();
  848.                                 m_firstActorStartPosition = firstActorMat.GetTranslation();
  849.                                 m_firstActorStartDirection = firstActorMat.GetColumn1();
  850.                                 m_firstActorTargetPosition = m_generalParams.qLocation.t;
  851.                                 m_firstActorTargetDirection = m_generalParams.qLocation.q * FORWARD_DIRECTION;
  852.                                 m_firstActorPushedDistance = 0.0f;
  853.                         } // end of DEBUG OUTPUT
  854.  
  855.                 }
  856.                 break;
  857.         case eAF_FirstActor:
  858.         case eAF_FirstActorNoRot:
  859.                 {
  860.                         // first actor (not maintaining rotation)
  861.  
  862.                         // Reference Point is the position of the first character minus
  863.                         // the relative location of his start location
  864.                         params = &(*(m_paramsList.begin()));  // looks overly complicated, but is needed to compile for console
  865.                         QuatT relativeOffset = GetStartOffset(*params);
  866.                         IEntity* pEnt = params->pActor->GetEntity();
  867.                         m_refPoint.q = pEnt->GetWorldRotation();
  868.  
  869.                         if (m_generalParams.eAlignment == eAF_FirstActorNoRot)
  870.                         {
  871.                                 m_refPoint.q = relativeOffset.q;
  872.                         }
  873.                         else
  874.                         {
  875.                                 // rotating the actor rotation backwards with the rotation from the animation
  876.                                 m_refPoint.q = m_refPoint.q * (!relativeOffset.q);
  877.                         }
  878.  
  879.                         // now get the correct world space vector that points from the actor to the
  880.                         // ref point (also in world space)
  881.                         Vec3 chartoRef = m_refPoint.q * (-relativeOffset.t);
  882.                         m_refPoint.t = pEnt->GetWorldPos() + chartoRef;
  883.                 }
  884.                 break;
  885.         case eAF_WildMatch:
  886.         default:
  887.                 {
  888.                         // Wild Matching
  889.                         // (meaning least amount of movement, rather rotate than change position)
  890.  
  891.                         // FIRST ITERATION: Only support for two characters
  892.  
  893.                         // rotate towards the second character before making this the reference point
  894.                         // (if this step is left out, the entity rotation of the actor will be preserved,
  895.                         // but that causes big distances for all other characters to their target positions)
  896.  
  897.                         // Reference Point is the position of the first character minus
  898.                         // the relative location of his start location
  899.                         params = &(*(m_paramsList.begin()));  // looks overly complicated, but is needed to compile for console
  900.                         QuatT relativeOffset = GetStartOffset(*params);
  901.                         IEntity* pEnt = params->pActor->GetEntity();
  902.                         m_refPoint.q = pEnt->GetWorldRotation();
  903.  
  904.                         // rotating the actor rotation backwards with the rotation from the animation
  905.                         m_refPoint.q = m_refPoint.q * relativeOffset.q;
  906.  
  907.                         // Get the vector from first to second character as it is in the animation
  908.                         SCharacterParams paramsSecond = (m_paramsList.at(1));
  909.                         Vec3 secondPos = GetStartOffset(paramsSecond).t;
  910.                         secondPos = (secondPos - relativeOffset.t);
  911.  
  912.                         // rotate it into world space
  913.                         secondPos = m_refPoint.q * secondPos;
  914.                         secondPos.z = 0.0f; // only interested in the rotation around the up vector
  915.  
  916.                         // Get the vector between first and second char in world space
  917.                         Vec3 firstToSecW = paramsSecond.pActor->GetEntity()->GetWorldPos() - pEnt->GetWorldPos();
  918.                         firstToSecW.z = 0.0f; // only interested in the rotation around the up vector
  919.  
  920.                         bool invalidOffset = false;
  921.                         if (firstToSecW.IsZero() || secondPos.IsZero())
  922.                                 invalidOffset = true; // this is ok, but it means that wild match cannot be used
  923.  
  924.                         secondPos.normalize();
  925.                         firstToSecW.normalize();
  926.  
  927.                         // get the rotation between those vectors (z axis rotation, from worldDir to animDir)
  928.                         float fDot = secondPos * firstToSecW;
  929.                         float angle = acos_tpl(fDot);
  930.  
  931.                         // cross product to determine if the angle needs to be flipped - but only z component is relevant
  932.                         // so save processing time and not calculate the full cross
  933.                         if (((firstToSecW.x * secondPos.y) - (firstToSecW.y * secondPos.x)) < 0)
  934.                                 angle = -angle;
  935.  
  936.                         // Create a rotation out of this
  937.                         Quat rot(IDENTITY);
  938.                         rot.SetRotationAA(angle, Vec3(0.0f, 0.0f, 1.0f));
  939.  
  940.                         // rotate the reference-QuatT by it
  941.                         if (rot.IsValid() || invalidOffset)  // safety check
  942.                                 m_refPoint.q = m_refPoint.q * (!rot);
  943.                         else
  944.                         {
  945.                                 CRY_ASSERT_MESSAGE(0, "Possibly an invalid quaternion, or only z deviation in animations.");
  946.                         }
  947.  
  948.                         // now get the correct world space vector that point from the actor to the
  949.                         // ref point (also in world space)
  950.                         Vec3 chartoRef = m_refPoint.q * relativeOffset.t;
  951.                         m_refPoint.t = pEnt->GetWorldPos() + chartoRef;
  952.                 } // end of wild matching
  953.                 break;
  954.         }
  955.  
  956.         // Now go through all characters and calculate their final target positions
  957.         TCharacterParams::iterator it = m_paramsList.begin();
  958.         TCharacterParams::iterator itend = m_paramsList.end();
  959.         for (; it != itend; ++it)
  960.         {
  961.                 // cast into the correct class
  962.                 params = &(*it);  // looks overly complicated, but is needed to compile for console
  963.  
  964.                 // Calculate target position
  965.                 QuatT relativeOffset = GetStartOffset(*params);
  966.                 params->qTarget = m_refPoint * relativeOffset;
  967.                 params->qTarget.q.NormalizeSafe();
  968.                 //params->qSlideOffset.q.NormalizeSafe();
  969.         }
  970. }
  971.  
  972. QuatT CCooperativeAnimation::GetStartOffset(SCharacterParams& params)
  973. {
  974.         QuatT retVal(IDENTITY);
  975.  
  976.         if (!params.pActor)
  977.         {
  978.                 CRY_ASSERT_MESSAGE(params.pActor, "No valid Actor received!");
  979.                 return retVal;
  980.         }
  981.  
  982.         ICharacterInstance* pCharacter = params.pActor->GetEntity()->GetCharacter(0);
  983.         CRY_ASSERT(pCharacter != NULL);
  984.  
  985.         IAnimationSet* pAnimSet = pCharacter->GetIAnimationSet();
  986.         if (pAnimSet == NULL)
  987.                 return retVal;
  988.  
  989.         //string animation0 = pState == NULL ? m_animations[0].c_str() : pState->ExpandVariationInputs( m_animations[0].c_str() ).c_str();
  990.         string animation0 = params.sSignalName;
  991.  
  992.         int id = pAnimSet->GetAnimIDByName(animation0.c_str());
  993.         if (id < 0)
  994.                 return retVal;
  995.  
  996.         uint32 flags = pAnimSet->GetAnimationFlags(id);
  997.         if ((flags & CA_ASSET_CREATED) == 0)
  998.                 return retVal;
  999.  
  1000.         float animDuration = pAnimSet->GetDuration_sec(id);
  1001.         if (animDuration < params.fSlidingDuration)
  1002.         {
  1003.                 CRY_ASSERT_MESSAGE(animDuration > params.fSlidingDuration, "Incorrect parameter: Sliding Duration longer than animation.");
  1004.                 CryLogAlways("Warning: sliding duration longer than actual animation. Will adjust given parameter.");
  1005.                 params.fSlidingDuration = min(animDuration, animParamDefaultSlidingDuration);
  1006.         }
  1007.  
  1008.         // the first key will always be in the center so this helper function will
  1009.         // reconstruct the actual starting location of the character's root from the
  1010.         // original scene
  1011.         const bool success = pAnimSet->GetAnimationDCCWorldSpaceLocation(id, retVal);
  1012.         retVal.q.NormalizeSafe();
  1013.  
  1014.         return retVal;
  1015. }
  1016.  
  1017. void CCooperativeAnimation::CleanupForFinishedCharacter(SCharacterParams& params)
  1018. {
  1019.         if ((!params.pActor) || (!params.IsActorValid()))
  1020.                 return;
  1021.  
  1022.         IAnimatedCharacter* pAC = params.pActor;
  1023.  
  1024.         const ICooperativeAnimationManager* const pCAManager = gEnv->pGameFramework->GetICooperativeAnimationManager();
  1025.         CRY_ASSERT(pCAManager);
  1026.  
  1027.         CRY_ASSERT_MESSAGE(!pCAManager->IsActorBusy(params.pActor, this), "Cleaning up for a character that's already playing a second animation");
  1028.  
  1029.         // reset the movementOverride for the characters that haven't
  1030.         // finished their animations yet (in case of premature termination)
  1031.         if (!params.bAllowHorizontalPhysics)
  1032.         {
  1033.                 pAC->SetNoMovementOverride(false);
  1034.         }
  1035.  
  1036.         pAC->RequestPhysicalColliderMode(eColliderMode_Pushable, eColliderModeLayer_Game, COOP_ANIM_NAME);
  1037.  
  1038.         // enable look&aim ik for this character again
  1039.         pAC->AllowLookIk(true);
  1040.         pAC->AllowAimIk(true);
  1041.  
  1042.         if (m_generalParams.bNoCollisionsBetweenFirstActorAndRest)
  1043.                 IgnoreCollisionsWithFirstActor(params, false);
  1044.  
  1045.         if (m_bPauseAG && pAC->GetAnimationGraphState())
  1046.         {
  1047.                 // Release reference
  1048.                 if (params.animationState != SCharacterParams::AS_Unrequested)
  1049.                 {
  1050.                         const bool bReleased = gEnv->pCharacterManager->CAF_Release(params.animFilepathCRC);
  1051.                         CRY_ASSERT(bReleased);
  1052.  
  1053.                         params.animationState = SCharacterParams::AS_Unrequested;
  1054.                 }
  1055.  
  1056.                 ISkeletonAnim* pISkeletonAnim = params.pActor->GetEntity()->GetCharacter(0)->GetISkeletonAnim();
  1057.                 CRY_ASSERT(pISkeletonAnim);
  1058.  
  1059.                 // reactivate animation graph
  1060.                 pAC->GetAnimationGraphState()->Pause(false, eAGP_PlayAnimationNode);
  1061.  
  1062.                 pAC->GetAnimationGraphState()->Update();
  1063.         }
  1064. }
  1065.  
  1066. void CCooperativeAnimation::IgnoreCollisionsWithFirstActor(SCharacterParams& characterParams, bool ignore)
  1067. {
  1068.         IPhysicalEntity* pActorPE = characterParams.pActor->GetEntity()->GetPhysics();
  1069.         if (pActorPE)
  1070.         {
  1071.                 if (ignore && !characterParams.collisionsDisabledWithFirstActor)
  1072.                 {
  1073.                         IAnimatedCharacter* pFirstActor = (m_paramsList.size() > 1) ? m_paramsList.begin()->pActor : NULL;
  1074.                         if (pFirstActor && (pFirstActor != characterParams.pActor))
  1075.                         {
  1076.                                 pe_player_dynamics ppd;
  1077.                                 ppd.pLivingEntToIgnore = pFirstActor->GetEntity()->GetPhysics();
  1078.  
  1079.                                 characterParams.collisionsDisabledWithFirstActor = pActorPE->SetParams(&ppd) != 0;
  1080.                         }
  1081.                 }
  1082.                 else if (!ignore && characterParams.collisionsDisabledWithFirstActor)
  1083.                 {
  1084.                         pe_player_dynamics ppd;
  1085.                         ppd.pLivingEntToIgnore = NULL;
  1086.                         pActorPE->SetParams(&ppd);
  1087.  
  1088.                         characterParams.collisionsDisabledWithFirstActor = false;
  1089.                 }
  1090.         }
  1091. }
  1092.  
  1093. void CCooperativeAnimation::SetColliderModeAndMCM(SCharacterParams* params)
  1094. {
  1095.         EMovementControlMethod eMoveVertical = eMCM_Animation;
  1096.  
  1097.         if (m_bPauseAG)
  1098.                 params->pActor->ForceRefreshPhysicalColliderMode();
  1099.  
  1100.         if (params->bAllowHorizontalPhysics)
  1101.         {
  1102.                 params->pActor->SetMovementControlMethods(eMCM_AnimationHCollision, eMoveVertical);
  1103.                 params->pActor->RequestPhysicalColliderMode(eColliderMode_Pushable, eColliderModeLayer_Game, COOP_ANIM_NAME);
  1104.         }
  1105.         else
  1106.         {
  1107.                 if (params->fSlidingTimer >= params->fSlidingDuration)
  1108.                 {
  1109.                         //params->pActor->SetNoMovementOverride(true);
  1110.                 }
  1111.                 params->pActor->SetMovementControlMethods(eMCM_Animation, eMoveVertical);
  1112.                 params->pActor->RequestPhysicalColliderMode(eColliderMode_PushesPlayersOnly, eColliderModeLayer_Game, COOP_ANIM_NAME);
  1113.         }
  1114.  
  1115.         // disable look & aim ik for this character
  1116.         ISkeletonPose* pISkeletonPose = params->pActor->GetEntity()->GetCharacter(0)->GetISkeletonPose();
  1117.         CRY_ASSERT(pISkeletonPose);
  1118.  
  1119.         IAnimationPoseBlenderDir* pIPoseBlenderLook = pISkeletonPose->GetIPoseBlenderLook();
  1120.         if (pIPoseBlenderLook)
  1121.         {
  1122.                 pIPoseBlenderLook->SetState(false);
  1123.         }
  1124.  
  1125.         params->pActor->AllowLookIk(false);
  1126.         params->pActor->AllowAimIk(false);
  1127.  
  1128.         if (m_generalParams.bNoCollisionsBetweenFirstActorAndRest)
  1129.                 IgnoreCollisionsWithFirstActor(*params, true);
  1130. }
  1131.  
  1132. float CCooperativeAnimation::GetAnimationNormalizedTime(const EntityId entID) const
  1133. {
  1134.         ISkeletonAnim* pISkeletonAnim = gEnv->pEntitySystem->GetEntity(entID)->GetCharacter(0)->GetISkeletonAnim();
  1135.         int iAnimCount = pISkeletonAnim->GetNumAnimsInFIFO(0);
  1136.  
  1137.         for (int i = 0; i < iAnimCount; ++i)
  1138.         {
  1139.                 const CAnimation& anim = pISkeletonAnim->GetAnimFromFIFO(0, i);
  1140.                 if (anim.HasUserToken(MY_ANIM))
  1141.                 {
  1142.                         return pISkeletonAnim->GetAnimationNormalizedTime(&anim);
  1143.                 }
  1144.         }
  1145.  
  1146.         return -1.0f;
  1147. }
  1148.  
  1149. bool CCooperativeAnimation::UpdateAnimationsStreaming()
  1150. {
  1151.         CRY_ASSERT(m_bPauseAG);
  1152.  
  1153.         uint animsReady = 0;
  1154.  
  1155.         TCharacterParams::iterator it = m_paramsList.begin();
  1156.         TCharacterParams::iterator iend = m_paramsList.end();
  1157.         for (; it != iend; ++it)
  1158.         {
  1159.                 SCharacterParams* params = &(*it);  // looks overly complicated, but is needed to compile for console
  1160.  
  1161.                 if (params->animationState != SCharacterParams::AS_Ready)
  1162.                 {
  1163.                         switch (params->animationState)
  1164.                         {
  1165.                         case SCharacterParams::AS_Unrequested:
  1166.                                 {
  1167.                                         // Request
  1168.                                         const bool bRefAdded = gEnv->pCharacterManager->CAF_AddRef(params->animFilepathCRC);
  1169.                                         CRY_ASSERT(bRefAdded);
  1170.  
  1171.                                         params->animationState = SCharacterParams::AS_NotReady;
  1172.                                 }
  1173.                                 break;
  1174.                         case SCharacterParams::AS_NotReady:
  1175.                                 {
  1176.                                         // Poll for streaming finish
  1177.                                         if (gEnv->pCharacterManager->CAF_IsLoaded(params->animFilepathCRC))
  1178.                                         {
  1179.                                                 params->animationState = SCharacterParams::AS_Ready;
  1180.                                                 ++animsReady;
  1181.                                         }
  1182.                                 }
  1183.                                 break;
  1184.                         default:
  1185.                                 break;
  1186.                         }
  1187.                 }
  1188.                 else
  1189.                 {
  1190.                         ++animsReady;
  1191.                 }
  1192.         }
  1193.  
  1194.         return (animsReady == m_paramsList.size());
  1195. }
  1196.  
  1197. void CCooperativeAnimation::OnEntityEvent(IEntity* pEntity, SEntityEvent& event)
  1198. {
  1199.         if (event.event == ENTITY_EVENT_DONE)
  1200.         {
  1201.                 EntityId removedId = pEntity->GetId();
  1202.  
  1203.                 TCharacterParams::const_iterator itParamsEnd = m_paramsList.end();
  1204.                 for (TCharacterParams::const_iterator itParams = m_paramsList.begin(); itParams != itParamsEnd; ++itParams)
  1205.                 {
  1206.                         IAnimatedCharacter* pAnimatedCharacter = itParams->pActor;
  1207.                         if (pAnimatedCharacter && pAnimatedCharacter->GetEntityId() == removedId)
  1208.                         {
  1209.                                 gEnv->pEntitySystem->RemoveEntityEventListener(removedId, ENTITY_EVENT_DONE, this);
  1210.                                 itParams->pActor = NULL;
  1211.                                 break;
  1212.                         }
  1213.                 }
  1214.         }
  1215. }
  1216.  
downloadCooperativeAnimation.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