BVB Source Codes

CRYENGINE Show PersonalInterestManager.cpp Source code

Return Download CRYENGINE: download PersonalInterestManager.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /********************************************************************
  4.    ---------------------------------------------------------------------
  5.    File name:   PersonalInterestManager.cpp
  6.    $Id$
  7.    $DateTime$
  8.    Description: Interest Manager (tracker) for interested individuals
  9.  
  10.    Notes:       Consider converting interest values float->int
  11.    -------------------------------------------------------------------------
  12.    History:
  13.    - 15 Feb 2010 : Heavily refactored by Ricardo Pillosu
  14.  *********************************************************************/
  15.  
  16. #include "StdAfx.h"
  17.  
  18. #include "PersonalInterestManager.h"
  19. #include "CentralInterestManager.h"
  20. #include "CAISystem.h"
  21. #include "Puppet.h"
  22. #include "AIActions.h"
  23. // For persistent debugging
  24. #include <CryGame/IGameFramework.h>
  25.  
  26. CPersonalInterestManager::CPersonalInterestManager(CAIActor* pAIActor) :
  27.         m_pCIM(NULL)
  28. {
  29.         Reset();
  30.  
  31.         if (pAIActor)
  32.         {
  33.                 Assign(pAIActor);
  34.         }
  35. }
  36.  
  37. //------------------------------------------------------------------------------------------------------------------------
  38.  
  39. // Clear tracking cache, clear assignment
  40. void CPersonalInterestManager::Reset()
  41. {
  42.         m_refAIActor.Reset();
  43.         m_refInterestDummy.Release();
  44.         m_IdInterestingEntity = 0;
  45.         m_IdLastInterestingEntity = 0;
  46.         m_timeLastInterestingEntity = 0.f;
  47.         m_Settings.Reset();
  48.         m_vOffsetInterestingEntity.zero();
  49.         m_bIsPlayingAction = false;
  50. }
  51.  
  52. bool CPersonalInterestManager::ForgetInterestingEntity()
  53. {
  54.         if (m_IdInterestingEntity > 0)
  55.         {
  56.                 m_IdLastInterestingEntity = m_IdInterestingEntity;
  57.                 m_timeLastInterestingEntity = GetAISystem()->GetFrameStartTime();
  58.                 m_pCIM->OnInterestEvent(
  59.                   IInterestListener::eIE_InterestStop,
  60.                   m_refAIActor.GetAIObject()->GetEntity()->GetId(),
  61.                   m_IdLastInterestingEntity);
  62.                 gAIEnv.pSmartObjectManager->RemoveSmartObjectState(gEnv->pEntitySystem->GetEntity(m_IdInterestingEntity), "Busy");
  63.                 m_IdInterestingEntity = 0;
  64.                 m_pCIM->AddDebugTag(GetAssigned()->GetEntityID(), "Nothing around");
  65.                 return true;
  66.         }
  67.  
  68.         return false;
  69. }
  70.  
  71. //------------------------------------------------------------------------------------------------------------------------
  72.  
  73. void CPersonalInterestManager::Assign(CAIActor* pAIActor)
  74. {
  75.         Assign(GetWeakRef(pAIActor));
  76. }
  77.  
  78. //------------------------------------------------------------------------------------------------------------------------
  79.  
  80. // You must also ensure the PIM pointer in the CAIActor is set to this object
  81. void CPersonalInterestManager::Assign(CWeakRef<CAIActor> refAIActor)
  82. {
  83.         // Check for redundant calls
  84.         if (m_refAIActor == refAIActor)
  85.                 return;
  86.  
  87.         CAIActor* pOldAIActor = m_refAIActor.GetAIObject();
  88.         IEntity* pOldEntity = pOldAIActor ? pOldAIActor->GetEntity() : NULL;
  89.         if (pOldEntity)
  90.         {
  91.                 gAIEnv.pSmartObjectManager->RemoveSmartObjectState(pOldEntity, "RegisteredActor");
  92.         }
  93.  
  94.         CAIActor* pNewAIActor = refAIActor.GetAIObject();
  95.         IEntity* pNewEntity = pNewAIActor ? pNewAIActor->GetEntity() : NULL;
  96.         if (pNewEntity)
  97.         {
  98.                 gAIEnv.pSmartObjectManager->AddSmartObjectState(pNewEntity, "RegisteredActor");
  99.         }
  100.  
  101.         Reset();
  102.  
  103.         // Assign
  104.         m_refAIActor = refAIActor;
  105.  
  106.         // Don't create interest dummy objects during serialization as the AI system itself is serialized later
  107.         //      (meaning the objects get leaked). The objects will be created by CObjectContainer::Serialize with the correct ID.
  108.         if (pNewAIActor && !gEnv->pSystem->IsSerializingFile())
  109.         {
  110.                 gAIEnv.pAIObjectManager->CreateDummyObject(m_refInterestDummy, "InterestDummy");
  111.         }
  112.  
  113.         m_pCIM = CCentralInterestManager::GetInstance();
  114.  
  115.         // Debug draw
  116.         if (m_pCIM->IsDebuggingEnabled())
  117.         {
  118.                 if (pOldEntity)
  119.                 {
  120.                         m_pCIM->AddDebugTag(pOldEntity->GetId(), "No longer interested");
  121.                 }
  122.  
  123.                 if (pNewEntity)
  124.                 {
  125.                         m_pCIM->AddDebugTag(pNewEntity->GetId(), "Interested");
  126.                 }
  127.         }
  128. }
  129.  
  130. //------------------------------------------------------------------------------------------------------------------------
  131.  
  132. bool CPersonalInterestManager::Update(bool bCloseToCamera)
  133. {
  134.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  135.  
  136.         if (m_bIsPlayingAction)
  137.                 return false;
  138.  
  139.         bool bRet = false;
  140.         IEntity* pUser = m_refAIActor.GetAIObject()->GetEntity();
  141.         const SEntityInterest* pMostInteresting = bCloseToCamera ? PickMostInteresting() : NULL;
  142.  
  143.         if (pMostInteresting)
  144.         {
  145.                 bRet = true;
  146.                 EntityId IdMostInteresting = pMostInteresting->GetEntityId();
  147.                 if (m_IdInterestingEntity != IdMostInteresting)
  148.                 {
  149.                         m_vOffsetInterestingEntity = pMostInteresting->m_vOffset;
  150.                         ForgetInterestingEntity();
  151.                         if (pMostInteresting->m_nbShared == 0)
  152.                         {
  153.                                 gAIEnv.pSmartObjectManager->AddSmartObjectState(gEnv->pEntitySystem->GetEntity(IdMostInteresting), "Busy");
  154.                         }
  155.                         m_pCIM->OnInterestEvent(IInterestListener::eIE_InterestStart, pUser->GetId(), IdMostInteresting);
  156.                         m_IdInterestingEntity = IdMostInteresting;
  157.  
  158.                         if (!pMostInteresting->m_sActionName.empty() && pMostInteresting->m_sActionName.compareNoCase("none") != 0)
  159.                         {
  160.                                 const IEntity* pMostInterestingEntity = pMostInteresting->GetEntity();
  161.                                 gAIEnv.pAIActionManager->ExecuteAIAction(
  162.                                   pMostInteresting->m_sActionName.c_str(), pUser, const_cast<IEntity*>(pMostInterestingEntity), 1, 0, this);
  163.                         }
  164.                 }
  165.         }
  166.         else
  167.         {
  168.                 bRet = ForgetInterestingEntity();
  169.         }
  170.  
  171.         return bRet;
  172. }
  173.  
  174. void CPersonalInterestManager::OnActionEvent(IAIAction::EActionEvent eActionEvent)
  175. {
  176.         if (m_IdInterestingEntity)
  177.         {
  178.                 CAIActor* pAIActor = m_refAIActor.GetAIObject();
  179.                 if (pAIActor)
  180.                 {
  181.                         IEntity* pUser = pAIActor->GetEntity();
  182.  
  183.                         //If no reference is available then exit without propagating the eActionEvent
  184.                         if (pUser)
  185.                         {
  186.                                 switch (eActionEvent)
  187.                                 {
  188.                                 case IAIAction::ActionEnd:
  189.                                         m_pCIM->OnInterestEvent(IInterestListener::eIE_InterestActionComplete, pUser->GetId(), m_IdInterestingEntity);
  190.                                         m_bIsPlayingAction = false;
  191.                                         break;
  192.  
  193.                                 case IAIAction::ActionStart:
  194.                                         m_bIsPlayingAction = true;
  195.                                         break;
  196.  
  197.                                 case IAIAction::ActionCancel:
  198.                                         m_pCIM->OnInterestEvent(IInterestListener::eIE_InterestActionCancel, pUser->GetId(), m_IdInterestingEntity);
  199.                                         m_bIsPlayingAction = false;
  200.                                         break;
  201.  
  202.                                 case IAIAction::ActionAbort:
  203.                                         m_pCIM->OnInterestEvent(IInterestListener::eIE_InterestActionAbort, pUser->GetId(), m_IdInterestingEntity);
  204.                                         m_bIsPlayingAction = false;
  205.                                         break;
  206.                                 }
  207.                         }
  208.                 }
  209.         }
  210. }
  211.  
  212. //------------------------------------------------------------------------------------------------------------------------
  213.  
  214. void CPersonalInterestManager::Serialize(TSerialize ser)
  215. {
  216.         ser.Value("m_refAIActor", m_refAIActor);
  217.         ser.Value("m_IdInterestingEntity", m_IdInterestingEntity);
  218.         ser.Value("m_IdLastInterestingEntity", m_IdLastInterestingEntity);
  219.         ser.Value("m_timeLastInterestingEntity", m_timeLastInterestingEntity);
  220.         ser.Value("m_vOffsetInterestingEntity", m_vOffsetInterestingEntity);
  221.         ser.Value("m_refInterestDummy", m_refInterestDummy);
  222.         ser.Value("m_Settings", m_Settings);
  223.         ser.Value("m_bIsPlayingAction", m_bIsPlayingAction);
  224.  
  225.         if (ser.IsReading())
  226.         {
  227.                 m_pCIM = CCentralInterestManager::GetInstance();
  228.         }
  229. }
  230.  
  231. //------------------------------------------------------------------------------------------------------------------------
  232.  
  233. void CPersonalInterestManager::SetSettings(bool bEnablePIM, float fInterestFilter, float fAngleCos)
  234. {
  235.         m_Settings.m_bEnablePIM = bEnablePIM;
  236.  
  237.         if (fInterestFilter >= 0.f)
  238.         {
  239.                 m_Settings.m_fInterestFilter = fInterestFilter;
  240.         }
  241.  
  242.         assert((-1.f <= fAngleCos) && (fAngleCos <= 1.f));
  243.         if ((-1.f <= fAngleCos) && (fAngleCos <= 1.f))
  244.         {
  245.                 m_Settings.m_fAngleCos = fAngleCos;
  246.         }
  247.  
  248.         if (m_pCIM->IsDebuggingEnabled())
  249.         {
  250.                 CryFixedStringT<32> sText;
  251.                 sText.Format("%s: Filter %0.1f Angle %0.1f",
  252.                              m_Settings.m_bEnablePIM ? "Enabled" : "Disabled",
  253.                              m_Settings.m_fInterestFilter,
  254.                              2.f * (RAD2DEG(acos(m_Settings.m_fAngleCos))));
  255.                 m_pCIM->AddDebugTag(GetAssigned()->GetEntityID(), sText);
  256.         }
  257. }
  258.  
  259. //------------------------------------------------------------------------------------------------------------------------
  260. const SEntityInterest* CPersonalInterestManager::PickMostInteresting() const
  261. {
  262.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  263.  
  264.         CAIActor* pAIActor = m_refAIActor.GetAIObject();
  265.         if (!pAIActor)
  266.         {
  267.                 assert(false);
  268.                 return NULL;
  269.         }
  270.  
  271.         const char* szActorClass = pAIActor->GetEntity()->GetClass()->GetName();
  272.  
  273.         Vec3 vActorPos = pAIActor->GetPos();
  274.         const SEntityInterest* pRet = NULL;
  275.         float fMostInterest = m_Settings.m_fInterestFilter;
  276.  
  277.         const float deltaTime = (GetAISystem()->GetFrameStartTime() - m_timeLastInterestingEntity).GetSeconds();
  278.  
  279.         CCentralInterestManager::TVecInteresting* pInterestingEntities = m_pCIM->GetInterestingEntities();
  280.         CCentralInterestManager::TVecInteresting::const_iterator it = pInterestingEntities->begin();
  281.         CCentralInterestManager::TVecInteresting::const_iterator itEnd = pInterestingEntities->end();
  282.         for (; it != itEnd; ++it)
  283.         {
  284.                 if (!(it->IsValid()))
  285.                         continue;
  286.  
  287.                 if (it->m_entityId == m_IdLastInterestingEntity)
  288.                 {
  289.                         if (deltaTime < it->m_fPause)
  290.                                 continue;
  291.                 }
  292.  
  293.                 if (!(it->SupportsActorClass(szActorClass)))
  294.                         continue;
  295.  
  296.                 Vec3 vToTarget = it->GetEntity()->GetPos() - vActorPos;
  297.                 float fDistToTargetSq = vToTarget.GetLengthSquared();
  298.                 float fRadius = it->m_fRadius;
  299.  
  300.                 if (fDistToTargetSq > square(fRadius))
  301.                         continue;
  302.  
  303.                 // Distance aspect - close objects have higher interest
  304.                 float& fMaxDist = fRadius;  // Use alias
  305.                 float fDist = clamp_tpl(sqrt_tpl(fDistToTargetSq), .1f, fMaxDist);
  306.                 float fDistanceAspect = (fMaxDist - fDist) / fMaxDist;
  307.  
  308.                 // Basic accumulation of interest
  309.                 float fAccumulated = (it->m_fInterest) * fDistanceAspect;
  310.  
  311.                 // Is this the most interesting so far?
  312.                 if (fMostInterest < fAccumulated)
  313.                 {
  314.                         // Check viewing angle
  315.                         float fDot = vToTarget.normalized().Dot(pAIActor->GetViewDir());
  316.                         if (fDot > m_Settings.m_fAngleCos)
  317.                         {
  318.                                 // Check if it's busy or not
  319.                                 if (it->m_nbShared ||
  320.                                     (m_IdInterestingEntity == it->m_entityId) ||
  321.                                     !gAIEnv.pSmartObjectManager->CheckSmartObjectStates(it->GetEntity(), "Busy"))
  322.                                 {
  323.                                         bool bSeen = m_pCIM->CanCastRays() ? CheckVisibility(*it) : true;
  324.                                         if (bSeen)
  325.                                         {
  326.                                                 fMostInterest = fAccumulated;
  327.                                                 pRet = &(*it);
  328.                                         }
  329.                                 }
  330.                         }
  331.                 }
  332.         }
  333.  
  334.         return pRet;
  335. }
  336.  
  337. //------------------------------------------------------------------------------------------------------------------------
  338.  
  339. IEntity* CPersonalInterestManager::GetInterestEntity() const
  340. {
  341.         return m_IdInterestingEntity ? gEnv->pEntitySystem->GetEntity(m_IdInterestingEntity) : NULL;
  342. }
  343.  
  344. //------------------------------------------------------------------------------------------------------------------------
  345. bool CPersonalInterestManager::CheckVisibility(const SEntityInterest& interestingRef) const
  346. {
  347.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  348.  
  349.         CAIActor* pAIActor = m_refAIActor.GetAIObject();
  350.         if (pAIActor)
  351.         {
  352.                 Vec3 vEyePos = pAIActor->GetPos();  // For an AI actor with a proxy, this is the eye position
  353.  
  354.                 // Select the point represented by the sum of the interesting target's position and the interesting target's offset.
  355.                 const IEntity* pTargetEntity = interestingRef.GetEntity();
  356.                 if (pTargetEntity)
  357.                 {
  358.                         //If no offset specified make sure existing entries work, by ensuring a 1 meter z-direction offset
  359.                         Vec3 vPoint2;
  360.                         Vec3 vOffset = interestingRef.m_vOffset;
  361.                         if (vOffset.IsZero())
  362.                         {
  363.                                 vPoint2 = pTargetEntity->GetPos();
  364.                                 vPoint2.z += 1.f;
  365.                         }
  366.                         else
  367.                         {
  368.                                 vPoint2 = pTargetEntity->GetWorldTM() * vOffset;
  369.                         }
  370.  
  371.                         ray_hit hits;
  372.                         int intersections = gEnv->pPhysicalWorld->RayWorldIntersection(vEyePos, vPoint2 - vEyePos, ent_all,
  373.                                                                                        rwi_stop_at_pierceable | rwi_colltype_any, &hits, 1, pAIActor->GetPhysics());
  374.  
  375.                         if (!intersections)
  376.                                 return true;
  377.  
  378.                         IEntity* pCollider = gEnv->pEntitySystem->GetEntityFromPhysics(hits.pCollider);
  379.                         return (pTargetEntity == pCollider);
  380.                 }
  381.         }
  382.  
  383.         return false;
  384. }
  385.  
  386. //------------------------------------------------------------------------------------------------------------------------
  387. Vec3 CPersonalInterestManager::GetInterestingPos() const
  388. {
  389.         // It is often appropriate to test against visible range before calling this (depending on interest type)
  390.         CAIActor* pAIActor = m_refAIActor.GetAIObject();
  391.         if (pAIActor)
  392.         {
  393.                 IEntity* pEntity = GetInterestEntity();
  394.                 if (pEntity)
  395.                 {
  396.                         return pEntity->GetWorldTM() * m_vOffsetInterestingEntity;
  397.                 }
  398.         }
  399.  
  400.         return ZERO;
  401. }
  402.  
  403. //------------------------------------------------------------------------------------------------------------------------
  404.  
  405. CWeakRef<CAIObject> CPersonalInterestManager::GetInterestDummyPoint()
  406. {
  407.         if (!IsInterested())
  408.                 return NILREF;
  409.  
  410.         CAIObject* pInterestDummy = m_refInterestDummy.GetAIObject();
  411.         if (pInterestDummy)
  412.                 pInterestDummy->SetPos(GetInterestingPos());
  413.  
  414.         return m_refInterestDummy.GetWeakRef();
  415. }
  416.  
  417. //------------------------------------------------------------------------------------------------------------------------
  418. ELookStyle CPersonalInterestManager::GetLookingStyle() const
  419. {
  420.         /* When this works we can really use a better selection of those values:
  421.            LOOKSTYLE_HARD,
  422.            LOOKSTYLE_HARD_NOLOWER,
  423.            LOOKSTYLE_SOFT,
  424.            LOOKSTYLE_SOFT_NOLOWER,
  425.          */
  426.  
  427.         return LOOKSTYLE_HARD;
  428. }
  429.  
downloadPersonalInterestManager.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