BVB Source Codes

CRYENGINE Show AnimationTrigger.cpp Source code

Return Download CRYENGINE: download AnimationTrigger.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.  
  5. #include <CryMath/Cry_Math.h>
  6. #include "AnimationTrigger.h"
  7. #include "AnimationGraphCVars.h"
  8. #include "PersistantDebug.h"
  9.  
  10. CAnimationTrigger::CAnimationTrigger()
  11.         : m_state(eS_Invalid)
  12.         , m_pos(ZERO)
  13.         , m_width(1.0f)
  14.         , m_posSize(1.0f)
  15.         , m_orient(Quat::CreateIdentity())
  16.         , m_cosOrientTolerance(1.0f)
  17.         , m_sideTime(0)
  18.         , m_distanceErrorFactor(1.0f)
  19.         , m_animMovementLength(0)
  20.         , m_distanceError(1000.0f)
  21.         , m_orientError(1000.0f)
  22.         , m_oldFwdDir(0.0f)
  23.         , m_userPos(ZERO)
  24.         , m_userOrient(Quat::CreateIdentity())
  25. {
  26.  
  27. }
  28.  
  29. CAnimationTrigger::CAnimationTrigger(const Vec3& pos, float width, const Vec3& triggerSize, const Quat& orient, float orientTolerance, float animMovementLength)
  30.         : m_pos(pos)
  31.         , m_width(width)
  32.         , m_posSize(triggerSize)
  33.         , m_orient(orient)
  34.         , m_cosOrientTolerance(cos(orientTolerance))
  35.         , m_sideTime(0)
  36.         , m_distanceErrorFactor(1.0f)
  37.         , m_animMovementLength(0)
  38.         , m_distanceError(1000.0f)
  39.         , m_orientError(1000.0f)
  40.         , m_oldFwdDir(0.0f)
  41.         , m_state(eS_Initializing)
  42.         , m_userPos(pos)
  43.         , m_userOrient(orient)
  44. {
  45.         CRY_ASSERT(m_pos.IsValid());
  46.         CRY_ASSERT(m_userPos.IsValid());
  47.         CRY_ASSERT(m_orient.IsValid());
  48.         CRY_ASSERT(m_userOrient.IsValid());
  49.         CRY_ASSERT(m_posSize.IsValid());
  50.         CRY_ASSERT(NumberValid(m_cosOrientTolerance));
  51.         CRY_ASSERT(NumberValid(m_width));
  52.  
  53.         // Make sure we have bigger than zero length,
  54.         // so that the error measurement is not zero no matter what direction.
  55.         m_animMovementLength = max(animMovementLength, 2.0f);
  56.  
  57.         // Make sure the trigger is not rotated, only Z-axis rotations are allowed
  58.         m_orient.v.x = m_orient.v.y = 0.0f;
  59.         m_orient.Normalize();
  60.         m_userOrient = m_orient;
  61. }
  62.  
  63. void CAnimationTrigger::Update(float frameTime, Vec3 userPos, Quat userOrient, bool allowTriggering)
  64. {
  65.         if (m_state == eS_Invalid)
  66.                 return;
  67.  
  68.         CRY_ASSERT(m_pos.IsValid());
  69.         CRY_ASSERT(m_userPos.IsValid());
  70.         CRY_ASSERT(m_orient.IsValid());
  71.         CRY_ASSERT(m_userOrient.IsValid());
  72.         CRY_ASSERT(m_posSize.IsValid());
  73.         CRY_ASSERT(NumberValid(m_cosOrientTolerance));
  74.  
  75.         CRY_ASSERT(NumberValid(frameTime));
  76.         CRY_ASSERT(userPos.IsValid());
  77.         CRY_ASSERT(userOrient.IsValid());
  78.  
  79.         m_userPos = userPos;
  80.         m_userOrient = userOrient;
  81.  
  82.         if (m_state == eS_Initializing)
  83.                 m_state = eS_Before;
  84.  
  85.         Plane threshold;
  86.         threshold.SetPlane(m_orient.GetColumn1(), m_pos);
  87.         if (threshold.DistFromPlane(userPos) >= 0.0f)
  88.         {
  89.                 if (m_sideTime < 0.0f)
  90.                         m_sideTime = 0.0f;
  91.                 else
  92.                         m_sideTime += frameTime;
  93.         }
  94.         else
  95.         {
  96.                 if (m_sideTime > 0.0f)
  97.                         m_sideTime = 0.0f;
  98.                 else
  99.                         m_sideTime -= frameTime;
  100.         }
  101.  
  102.         Vec3 curDir = userOrient.GetColumn1();
  103.         Vec3 wantDir = m_orient.GetColumn1();
  104.  
  105.         if (m_state == eS_Before)
  106.         {
  107.                 OBB triggerBox;
  108.                 triggerBox.SetOBB(Matrix33(m_orient), m_posSize + Vec3(0.5f, 0.5f, 0), ZERO);
  109.                 if (Overlap::Point_OBB(m_userPos, m_pos, triggerBox))
  110.                         m_state = eS_Optimizing;
  111.         }
  112.  
  113.         if ((m_state == eS_Optimizing) && allowTriggering)
  114.         {
  115.                 bool debug = (CAnimationGraphCVars::Get().m_debugExactPos != 0);
  116.                 CPersistantDebug* pPD = CCryAction::GetCryAction()->GetPersistantDebug();
  117.  
  118.                 Vec3 bump(0.0f, 0.0f, 0.1f);
  119.  
  120.                 Vec3 posDistanceError = m_userPos - m_pos;
  121.                 if (posDistanceError.z > -1.0f && posDistanceError.z < 1.0f)
  122.                         posDistanceError.z = 0;
  123.  
  124.                 Vec3 orientFwd = m_orient.GetColumn1();
  125.                 orientFwd.z = 0.0f;
  126.                 orientFwd.Normalize();
  127.                 Vec3 rotAnimMovementWanted = orientFwd * m_animMovementLength;
  128.  
  129.                 Vec3 userFwd = m_userOrient.GetColumn1();
  130.                 userFwd.z = 0.0f;
  131.                 userFwd.Normalize();
  132.                 Vec3 rotAnimMovementUser = userFwd * m_animMovementLength;
  133.  
  134.                 float cosRotError = orientFwd.Dot(userFwd);
  135.                 float rotError = CLAMP(m_cosOrientTolerance - cosRotError, 0.0f, 1.0f);
  136.                 //Vec3 rotDistanceError = rotAnimMovementUser - rotAnimMovementWanted;
  137.  
  138.                 float fwdDistance = fabsf(orientFwd.Dot(posDistanceError));
  139.                 float sideDistance = max(0.0f, sqrtf(MAX(0, posDistanceError.GetLengthSquared2D() - sqr(fwdDistance))) - m_width);
  140.  
  141.                 float deltaFwd = m_oldFwdDir < fwdDistance ? fwdDistance - m_oldFwdDir : 0.0f;
  142.                 m_oldFwdDir = fwdDistance;
  143.                 fwdDistance += deltaFwd * 0.5f;
  144.                 deltaFwd = max(0.1f, deltaFwd);
  145.  
  146.                 f32 distanceError = sqrtf(sqr(fwdDistance) + sqr(sideDistance)); // posDistanceError.len() * m_distanceErrorFactor;
  147.                 f32 temp = 1.0f - sqr(1.0f - rotError * rotError);
  148.                 temp = max(temp, 0.0f);                               //never do a sqrtf with a negative value
  149.                 f32 orientError = sqrtf(temp) * m_animMovementLength; // rotDistanceError.len();
  150.                 f32 totalDistanceError = distanceError + orientError;
  151.                 if (((m_distanceError * 1.05f) < distanceError) && ((m_orientError * 1.05f) < orientError) && (totalDistanceError < deltaFwd) ||
  152.                     (totalDistanceError < deltaFwd * 0.5f))
  153.                 {
  154.                         // found local minimum in distance error, force triggering.
  155.                         m_state = eS_Triggered;
  156.                         m_oldFwdDir = 0.0f;
  157.  
  158.                         if (debug)
  159.                         {
  160.                                 pPD->Begin("AnimationTrigger LocalMinima Triggered", false);
  161.                                 pPD->AddPlanarDisc(m_pos + bump, 0.0f, m_distanceError, ColorF(0, 1, 0, 0.5), 10.0f);
  162.                         }
  163.                 }
  164.                 else
  165.                 {
  166.                         m_distanceError = m_distanceError > distanceError ? distanceError : m_distanceError * 0.999f; // should timeout in ~2 secs. on 50 FPS
  167.                         m_orientError = m_orientError > orientError ? orientError : m_orientError - 0.0001f;
  168.  
  169.                         if (debug)
  170.                         {
  171.                                 pPD->Begin("AnimationTrigger LocalMinima Optimizing", true);
  172.                                 pPD->AddPlanarDisc(m_pos + bump, 0.0f, m_distanceError, ColorF(1, 1, 0, 0.5), 10.0f);
  173.                         }
  174.                 }
  175.  
  176.                 if (debug)
  177.                 {
  178.                         pPD->AddLine(m_userPos + bump, m_pos + bump, ColorF(1, 0, 0, 1), 10.0f);
  179.                         pPD->AddLine(m_userPos + rotAnimMovementUser + bump, m_pos + rotAnimMovementWanted + bump, ColorF(1, 0, 0, 1), 10.0f);
  180.                         pPD->AddLine(m_pos + bump, m_pos + rotAnimMovementWanted + bump, ColorF(1, 0.5, 0, 1), 10.0f);
  181.                         pPD->AddLine(m_userPos + bump, m_pos + rotAnimMovementUser + bump, ColorF(1, 0.5, 0, 1), 10.0f);
  182.                 }
  183.         }
  184.  
  185.         CRY_ASSERT(m_pos.IsValid());
  186.         CRY_ASSERT(m_userPos.IsValid());
  187.         CRY_ASSERT(m_orient.IsValid());
  188.         CRY_ASSERT(m_userOrient.IsValid());
  189.         CRY_ASSERT(m_posSize.IsValid());
  190.         CRY_ASSERT(NumberValid(m_cosOrientTolerance));
  191. }
  192.  
  193. void CAnimationTrigger::DebugDraw()
  194. {
  195.         if (m_state == eS_Invalid)
  196.                 return;
  197.  
  198.         CRY_ASSERT(m_pos.IsValid());
  199.         CRY_ASSERT(m_userPos.IsValid());
  200.         CRY_ASSERT(m_orient.IsValid());
  201.         CRY_ASSERT(m_userOrient.IsValid());
  202.         CRY_ASSERT(m_posSize.IsValid());
  203.         CRY_ASSERT(NumberValid(m_cosOrientTolerance));
  204.  
  205.         OBB triggerBox;
  206.         triggerBox.SetOBB(Matrix33(m_orient), m_state == eS_Before ? m_posSize + Vec3(0.5f, 0.5f, 0) : m_posSize, ZERO);
  207.  
  208.         ColorF clr(1, 0, 0, 1);
  209.  
  210.         Vec3 curDir = m_userOrient.GetColumn1();
  211.         Vec3 wantDir = m_orient.GetColumn1();
  212.         float cosAngle = curDir.Dot(wantDir);
  213.  
  214.         bool inAngleRange = false;
  215.  
  216.         switch (m_state)
  217.         {
  218.         case eS_Initializing:
  219.                 clr = ColorF(1, 0, 0, 0.3f);
  220.                 break;
  221.         case eS_Before:
  222.                 inAngleRange = cosAngle < 2 * m_cosOrientTolerance;
  223.                 clr = ColorF(1, 0, 1, 0.3f);
  224.                 break;
  225.         case eS_Optimizing:
  226.                 inAngleRange = cosAngle < m_cosOrientTolerance;
  227.                 clr = ColorF(1, 1, 0, 1);
  228.                 break;
  229.         case eS_Triggered:
  230.                 inAngleRange = true;
  231.                 clr = ColorF(1, 0, 1, 0.1f);
  232.                 break;
  233.         }
  234.  
  235.         gEnv->pRenderer->GetIRenderAuxGeom()->DrawOBB(triggerBox, Matrix34::CreateTranslationMat(m_pos), true, clr, eBBD_Faceted);
  236.  
  237.         clr = ColorF(0, 1, 0, 1);
  238.         if (inAngleRange)
  239.                 clr = ColorF(1, 0, 0, 1);
  240.         static const int NUM_STEPS = 20;
  241.         for (int i = 0; i < NUM_STEPS; i++)
  242.         {
  243.                 float t = float(i) / float(NUM_STEPS - 1);
  244.                 Vec3 dir = Quat::CreateSlerp(m_userOrient, m_orient, t).GetColumn1();
  245.                 gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(m_pos, clr, m_pos + 4.0f * dir, clr);
  246.         }
  247. }
  248.  
  249. void CAnimationTrigger::ResetRadius(const Vec3& triggerSize, float orientTolerance)
  250. {
  251.         CRY_ASSERT(m_pos.IsValid());
  252.         CRY_ASSERT(m_userPos.IsValid());
  253.         CRY_ASSERT(m_orient.IsValid());
  254.         CRY_ASSERT(m_userOrient.IsValid());
  255.         CRY_ASSERT(m_posSize.IsValid());
  256.         CRY_ASSERT(NumberValid(m_cosOrientTolerance));
  257.  
  258.         if (m_state == eS_Invalid)
  259.                 return;
  260.         m_state = eS_Initializing;
  261.         m_posSize = triggerSize;
  262.         m_cosOrientTolerance = cos(orientTolerance);
  263.  
  264.         // TODO: Update should not be called here. Maybe it's only used to set some values or something, not really an update.
  265.         Update(0.0f, m_userPos, m_userOrient, false);
  266. }
  267.  
downloadAnimationTrigger.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