BVB Source Codes

CRYENGINE Show VehicleAnimation.cpp Source code

Return Download CRYENGINE: download VehicleAnimation.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:
  8.  
  9.    -------------------------------------------------------------------------
  10.    History:
  11.    - 22:03:2006: Created by Mathieu Pinard
  12.  
  13. *************************************************************************/
  14. #include "StdAfx.h"
  15. #include <CryAnimation/ICryAnimation.h>
  16. #include "IVehicleSystem.h"
  17. #include "VehiclePartAnimated.h"
  18. #include "VehiclePartAnimatedChar.h"
  19. #include "VehicleAnimation.h"
  20.  
  21. //------------------------------------------------------------------------
  22. CVehicleAnimation::CVehicleAnimation()
  23.         : m_pPartAnimated(nullptr)
  24.         , m_layerId(0)
  25.         , m_currentStateId(0)
  26.         , m_currentAnimIsWaiting(false)
  27. {}
  28.  
  29. //------------------------------------------------------------------------
  30. bool CVehicleAnimation::Init(IVehicle* pVehicle, const CVehicleParams& table)
  31. {
  32.         m_currentAnimIsWaiting = false;
  33.  
  34.         if (table.haveAttr("part"))
  35.         {
  36.                 if (IVehiclePart* pPart = pVehicle->GetPart(table.getAttr("part")))
  37.                 {
  38.                         m_pPartAnimated = CAST_VEHICLEOBJECT(CVehiclePartAnimated, pPart);
  39.                         if (!m_pPartAnimated)
  40.                         {
  41.                                 m_pPartAnimated = CAST_VEHICLEOBJECT(CVehiclePartAnimatedChar, pPart);
  42.                         }
  43.                 }
  44.         }
  45.  
  46.         if (!m_pPartAnimated)
  47.                 return false;
  48.  
  49.         if (CVehicleParams statesTable = table.findChild("States"))
  50.         {
  51.                 int c = statesTable.getChildCount();
  52.                 int i = 0;
  53.  
  54.                 m_animationStates.reserve(c);
  55.  
  56.                 for (; i < c; i++)
  57.                 {
  58.                         if (CVehicleParams stateTable = statesTable.getChild(i))
  59.                                 ParseState(stateTable, pVehicle);
  60.                 }
  61.         }
  62.  
  63.         if (m_animationStates.empty() == false)
  64.                 m_currentStateId = 0;
  65.         else
  66.                 m_currentStateId = InvalidVehicleAnimStateId;
  67.  
  68.         m_layerId = m_pPartAnimated->AssignAnimationLayer();
  69.  
  70.         return true;
  71. }
  72.  
  73. //------------------------------------------------------------------------
  74. bool CVehicleAnimation::ParseState(const CVehicleParams& table, IVehicle* pVehicle)
  75. {
  76.         m_animationStates.resize(m_animationStates.size() + 1);
  77.         SAnimationState& animState = m_animationStates.back();
  78.  
  79.         animState.name = table.getAttr("name");
  80.         animState.animation = table.getAttr("animation");
  81.         animState.sound = table.getAttr("sound");
  82.         animState.pSoundHelper = NULL;
  83.  
  84.         if (table.haveAttr("sound"))
  85.                 animState.pSoundHelper = pVehicle->GetHelper(table.getAttr("sound"));
  86.         else
  87.                 animState.pSoundHelper = NULL;
  88.  
  89.         //animState.soundId = INVALID_SOUNDID;
  90.  
  91.         table.getAttr("speedDefault", animState.speedDefault);
  92.         table.getAttr("speedMin", animState.speedMin);
  93.         table.getAttr("speedMax", animState.speedMax);
  94.         table.getAttr("isLooped", animState.isLooped);
  95.         animState.isLoopedEx = false;
  96.         table.getAttr("isLoopedEx", animState.isLoopedEx);
  97.  
  98.         if (CVehicleParams materialsTable = table.findChild("Materials"))
  99.         {
  100.                 int i = 0;
  101.                 int c = materialsTable.getChildCount();
  102.  
  103.                 animState.materials.reserve(c);
  104.  
  105.                 for (; i < c; ++i)
  106.                 {
  107.                         if (CVehicleParams materialTable = materialsTable.getChild(i))
  108.                         {
  109.                                 animState.materials.resize(animState.materials.size() + 1);
  110.  
  111.                                 SAnimationStateMaterial& stateMaterial = animState.materials.back();
  112.  
  113.                                 stateMaterial.material = materialTable.getAttr("name");
  114.                                 stateMaterial.setting = materialTable.getAttr("setting");
  115.  
  116.                                 if (materialTable.haveAttr("min"))
  117.                                 {
  118.                                         materialTable.getAttr("min", stateMaterial._min);
  119.                                 }
  120.                                 else
  121.                                 {
  122.                                         stateMaterial._min = 0.001f;
  123.                                 }
  124.  
  125.                                 if (materialTable.haveAttr("max"))
  126.                                 {
  127.                                         materialTable.getAttr("max", stateMaterial._max);
  128.                                 }
  129.                                 else
  130.                                 {
  131.                                         stateMaterial._max = 0.999f;
  132.                                 }
  133.  
  134.                                 materialTable.getAttr("invertValue", stateMaterial.invertValue);
  135.                         }
  136.                 }
  137.         }
  138.  
  139.         return true;
  140. }
  141.  
  142. //------------------------------------------------------------------------
  143. void CVehicleAnimation::Reset()
  144. {
  145.         if (m_currentStateId != InvalidVehicleAnimStateId)
  146.         {
  147.                 const SAnimationState& animState = m_animationStates[m_currentStateId];
  148.  
  149.                 if (IEntity* pEntity = m_pPartAnimated->GetEntity())
  150.                 {
  151.                         for (TAnimationStateMaterialVector::const_iterator ite = animState.materials.begin(), end = animState.materials.end(); ite != end; ++ite)
  152.                         {
  153.                                 const SAnimationStateMaterial& stateMaterial = *ite;
  154.  
  155.                                 if (IMaterial* pMaterial = FindMaterial(stateMaterial, m_pPartAnimated->GetMaterial()))
  156.                                 {
  157.                                         float value = max(0.00f, min(1.0f, animState.speedDefault));
  158.  
  159.                                         if (stateMaterial.invertValue)
  160.                                         {
  161.                                                 value = 1.0f - value;
  162.                                         }
  163.  
  164.                                         value = stateMaterial._min + (value * (stateMaterial._max - stateMaterial._min));
  165.  
  166.                                         pMaterial->SetGetMaterialParamFloat(stateMaterial.setting, value, false);
  167.                                 }
  168.                         }
  169.                 }
  170.  
  171.                 if (m_currentStateId != 0)
  172.                         ChangeState(0);
  173.         }
  174.  
  175.         if (m_layerId > -1)
  176.                 StopAnimation();
  177. }
  178.  
  179. //------------------------------------------------------------------------
  180. bool CVehicleAnimation::StartAnimation()
  181. {
  182.         if (m_currentStateId == -1)
  183.                 m_currentStateId = 0;
  184.  
  185.         SAnimationState& animState = m_animationStates[m_currentStateId];
  186.  
  187.         if (animState.materials.empty() == false)
  188.         {
  189.                 m_pPartAnimated->CloneMaterial();
  190.         }
  191.  
  192.         if (IEntity* pEntity = m_pPartAnimated->GetEntity())
  193.         {
  194.                 if (ICharacterInstance* pCharInstance = pEntity->GetCharacter(m_pPartAnimated->GetSlot()))
  195.                 {
  196.                         ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  197.                         CRY_ASSERT(pSkeletonAnim);
  198.  
  199.                         CryCharAnimationParams animParams;
  200.                         animParams.m_nFlags = CA_FORCE_SKELETON_UPDATE;
  201.                         animParams.m_nLayerID = m_layerId;
  202.  
  203.                         if (animState.isLooped)
  204.                                 animParams.m_nFlags |= CA_LOOP_ANIMATION;
  205.  
  206.                         if (animState.isLoopedEx)
  207.                         {
  208.                                 animParams.m_nFlags |= CA_REPEAT_LAST_KEY;
  209.                                 uint32 numAnimsLayer0 = pSkeletonAnim->GetNumAnimsInFIFO(animParams.m_nLayerID);
  210.                                 if (numAnimsLayer0)
  211.                                 {
  212.                                         CAnimation& animation = pSkeletonAnim->GetAnimFromFIFO(animParams.m_nLayerID, numAnimsLayer0 - 1);
  213.                                         const float animationTime = pSkeletonAnim->GetAnimationNormalizedTime(&animation);
  214.                                         if (animationTime == 1.0f)
  215.                                                 pSkeletonAnim->SetAnimationNormalizedTime(&animation, 0.f);
  216.                                 }
  217.  
  218.                         }
  219.  
  220.                         // cope with empty animation names (for disabling some in certain vehicle modifications)
  221.                         if (animState.animation.empty())
  222.                                 return false;
  223.  
  224.                         if (!pSkeletonAnim->StartAnimation(animState.animation, animParams))
  225.                                 return false;
  226.  
  227.                         if (!animState.sound.empty())
  228.                         {
  229.                                 IEntityAudioComponent* pEntitySoundsProxy = pEntity->GetOrCreateComponent<IEntityAudioComponent>();
  230.                                 CRY_ASSERT(pEntitySoundsProxy);
  231.  
  232.                                 REINST("send an animation start event?");
  233.                                 /*int soundFlags = FLAG_SOUND_DEFAULT_3D;
  234.                                    if (animState.isLooped)
  235.                                    soundFlags |= FLAG_SOUND_LOOP;
  236.  
  237.                                    Vec3 pos(ZERO);
  238.                                    if (animState.pSoundHelper)
  239.                                    pos = animState.pSoundHelper->GetVehicleSpaceTranslation();
  240.  
  241.                                    animState.soundId = pEntitySoundsProxy->PlaySound(animState.sound.c_str(), pos, FORWARD_DIRECTION, soundFlags, 0, eSoundSemantic_Vehicle);*/
  242.                         }
  243.  
  244.                         pSkeletonAnim->SetLayerPlaybackScale(m_layerId, animState.speedDefault);
  245.                         return true;
  246.                 }
  247.         }
  248.  
  249.         return true;
  250. }
  251.  
  252. //------------------------------------------------------------------------
  253. void CVehicleAnimation::StopAnimation()
  254. {
  255.         if (m_layerId < 0)
  256.                 return;
  257.  
  258.         if (IsUsingManualUpdates())
  259.                 SetTime(0.0f);
  260.  
  261.         IEntity* pEntity = m_pPartAnimated->GetEntity();
  262.         CRY_ASSERT(pEntity);
  263.  
  264.         SAnimationState& animState = m_animationStates[m_currentStateId];
  265.  
  266.         if (ICharacterInstance* pCharInstance = pEntity->GetCharacter(m_pPartAnimated->GetSlot()))
  267.         {
  268.                 ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  269.                 CRY_ASSERT(pSkeletonAnim);
  270.  
  271.                 pSkeletonAnim->StopAnimationInLayer(m_layerId, 0.0f);
  272.         }
  273.  
  274.         REINST("send an animation stop event?");
  275.         /*if (animState.soundId != INVALID_SOUNDID)
  276.            {
  277.            IEntityAudioComponent* pEntitySoundsProxy = pEntity->GetOrCreateComponent<IEntityAudioComponent>();
  278.            CRY_ASSERT(pEntitySoundsProxy);
  279.  
  280.            pEntitySoundsProxy->StopSound(animState.soundId);
  281.            animState.soundId = INVALID_SOUNDID;
  282.            }*/
  283.  
  284.         m_currentAnimIsWaiting = false;
  285. }
  286.  
  287. //------------------------------------------------------------------------
  288. TVehicleAnimStateId CVehicleAnimation::GetState()
  289. {
  290.         return m_currentStateId;
  291. }
  292.  
  293. //------------------------------------------------------------------------
  294. bool CVehicleAnimation::ChangeState(TVehicleAnimStateId stateId)
  295. {
  296.         if (stateId <= InvalidVehicleAnimStateId || stateId > m_animationStates.size())
  297.                 return false;
  298.  
  299.         SAnimationState& animState = m_animationStates[stateId];
  300.  
  301.         m_currentStateId = stateId;
  302.  
  303.         if (IEntity* pEntity = m_pPartAnimated->GetEntity())
  304.         {
  305.                 if (ICharacterInstance* pCharInstance = pEntity->GetCharacter(m_pPartAnimated->GetSlot()))
  306.                 {
  307.                         ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  308.                         CRY_ASSERT(pSkeletonAnim);
  309.  
  310.                         if (pSkeletonAnim->GetNumAnimsInFIFO(m_layerId) > 0)
  311.                         {
  312.                                 const CAnimation& animation = pSkeletonAnim->GetAnimFromFIFO(m_layerId, 0);
  313.                                 const f32 animationNormalizedTime = pSkeletonAnim->GetAnimationNormalizedTime(&animation);
  314.                                 if (animationNormalizedTime > 0.0f)
  315.                                 {
  316.                                         float speed = pSkeletonAnim->GetLayerPlaybackScale(m_layerId) * -1.0f;
  317.                                         pSkeletonAnim->SetLayerPlaybackScale(m_layerId, speed);
  318.                                 }
  319.                                 else
  320.                                         StopAnimation();
  321.                         }
  322.                         else
  323.                                 StartAnimation();
  324.                 }
  325.         }
  326.  
  327.         return true;
  328. }
  329.  
  330. //------------------------------------------------------------------------
  331. string CVehicleAnimation::GetStateName(TVehicleAnimStateId stateId)
  332. {
  333.         if (stateId <= InvalidVehicleAnimStateId || stateId > m_animationStates.size())
  334.                 return "";
  335.  
  336.         SAnimationState& animState = m_animationStates[stateId];
  337.         return animState.name;
  338. }
  339.  
  340. //------------------------------------------------------------------------
  341. TVehicleAnimStateId CVehicleAnimation::GetStateId(const string& name)
  342. {
  343.         TVehicleAnimStateId stateId = 0;
  344.  
  345.         for (TAnimationStateVector::iterator ite = m_animationStates.begin(); ite != m_animationStates.end(); ++ite)
  346.         {
  347.                 SAnimationState& animState = *ite;
  348.                 if (animState.name == name)
  349.                         return stateId;
  350.  
  351.                 stateId++;
  352.         }
  353.  
  354.         return InvalidVehicleAnimStateId;
  355. }
  356.  
  357. //------------------------------------------------------------------------
  358. void CVehicleAnimation::SetSpeed(float speed)
  359. {
  360.         if (m_currentStateId == InvalidVehicleAnimStateId)
  361.                 return;
  362.  
  363.         const SAnimationState& animState = m_animationStates[m_currentStateId];
  364.  
  365.         IEntity* pEntity = m_pPartAnimated->GetEntity();
  366.         CRY_ASSERT(pEntity);
  367.  
  368.         ICharacterInstance* pCharInstance = pEntity->GetCharacter(m_pPartAnimated->GetSlot());
  369.         if (!pCharInstance)
  370.                 return;
  371.  
  372.         ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  373.         CRY_ASSERT(pSkeletonAnim);
  374.  
  375.         pSkeletonAnim->SetLayerPlaybackScale(m_layerId, max(min(speed, animState.speedMax), animState.speedMin));
  376.  
  377.         for (TAnimationStateMaterialVector::const_iterator ite = animState.materials.begin(), end = animState.materials.end(); ite != end; ++ite)
  378.         {
  379.                 const SAnimationStateMaterial& stateMaterial = *ite;
  380.  
  381.                 IMaterial* pPartMaterial = m_pPartAnimated->GetMaterial();
  382.  
  383.                 if (pPartMaterial)
  384.                 {
  385.                         if (IMaterial* pMaterial = FindMaterial(stateMaterial, pPartMaterial))
  386.                         {
  387.                                 float value = max(0.0f, min(1.0f, speed));
  388.  
  389.                                 if (stateMaterial.invertValue)
  390.                                 {
  391.                                         value = 1.0f - value;
  392.                                 }
  393.  
  394.                                 value = stateMaterial._min + (value * (stateMaterial._max - stateMaterial._min));
  395.  
  396.                                 pMaterial->SetGetMaterialParamFloat(stateMaterial.setting, value, false);
  397.                         }
  398.                 }
  399.         }
  400. }
  401.  
  402. //------------------------------------------------------------------------
  403. IMaterial* CVehicleAnimation::FindMaterial(const SAnimationStateMaterial& animStateMaterial, IMaterial* pMaterial)
  404. {
  405.         CRY_ASSERT(pMaterial);
  406.         if (!pMaterial)
  407.                 return NULL;
  408.  
  409.         if (animStateMaterial.material == pMaterial->GetName())
  410.                 return pMaterial;
  411.  
  412.         for (int i = 0; i < pMaterial->GetSubMtlCount(); i++)
  413.         {
  414.                 if (IMaterial* pSubMaterial = pMaterial->GetSubMtl(i))
  415.                 {
  416.                         if (IMaterial* pFoundSubMaterial = FindMaterial(animStateMaterial, pSubMaterial))
  417.                                 return pFoundSubMaterial;
  418.                 }
  419.         }
  420.  
  421.         return NULL;
  422. }
  423.  
  424. //------------------------------------------------------------------------
  425. void CVehicleAnimation::ToggleManualUpdate(bool isEnabled)
  426. {
  427.         if (m_layerId < 0 || !m_pPartAnimated)
  428.                 return;
  429.  
  430.         if (ICharacterInstance* pCharInstance =
  431.               m_pPartAnimated->GetEntity()->GetCharacter(m_pPartAnimated->GetSlot()))
  432.         {
  433.                 ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  434.                 CRY_ASSERT(pSkeletonAnim);
  435.  
  436.                 uint32 numAnimsLayer0 = pSkeletonAnim->GetNumAnimsInFIFO(m_layerId);
  437.                 if (0 < numAnimsLayer0)
  438.                 {
  439.                         CAnimation& animation = pSkeletonAnim->GetAnimFromFIFO(m_layerId, numAnimsLayer0 - 1);
  440.  
  441.                         if (isEnabled)
  442.                                 animation.SetStaticFlag(CA_MANUAL_UPDATE);
  443.                         else
  444.                                 animation.ClearStaticFlag(CA_MANUAL_UPDATE);
  445.                 }
  446.         }
  447. }
  448.  
  449. //------------------------------------------------------------------------
  450. float CVehicleAnimation::GetAnimTime(bool raw /*=false*/)
  451. {
  452.         if (m_layerId < 0 || !m_pPartAnimated)
  453.                 return 0.0f;
  454.  
  455.         if (ICharacterInstance* pCharInstance =
  456.               m_pPartAnimated->GetEntity()->GetCharacter(m_pPartAnimated->GetSlot()))
  457.         {
  458.                 ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  459.                 CRY_ASSERT(pSkeletonAnim);
  460.  
  461.                 uint32 numAnimsLayer0 = pSkeletonAnim->GetNumAnimsInFIFO(m_layerId);
  462.                 if (0 < numAnimsLayer0)
  463.                 {
  464.                         CAnimation& animation = pSkeletonAnim->GetAnimFromFIFO(m_layerId, numAnimsLayer0 - 1);
  465.                         const float animationNormalizedTime = pSkeletonAnim->GetAnimationNormalizedTime(&animation);
  466.                         if (!raw && animationNormalizedTime == 0.0f)
  467.                                 return 1.0f;
  468.  
  469.                         return max(0.0f, animationNormalizedTime);
  470.                 }
  471.                 else
  472.                 {
  473.                         return 1.0f;
  474.                 }
  475.         }
  476.  
  477.         return 0.0f;
  478. }
  479.  
  480. //------------------------------------------------------------------------
  481. void CVehicleAnimation::SetTime(float time, bool force)
  482. {
  483.         if (m_layerId < 0 || !m_pPartAnimated)
  484.                 return;
  485.  
  486.         if (ICharacterInstance* pCharInstance =
  487.               m_pPartAnimated->GetEntity()->GetCharacter(m_pPartAnimated->GetSlot()))
  488.         {
  489.                 ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  490.                 CRY_ASSERT(pSkeletonAnim);
  491.  
  492.                 uint32 numAnimsLayer0 = pSkeletonAnim->GetNumAnimsInFIFO(m_layerId);
  493.                 if (0 < numAnimsLayer0)
  494.                 {
  495.                         CAnimation& animation = pSkeletonAnim->GetAnimFromFIFO(m_layerId, numAnimsLayer0 - 1);
  496.                         if (force)
  497.                                 animation.SetStaticFlag(CA_MANUAL_UPDATE);
  498.  
  499.                         if (animation.HasStaticFlag(CA_MANUAL_UPDATE))
  500.                                 pSkeletonAnim->SetAnimationNormalizedTime(&animation, time);
  501.  
  502.                         //else
  503.                         //CryLogAlways("Error: can't use SetTime on a VehicleAnimation that wasn't set for manual updates.");
  504.                 }
  505.         }
  506. }
  507.  
  508. //------------------------------------------------------------------------
  509. bool CVehicleAnimation::IsUsingManualUpdates()
  510. {
  511.         if (ICharacterInstance* pCharInstance =
  512.               m_pPartAnimated->GetEntity()->GetCharacter(m_pPartAnimated->GetSlot()))
  513.         {
  514.                 ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
  515.                 CRY_ASSERT(pSkeletonAnim);
  516.  
  517.                 uint32 numAnimsLayer0 = pSkeletonAnim->GetNumAnimsInFIFO(m_layerId);
  518.                 if (0 < numAnimsLayer0)
  519.                 {
  520.                         CAnimation& animation = pSkeletonAnim->GetAnimFromFIFO(m_layerId, numAnimsLayer0 - 1);
  521.                         if (animation.HasStaticFlag(CA_MANUAL_UPDATE))
  522.                                 return true;
  523.                 }
  524.         }
  525.  
  526.         return false;
  527. }
  528.  
downloadVehicleAnimation.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