BVB Source Codes

CRYENGINE Show AnimatedCharacterPPS_Common.cpp Source code

Return Download CRYENGINE: download AnimatedCharacterPPS_Common.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "AnimatedCharacter.h"
  5. #include "CryAction.h"
  6. #include "AnimationGraphCVars.h"
  7. #include "PersistantDebug.h"
  8. #include <CryAnimation/IFacialAnimation.h>
  9.  
  10. #include "CryActionCVars.h"
  11.  
  12. #include <IViewSystem.h>
  13.  
  14. //--------------------------------------------------------------------------------
  15.  
  16. float ApplyAntiOscilationFilter(float value, float filtersize)
  17. {
  18.         float filterfraction = clamp_tpl(abs(value) / filtersize, 0.0f, 1.0f);
  19.         float filter = (0.5f - 0.5f * cos_tpl(filterfraction * gf_PI));
  20.         value *= filter;
  21.         return value;
  22. }
  23.  
  24. //--------------------------------------------------------------------------------
  25.  
  26. float GetQuatAbsAngle(const Quat& q)
  27. {
  28.         //float fwd = q.GetColumn1().y;
  29.         float fwd = q.GetFwdY();
  30.         return acos_tpl(fwd);
  31. }
  32.  
  33. //--------------------------------------------------------------------------------
  34.  
  35. f32 GetYaw(const Vec3& v0, const Vec3& v1)
  36. {
  37.         float a0 = atan2f(v0.y, v0.x);
  38.         float a1 = atan2f(v1.y, v1.x);
  39.         float a = a1 - a0;
  40.         if (a > gf_PI) a -= gf_PI2;
  41.         else if (a < -gf_PI)
  42.                 a += gf_PI2;
  43.         return a;
  44. }
  45.  
  46. //--------------------------------------------------------------------------------
  47.  
  48. f32 GetYaw(const Vec2& v0, const Vec2& v1)
  49. {
  50.         Vec3 _v0 = Vec3(v0.x, v0.y, 0);
  51.         Vec3 _v1 = Vec3(v1.x, v1.y, 0);
  52.         return GetYaw(_v0, _v1);
  53. }
  54.  
  55. //--------------------------------------------------------------------------------
  56.  
  57. QuatT ApplyWorldOffset(const QuatT& origin, const QuatT& offset)
  58. {
  59.         CRY_ASSERT(origin.IsValid());
  60.         CRY_ASSERT(offset.IsValid());
  61.         QuatT destination(origin.q * offset.q, origin.t + offset.t);
  62.         destination.q.Normalize();
  63.         CRY_ASSERT(destination.IsValid());
  64.         return destination;
  65. }
  66.  
  67. //--------------------------------------------------------------------------------
  68.  
  69. QuatT GetWorldOffset(const QuatT& origin, const QuatT& destination)
  70. {
  71.         CRY_ASSERT(origin.IsValid());
  72.         CRY_ASSERT(destination.IsValid());
  73.         QuatT offset(destination.t - origin.t, origin.q.GetInverted() * destination.q);
  74.         offset.q.Normalize();
  75.         CRY_ASSERT(offset.IsValid());
  76.         return offset;
  77. }
  78.  
  79. //--------------------------------------------------------------------------------
  80.  
  81. // Returns the actual unclamped distance and angle.
  82. QuatT GetClampedOffset(const QuatT& offset, float maxDistance, float maxAngle, float& distance, float& angle)
  83. {
  84.         QuatT clampedOffset;
  85.  
  86.         distance = offset.t.GetLength();
  87.         if (distance == 0.0f) distance = 0.000001f;
  88.         if (distance > maxDistance)
  89.         {
  90.                 clampedOffset.t = offset.t * maxDistance / distance;
  91.         }
  92.         else
  93.         {
  94.                 clampedOffset.t = offset.t;
  95.         }
  96.  
  97.         angle = RAD2DEG(GetQuatAbsAngle(offset.q));
  98.         if (angle > maxAngle)
  99.         {
  100.                 clampedOffset.q.SetNlerp(Quat(IDENTITY), offset.q, (angle == 0.0f) ? 0.0f : (maxAngle / angle));
  101.         }
  102.         else
  103.         {
  104.                 clampedOffset.q = offset.q;
  105.         }
  106.  
  107.         return clampedOffset;
  108. }
  109.  
  110. //--------------------------------------------------------------------------------
  111.  
  112. Vec3 CAnimatedCharacter::RemovePenetratingComponent(const Vec3& v, const Vec3& n) const
  113. {
  114.         float penetration = n.Dot(v);
  115.         if (penetration >= 0.0f)
  116.                 return v;
  117.  
  118.         return (v - n * penetration);
  119. }
  120.  
  121. //--------------------------------------------------------------------------------
  122.  
  123. QuatT /*CAnimatedCharacter::*/ ExtractHComponent(const QuatT& m) /*const*/
  124. {
  125.         ANIMCHAR_PROFILE_DETAILED;
  126.  
  127.         // NOTE: This function assumes there is no pitch/bank and totally ignores XY rotations.
  128.  
  129.         CRY_ASSERT(m.IsValid());
  130.  
  131.         QuatT ext;//(IDENTITY);
  132.         ext.t.x = m.t.x;
  133.         ext.t.y = m.t.y;
  134.         ext.t.z = 0.0f;
  135.  
  136.         /*
  137.            Ang3 a(m.q);
  138.            a.x = 0.0f;
  139.            a.y = 0.0f;
  140.            ext.q.SetRotationXYZ(a);
  141.          */
  142.         ext.q.SetRotationZ(m.q.GetRotZ());
  143.  
  144.         CRY_ASSERT(ext.IsValid());
  145.         return ext;
  146. }
  147.  
  148. //--------------------------------------------------------------------------------
  149.  
  150. QuatT /*CAnimatedCharacter::*/ ExtractVComponent(const QuatT& m) /*const*/
  151. {
  152.         ANIMCHAR_PROFILE_DETAILED;
  153.  
  154.         // NOTE: This function assumes there is no pitch/bank and totally ignores XY rotations.
  155.  
  156.         CRY_ASSERT(m.IsValid());
  157.  
  158.         QuatT ext;//(IDENTITY);
  159.         ext.t.z = m.t.z;
  160.         ext.t.x = 0.0f;
  161.         ext.t.y = 0.0f;
  162.  
  163.         /*
  164.            Ang3 a(m.q);
  165.            a.z = 0.0f;
  166.            ext.q.SetRotationXYZ(a);
  167.          */
  168.         ext.q.SetIdentity();
  169.  
  170.         CRY_ASSERT(ext.IsValid());
  171.         return ext;
  172. }
  173.  
  174. //--------------------------------------------------------------------------------
  175.  
  176. QuatT CombineHVComponents2D(const QuatT& cmpH, const QuatT& cmpV)
  177. {
  178.         ANIMCHAR_PROFILE_DETAILED;
  179.  
  180.         // NOTE: This function assumes there is no pitch/bank and totally ignores XY rotations.
  181.  
  182.         CRY_ASSERT(cmpH.IsValid());
  183.         CRY_ASSERT(cmpV.IsValid());
  184.  
  185.         QuatT cmb;
  186.         cmb.t.x = cmpH.t.x;
  187.         cmb.t.y = cmpH.t.y;
  188.         cmb.t.z = cmpV.t.z;
  189.         cmb.q.SetRotationZ(cmpH.q.GetRotZ());
  190.  
  191.         CRY_ASSERT(cmb.IsValid());
  192.  
  193.         return cmb;
  194. }
  195.  
  196. //--------------------------------------------------------------------------------
  197.  
  198. QuatT CombineHVComponents3D(const QuatT& cmpH, const QuatT& cmpV)
  199. {
  200.         ANIMCHAR_PROFILE_DETAILED;
  201.  
  202.         //return CombineHVComponents2D(cmpH, cmpV);
  203.  
  204.         CRY_ASSERT(cmpH.IsValid());
  205.         CRY_ASSERT(cmpV.IsValid());
  206.  
  207.         QuatT cmb;
  208.         cmb.t.x = cmpH.t.x;
  209.         cmb.t.y = cmpH.t.y;
  210.         cmb.t.z = cmpV.t.z;
  211.  
  212.         // TODO: This should be optimized!
  213.         Ang3 ah(cmpH.q);
  214.         Ang3 av(cmpV.q);
  215.         Ang3 a(av.x, av.y, ah.z);
  216.         cmb.q.SetRotationXYZ(a);
  217.  
  218.         CRY_ASSERT(cmb.IsValid());
  219.  
  220.         return cmb;
  221. }
  222.  
  223. //--------------------------------------------------------------------------------
  224.  
  225. // Override the entity's desired movement with the animation's for selected components
  226. QuatT CAnimatedCharacter::OverrideEntityMovement(const QuatT& ent, const QuatT& anim) const
  227. {
  228.         QuatT overriddenEntMovement = ent;
  229.  
  230.         if (m_moveOverride_useAnimXY)
  231.         {
  232.                 overriddenEntMovement.t.x = anim.t.x;
  233.                 overriddenEntMovement.t.y = anim.t.y;
  234.         }
  235.         if (m_moveOverride_useAnimZ)
  236.         {
  237.                 overriddenEntMovement.t.z = anim.t.z;
  238.         }
  239.         if (m_moveOverride_useAnimRot)
  240.         {
  241.                 overriddenEntMovement.q = anim.q;
  242.         }
  243.  
  244.         return overriddenEntMovement;
  245. }
  246.  
  247. //--------------------------------------------------------------------------------
  248.  
  249. QuatT CAnimatedCharacter::MergeMCM(const QuatT& ent, const QuatT& anim, bool flat) const
  250. {
  251.         ANIMCHAR_PROFILE_DETAILED;
  252.  
  253.         CRY_ASSERT(ent.IsValid());
  254.         CRY_ASSERT(anim.IsValid());
  255.  
  256.         EMovementControlMethod mcmh = GetMCMH();
  257.         EMovementControlMethod mcmv = GetMCMV();
  258.  
  259.         CRY_ASSERT(mcmh >= 0 && mcmh < eMCM_COUNT);
  260.         CRY_ASSERT(mcmv >= 0 && mcmv < eMCM_COUNT);
  261.  
  262.         if (mcmh == mcmv)
  263.         {
  264.                 switch (mcmh /*or mcmv*/)
  265.                 {
  266.                 case eMCM_Entity:
  267.                 case eMCM_ClampedEntity:
  268.                 case eMCM_SmoothedEntity:
  269.                         return ent;
  270.                 case eMCM_DecoupledCatchUp:
  271.                 case eMCM_Animation:
  272.                 case eMCM_AnimationHCollision:
  273.                         return anim;
  274.                 default:
  275.                         GameWarning("CAnimatedCharacter::MergeMCM() - Horizontal & Vertical MCM %s not implemented!", g_szMCMString[mcmh]);
  276.                         return ent;
  277.                 }
  278.         }
  279.  
  280.         QuatT mergedH, mergedV;
  281.         switch (mcmh)
  282.         {
  283.         case eMCM_Entity:
  284.         case eMCM_ClampedEntity:
  285.         case eMCM_SmoothedEntity:
  286.                 mergedH = ent;
  287.                 break;
  288.         case eMCM_DecoupledCatchUp:
  289.         case eMCM_Animation:
  290.         case eMCM_AnimationHCollision:
  291.                 mergedH = anim;
  292.                 break;
  293.         default:
  294.                 mergedH = ent;
  295.                 GameWarning("CAnimatedCharacter::MergeMCM() - Horizontal MCM %s not implemented!", g_szMCMString[mcmh]);
  296.                 break;
  297.         }
  298.  
  299.         switch (mcmv)
  300.         {
  301.         case eMCM_Entity:
  302.         case eMCM_ClampedEntity:
  303.         case eMCM_SmoothedEntity:
  304.                 mergedV = ent;
  305.                 break;
  306.         case eMCM_DecoupledCatchUp:
  307.         case eMCM_Animation:
  308.                 mergedV = anim;
  309.                 break;
  310.         default:
  311.                 mergedV = ent;
  312.                 GameWarning("CAnimatedCharacter::MergeMCM() - Vertical MCM %s not implemented!", g_szMCMString[mcmv]);
  313.                 break;
  314.         }
  315.  
  316.         QuatT merged;
  317.         if (flat)
  318.                 merged = CombineHVComponents2D(mergedH, mergedV);
  319.         else
  320.                 merged = CombineHVComponents3D(mergedH, mergedV);
  321.  
  322.         CRY_ASSERT(merged.IsValid());
  323.         return merged;
  324. }
  325.  
  326. //--------------------------------------------------------------------------------
  327.  
  328. void CAnimatedCharacter::UpdateMCMs()
  329. {
  330.         m_movementControlMethod[eMCMComponent_Horizontal][eMCMSlot_Debug] = (EMovementControlMethod)CAnimationGraphCVars::Get().m_MCMH;
  331.         m_movementControlMethod[eMCMComponent_Vertical][eMCMSlot_Debug] = (EMovementControlMethod)CAnimationGraphCVars::Get().m_MCMV;
  332.  
  333.         UpdateMCMComponent(eMCMComponent_Horizontal);
  334.         UpdateMCMComponent(eMCMComponent_Vertical);
  335.  
  336. #ifdef _DEBUG
  337.         if (DebugFilter() && ((CAnimationGraphCVars::Get().m_debugText != 0) || (CAnimationGraphCVars::Get().m_debugMovementControlMethods != 0)))
  338.         {
  339.                 //IRenderAuxText::Draw2dLabel(10, 75, 2.0f, (float*)&ColorF(1,1,1,1), false, "MCM H[%s] V[%s]", g_szMCMString[mcmh], g_szMCMString[mcmv]);
  340.  
  341.                 EMovementControlMethod mcmh = GetMCMH();
  342.                 EMovementControlMethod mcmv = GetMCMV();
  343.                 DebugHistory_AddValue("eDH_MovementControlMethodH", (float)mcmh);
  344.                 DebugHistory_AddValue("eDH_MovementControlMethodV", (float)mcmv);
  345.         }
  346. #endif
  347. }
  348.  
  349. //--------------------------------------------------------------------------------
  350.  
  351. // NOTE: To make sure the dynamic steering by PlayerMovementController doesn't overshoot:
  352. // - Force entity controlled clamping, so that the character 'warps' to the entity.
  353. // - Tweak the fading in of the clamping to make sure it is fully entity controlled *before* we reach the target.
  354. // - Force 'fly' mode in physics to disable momentum effects.
  355. void CAnimatedCharacter::PreventAnimTargetOvershooting(EMCMComponent component)
  356. {
  357.         const float ANIMTARGET_FORCE_ENTITY_DRIVEN_DISTANCE = 4.0f;
  358.         const float ANIMTARGET_FORCE_FLY_MODE_DISTANCE = 1.0f;
  359.  
  360.         if (m_pAnimTarget == NULL)
  361.                 return;
  362.  
  363.         EMovementControlMethod* mcm = m_movementControlMethod[component];
  364.         float dist = m_pAnimTarget->location.t.GetDistance(m_entLocation.t);
  365.  
  366.         if (dist < ANIMTARGET_FORCE_ENTITY_DRIVEN_DISTANCE)
  367.         {
  368.                 if (mcm[eMCMSlot_Cur] == eMCM_DecoupledCatchUp)
  369.                 {
  370.                         mcm[eMCMSlot_Cur] = eMCM_Entity;
  371.  
  372.                         if (mcm[eMCMSlot_Prev] != eMCM_Entity)
  373.                         {
  374.                                 mcm[eMCMSlot_Prev] = eMCM_Entity;
  375.                         }
  376.                 }
  377.         }
  378.  
  379.         if (m_pAnimTarget->activated || (dist < ANIMTARGET_FORCE_FLY_MODE_DISTANCE))
  380.         {
  381.                 m_requestedEntityMovementType = RequestedEntMovementType_Absolute;
  382.                 m_requestedIJump = 3; // fly mode
  383.         }
  384. }
  385.  
  386. //--------------------------------------------------------------------------------
  387.  
  388. void CAnimatedCharacter::UpdateMCMComponent(EMCMComponent component)
  389. {
  390.         ANIMCHAR_PROFILE_DETAILED;
  391.  
  392.         EMovementControlMethod* mcm = m_movementControlMethod[component];
  393.  
  394.         mcm[eMCMSlot_Cur] = eMCM_Entity;
  395.         m_currentMovementControlMethodTags[component] = "Default";
  396.         for (size_t i = eMCMSlotStack_Begin; i < eMCMSlotStack_End; ++i)
  397.         {
  398.                 const EMovementControlMethod mcmMethod = mcm[i];
  399.                 if (mcmMethod != eMCM_Undefined)
  400.                 {
  401.                         mcm[eMCMSlot_Cur] = mcmMethod;
  402.                         m_currentMovementControlMethodTags[component] = m_movementControlMethodTags[i];
  403.                 }
  404.         }
  405.  
  406.         PreventAnimTargetOvershooting(component);
  407.  
  408.         if (NoMovementOverride())
  409.         {
  410.                 mcm[eMCMSlot_Cur] = eMCM_Entity;
  411.                 m_currentMovementControlMethodTags[component] = "NoMoveOverride";
  412.         }
  413.  
  414.         if (InCutscene())
  415.         {
  416.                 mcm[eMCMSlot_Cur] = eMCM_Animation;
  417.                 m_currentMovementControlMethodTags[component] = "InCutscene";
  418.         }
  419.  
  420.         if (mcm[eMCMSlot_Debug] != eMCM_Undefined)
  421.         {
  422.                 mcm[eMCMSlot_Cur] = mcm[eMCMSlot_Debug];
  423.                 m_currentMovementControlMethodTags[component] = "Debug";
  424.         }
  425.  
  426.         if (mcm[eMCMSlot_Cur] != mcm[eMCMSlot_Prev])
  427.         {
  428.                 mcm[eMCMSlot_Prev] = mcm[eMCMSlot_Cur];
  429.                 m_elapsedTimeMCM[component] = 0.0f;
  430.         }
  431.  
  432.         if (gEnv->IsDedicated())
  433.         {
  434.                 mcm[eMCMSlot_Cur] = eMCM_Entity;
  435.                 m_currentMovementControlMethodTags[component] = "DedicatedServer";
  436.         }
  437. }
  438.  
  439. //--------------------------------------------------------------------------------
  440.  
  441. void CAnimatedCharacter::SetMovementControlMethods(EMovementControlMethod horizontal, EMovementControlMethod vertical)
  442. {
  443.         // vertical eMCM_AnimationHCollision is not allowed (H stands for horizontal)
  444.         if (vertical == eMCM_AnimationHCollision)
  445.                 vertical = eMCM_Animation;
  446.  
  447.         SetMovementControlMethods(eMCMSlot_Game, horizontal, vertical, "SetMCM");
  448. }
  449.  
  450. //--------------------------------------------------------------------------------
  451.  
  452. void CAnimatedCharacter::SetMovementControlMethods(EMCMSlot slot, EMovementControlMethod horizontal, EMovementControlMethod vertical, const char* tag)
  453. {
  454.         CRY_ASSERT((uint32)eMCMSlotStack_Begin <= (uint32)slot);
  455.         CRY_ASSERT((uint32)slot < (uint32)eMCMSlotStack_End);
  456.         CRY_ASSERT(vertical != eMCM_AnimationHCollision);
  457.  
  458.         m_movementControlMethodTags[slot] = tag;
  459.         m_movementControlMethod[eMCMComponent_Horizontal][slot] = horizontal;
  460.         m_movementControlMethod[eMCMComponent_Vertical][slot] = vertical;
  461. }
  462.  
  463. //--------------------------------------------------------------------------------
  464.  
  465. EMovementControlMethod CAnimatedCharacter::GetMCMH() const
  466. {
  467.         return (m_movementControlMethod[eMCMComponent_Horizontal][eMCMSlot_Cur]);
  468. }
  469.  
  470. //--------------------------------------------------------------------------------
  471.  
  472. EMovementControlMethod CAnimatedCharacter::GetMCMV() const
  473. {
  474.         return (m_movementControlMethod[eMCMComponent_Vertical][eMCMSlot_Cur]);
  475. }
  476.  
  477. //--------------------------------------------------------------------------------
  478.  
  479. void CAnimatedCharacter::SetNoMovementOverride(bool external)
  480. {
  481.         m_noMovementOverrideExternal = external;
  482. }
  483.  
  484. //--------------------------------------------------------------------------------
  485.  
  486. bool CAnimatedCharacter::NoMovementOverride() const
  487. {
  488.         return m_noMovementOverrideExternal;
  489. }
  490.  
  491. //--------------------------------------------------------------------------------
  492.  
  493. void CAnimatedCharacter::RefreshAnimTarget()
  494. {
  495.         if (m_pMannequinAGState)
  496.         {
  497.                 IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem();
  498.                 assert(pActorSystem != NULL);
  499.                 IActor* pActor = pActorSystem->GetActor(GetEntity()->GetId());
  500.                 IMovementController* pMovementController = pActor->GetMovementController();
  501.  
  502.                 m_pAnimTarget = pMovementController->GetExactPositioningTarget();
  503.         }
  504. }
  505.  
  506. //--------------------------------------------------------------------------------
  507.  
downloadAnimatedCharacterPPS_Common.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