BVB Source Codes

CRYENGINE Show VisionMap.cpp Source code

Return Download CRYENGINE: download VisionMap.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.  
  8.    -------------------------------------------------------------------------
  9.    History:
  10.    - 4:3:2009   11:38 : Created by M谩rcio Martins
  11.  
  12. *************************************************************************/
  13. #include "StdAfx.h"
  14. #include "VisionMap.h"
  15.  
  16. #include "DebugDrawContext.h"
  17. #include <CryAISystem/VisionMapTypes.h>
  18.  
  19. namespace
  20. {
  21. static const float positionEpsilon = 0.05f;
  22. static const float orientationEpsilon = 0.05f;
  23. }
  24.  
  25. CVisionMap::CVisionMap()
  26.         : m_visionIdCounter(0)
  27. {
  28.         Reset();
  29. }
  30.  
  31. CVisionMap::~CVisionMap()
  32. {
  33.         Reset();
  34. }
  35.  
  36. void CVisionMap::Reset()
  37. {
  38.         static_assert(ObserverParams::MaxSkipListSize + ObservableParams::MaxSkipListSize <= RayCastRequest::MaxSkipListCount, "Unexpected enum value!");
  39.  
  40.         for (Observers::iterator observerIt = m_observers.begin(), end = m_observers.end(); observerIt != end; ++observerIt)
  41.         {
  42.                 ObserverInfo& observerInfo = observerIt->second;
  43.  
  44.                 ReleaseSkipList(&observerInfo.observerParams.skipList[0], observerInfo.observerParams.skipListSize);
  45.                 DeletePendingRays(observerIt->second.pvs);
  46.         }
  47.  
  48.         for (Observables::iterator observableIt = m_observables.begin(), end = m_observables.end(); observableIt != end; ++observableIt)
  49.         {
  50.                 ObservableInfo& observableInfo = observableIt->second;
  51.  
  52.                 ReleaseSkipList(&observableInfo.observableParams.skipList[0], observableInfo.observableParams.skipListSize);
  53.         }
  54.  
  55. #if VISIONMAP_DEBUG
  56.         m_debugTimer = 0.0f;
  57.         m_numberOfPVSUpdatesThisFrame = 0;
  58.         m_numberOfVisibilityUpdatesThisFrame = 0;
  59.         m_numberOfRayCastsSubmittedThisFrame = 0;
  60.         m_debugObserverVisionID = VisionID();
  61.         m_debugObservableVisionID = VisionID();
  62.         memset(m_latencyInfo, 0, sizeof(m_latencyInfo));
  63.         memset(m_pendingRayCounts, 0, sizeof(m_pendingRayCounts));
  64.  
  65.         m_pvsUpdateQueueLatency = 0.0f;
  66.         m_visibilityUpdateQueueLatency = 0.0f;
  67. #endif
  68.  
  69.         m_observers.clear();
  70.  
  71.         m_observablesGrid.clear();
  72.         m_observables.clear();
  73.  
  74.         m_observerPVSUpdateQueue.clear();
  75.         m_observerVisibilityUpdateQueue.clear();
  76. }
  77.  
  78. VisionID CVisionMap::CreateVisionID(const char* name)
  79. {
  80.         ++m_visionIdCounter;
  81.         while (!m_visionIdCounter)
  82.                 ++m_visionIdCounter;
  83.  
  84.         return VisionID(m_visionIdCounter, name);
  85. }
  86.  
  87. void CVisionMap::RegisterObserver(const ObserverID& observerID, const ObserverParams& observerParams)
  88. {
  89.         if (!observerID)
  90.                 return;
  91.  
  92.         m_observers.insert(Observers::value_type(observerID, ObserverInfo(observerID)));
  93.  
  94.         ObserverChanged(observerID, observerParams, eChangedAll);
  95. }
  96.  
  97. void CVisionMap::UnregisterObserver(const ObserverID& observerID)
  98. {
  99.         if (!observerID)
  100.                 return;
  101.  
  102.         Observers::iterator observerIt = m_observers.find(observerID);
  103.         if (observerIt == m_observers.end())
  104.                 return;
  105.  
  106.         ObserverInfo& observerInfo = observerIt->second;
  107.         ReleaseSkipList(&observerInfo.observerParams.skipList[0], observerInfo.observerParams.skipListSize);
  108.         DeletePendingRays(observerInfo.pvs);
  109.  
  110.         if (observerInfo.queuedForPVSUpdate)
  111.                 stl::find_and_erase(m_observerPVSUpdateQueue, observerInfo.observerID);
  112.  
  113.         if (observerInfo.queuedForVisibilityUpdate)
  114.                 stl::find_and_erase(m_observerVisibilityUpdateQueue, observerInfo.observerID);
  115.  
  116.         for (const auto& pvsIdEntryPair : observerInfo.pvs)
  117.         {
  118.                 const PVSEntry& pvsEntry = pvsIdEntryPair.second;
  119.                 if (pvsEntry.visible)
  120.                 {
  121.                         TriggerObserverCallback(observerInfo, pvsEntry.observableInfo, false);
  122.                         TriggerObservableCallback(observerInfo, pvsEntry.observableInfo, false);
  123.                 }
  124.         }
  125.  
  126.         m_observers.erase(observerIt);
  127. }
  128.  
  129. void CVisionMap::RegisterObservable(const ObservableID& observableID, const ObservableParams& observerParams)
  130. {
  131.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  132.  
  133.         if (!observableID)
  134.                 return;
  135.  
  136.         assert(observerParams.observablePositionsCount > 0);
  137.         assert(observerParams.observablePositionsCount <= ObservableParams::MaxPositionCount);
  138.  
  139.         std::pair<Observables::iterator, bool> result = m_observables.insert(Observables::value_type(observableID, ObservableInfo(observableID, ObservableParams())));
  140.  
  141.         ObservableInfo& insertedObservableInfo = result.first->second;
  142.         m_observablesGrid.insert(insertedObservableInfo.observableParams.observablePositions[0], &insertedObservableInfo);
  143.  
  144.         ObservableChanged(observableID, observerParams, eChangedAll);
  145.  
  146.         for (Observers::iterator observerIt = m_observers.begin(), end = m_observers.end(); observerIt != end; ++observerIt)
  147.         {
  148.                 ObserverInfo& observerInfo = observerIt->second;
  149.                 if (ShouldBeAddedToObserverPVS(observerInfo, insertedObservableInfo))
  150.                         AddToObserverPVS(observerInfo, insertedObservableInfo);
  151.         }
  152. }
  153.  
  154. void CVisionMap::UnregisterObservable(const ObservableID& observableID)
  155. {
  156.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  157.  
  158.         if (!observableID)
  159.                 return;
  160.  
  161.         Observables::iterator observableIt = m_observables.find(observableID);
  162.         if (observableIt == m_observables.end())
  163.                 return;
  164.  
  165.         ObservableInfo& observableInfo = observableIt->second;
  166.         ReleaseSkipList(&observableInfo.observableParams.skipList[0], observableInfo.observableParams.skipListSize);
  167.  
  168.         for (Observers::iterator observerIt = m_observers.begin(), end = m_observers.end(); observerIt != end; ++observerIt)
  169.         {
  170.                 if (observerIt->first == observableID)
  171.                         continue;
  172.  
  173.                 ObserverInfo& observerInfo = observerIt->second;
  174.  
  175.                 PVS::iterator pvsIt = observerInfo.pvs.find(observableID);
  176.                 if (pvsIt == observerInfo.pvs.end())
  177.                         continue;
  178.  
  179.                 PVSEntry& pvsEntry = pvsIt->second;
  180.  
  181.                 if (pvsEntry.visible)
  182.                 {
  183.                         TriggerObserverCallback(observerInfo, pvsEntry.observableInfo, false);
  184.                         TriggerObservableCallback(observerInfo, pvsEntry.observableInfo, false);
  185.                 }
  186.  
  187.                 DeletePendingRay(pvsEntry);
  188.  
  189.                 observerInfo.needsPVSUpdate = true;
  190.                 observerInfo.pvs.erase(pvsIt);
  191.         }
  192.  
  193.         m_observablesGrid.erase(observableInfo.observableParams.observablePositions[0], &observableInfo);
  194.         m_observables.erase(observableIt);
  195. }
  196.  
  197. void CVisionMap::ObserverChanged(const ObserverID& observerID, const ObserverParams& newObserverParams, uint32 hint)
  198. {
  199.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  200.  
  201.         Observers::iterator it = m_observers.find(observerID);
  202.         assert(it != m_observers.end());
  203.         if (it == m_observers.end())
  204.                 return;
  205.  
  206.         bool needsUpdate = false;
  207.         ObserverInfo& observerInfo = it->second;
  208.         ObserverParams& currentObserverParams = observerInfo.observerParams;
  209.  
  210.         if (hint & eChangedFaction)
  211.         {
  212.                 currentObserverParams.faction = newObserverParams.faction;
  213.                 needsUpdate = true;
  214.         }
  215.  
  216.         if (hint & eChangedFactionsToObserveMask)
  217.         {
  218.                 currentObserverParams.factionsToObserveMask = newObserverParams.factionsToObserveMask;
  219.         }
  220.  
  221.         if (hint & eChangedTypesToObserveMask)
  222.         {
  223.                 currentObserverParams.typesToObserveMask = newObserverParams.typesToObserveMask;
  224.         }
  225.  
  226.         if (hint & eChangedSightRange)
  227.         {
  228.                 currentObserverParams.sightRange = newObserverParams.sightRange;
  229.                 needsUpdate = true;
  230.         }
  231.  
  232.         if (hint & eChangedFOV)
  233.         {
  234.                 currentObserverParams.fovCos = newObserverParams.fovCos;
  235.                 needsUpdate = true;
  236.         }
  237.  
  238.         if (hint & eChangedPosition)
  239.         {
  240.                 if (!IsEquivalent(currentObserverParams.eyePosition, newObserverParams.eyePosition, positionEpsilon))
  241.                 {
  242.                         currentObserverParams.eyePosition = newObserverParams.eyePosition;
  243.                         needsUpdate = true;
  244.                 }
  245.         }
  246.  
  247.         if (hint & eChangedOrientation)
  248.         {
  249.                 if (!IsEquivalent(currentObserverParams.eyeDirection, newObserverParams.eyeDirection, orientationEpsilon))
  250.                 {
  251.                         currentObserverParams.eyeDirection = newObserverParams.eyeDirection;
  252.                         needsUpdate = true;
  253.                 }
  254.         }
  255.  
  256.         if (hint & eChangedSkipList)
  257.         {
  258.                 assert(newObserverParams.skipListSize <= ObserverParams::MaxSkipListSize);
  259.  
  260.                 uint32 skipListSize = std::min<uint32>(newObserverParams.skipListSize, ObserverParams::MaxSkipListSize);
  261.                 AcquireSkipList(const_cast<IPhysicalEntity**>(&newObserverParams.skipList[0]), skipListSize);
  262.                 ReleaseSkipList(&currentObserverParams.skipList[0], currentObserverParams.skipListSize);
  263.  
  264.                 currentObserverParams.skipListSize = skipListSize;
  265.                 for (int i = 0; i < currentObserverParams.skipListSize; ++i)
  266.                         currentObserverParams.skipList[i] = newObserverParams.skipList[i];
  267.  
  268. #ifdef _DEBUG
  269.                 std::sort(&currentObserverParams.skipList[0], &currentObserverParams.skipList[currentObserverParams.skipListSize]);
  270.  
  271.                 for (uint i = 1; i < currentObserverParams.skipListSize; ++i)
  272.                 {
  273.                         assert(currentObserverParams.skipList[i - 1] != currentObserverParams.skipList[i]);
  274.                 }
  275. #endif
  276.         }
  277.  
  278.         if (hint & eChangedCallback)
  279.         {
  280.                 currentObserverParams.callback = newObserverParams.callback;
  281.         }
  282.  
  283.         if (hint & eChangedUserData)
  284.         {
  285.                 currentObserverParams.userData = newObserverParams.userData;
  286.         }
  287.  
  288.         if (hint & eChangedTypeMask)
  289.         {
  290.                 currentObserverParams.typeMask = newObserverParams.typeMask;
  291.                 needsUpdate = true;
  292.         }
  293.  
  294.         if (hint & eChangedRaycastFlags)
  295.         {
  296.                 currentObserverParams.raycastFlags = newObserverParams.raycastFlags;
  297.                 needsUpdate = true;
  298.         }
  299.  
  300.         if (hint & eChangedEntityId)
  301.         {
  302.                 currentObserverParams.entityId = newObserverParams.entityId;
  303.         }
  304.  
  305.         if (hint & eChangedUserCondition)
  306.         {
  307.                 needsUpdate = true;
  308.         }
  309.  
  310.         if (hint & eChangedUserConditionCallback)
  311.         {
  312.                 currentObserverParams.userConditionCallback = newObserverParams.userConditionCallback;
  313.                 needsUpdate = true;
  314.         }
  315.  
  316.         if (needsUpdate)
  317.         {
  318.                 observerInfo.needsPVSUpdate = true;
  319.                 observerInfo.needsVisibilityUpdate = true;
  320.                 observerInfo.updateAllVisibilityStatus = true;
  321.         }
  322. }
  323.  
  324. void CVisionMap::ObservableChanged(const ObservableID& observableID, const ObservableParams& newObservableParams, uint32 hint)
  325. {
  326.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  327.  
  328.         Observables::iterator observableIt = m_observables.find(observableID);
  329.         assert(observableIt != m_observables.end());
  330.         if (observableIt == m_observables.end())
  331.                 return;
  332.  
  333.         ObservableInfo& observableInfo = observableIt->second;
  334.         ObservableParams& currentObservableParams = observableInfo.observableParams;
  335.  
  336.         bool observableVisibilityPotentiallyChanged = false;
  337.  
  338.         if (hint & eChangedPosition)
  339.         {
  340.                 assert(newObservableParams.observablePositionsCount > 0);
  341.                 assert(newObservableParams.observablePositionsCount <= ObservableParams::MaxPositionCount);
  342.                 assert(newObservableParams.observablePositions[0].IsValid());
  343.  
  344.                 Vec3 oldPosition = currentObservableParams.observablePositions[0];
  345.  
  346.                 if (!IsEquivalent(oldPosition, newObservableParams.observablePositions[0], positionEpsilon))
  347.                 {
  348.                         FRAME_PROFILER("CVisionMap::ObservableChanged_UpdateHashGrid", GetISystem(), PROFILE_AI);
  349.  
  350.                         currentObservableParams.observablePositions[0] = newObservableParams.observablePositions[0];
  351.                         m_observablesGrid.move(m_observablesGrid.find(oldPosition, &observableInfo), newObservableParams.observablePositions[0]);
  352.                         observableVisibilityPotentiallyChanged = true;
  353.  
  354.                         currentObservableParams.observablePositionsCount = newObservableParams.observablePositionsCount;
  355.  
  356.                         for (int i = 1; i < currentObservableParams.observablePositionsCount; ++i)
  357.                         {
  358.                                 assert(newObservableParams.observablePositions[i].IsValid());
  359.                                 currentObservableParams.observablePositions[i] = newObservableParams.observablePositions[i];
  360.                         }
  361.                 }
  362.         }
  363.  
  364.         if (hint & eChangedUserData)
  365.         {
  366.                 currentObservableParams.userData = newObservableParams.userData;
  367.         }
  368.  
  369.         if (hint & eChangedCallback)
  370.         {
  371.                 currentObservableParams.callback = newObservableParams.callback;
  372.         }
  373.  
  374.         if (hint & eChangedSkipList)
  375.         {
  376.                 FRAME_PROFILER("CVisionMap::ObservableChanged_UpdateSkipList", GetISystem(), PROFILE_AI);
  377.  
  378.                 assert(newObservableParams.skipListSize <= ObserverParams::MaxSkipListSize);
  379.  
  380.                 uint32 skipListSize = std::min<uint32>(newObservableParams.skipListSize, ObserverParams::MaxSkipListSize);
  381.                 AcquireSkipList(const_cast<IPhysicalEntity**>(&newObservableParams.skipList[0]), skipListSize);
  382.                 ReleaseSkipList(&currentObservableParams.skipList[0], currentObservableParams.skipListSize);
  383.  
  384.                 currentObservableParams.skipListSize = skipListSize;
  385.                 for (int i = 0; i < currentObservableParams.skipListSize; ++i)
  386.                         currentObservableParams.skipList[i] = newObservableParams.skipList[i];
  387.  
  388. #ifdef _DEBUG
  389.                 std::sort(&currentObservableParams.skipList[0], &currentObservableParams.skipList[currentObservableParams.skipListSize]);
  390.  
  391.                 for (uint i = 1; i < currentObservableParams.skipListSize; ++i)
  392.                 {
  393.                         assert(currentObservableParams.skipList[i - 1] != currentObservableParams.skipList[i]);
  394.                 }
  395. #endif
  396.         }
  397.  
  398.         if (hint & eChangedFaction)
  399.         {
  400.                 currentObservableParams.faction = newObservableParams.faction;
  401.                 observableVisibilityPotentiallyChanged = true;
  402.         }
  403.  
  404.         if (hint & eChangedTypeMask)
  405.         {
  406.                 currentObservableParams.typeMask = newObservableParams.typeMask;
  407.                 observableVisibilityPotentiallyChanged = true;
  408.         }
  409.  
  410.         if (hint & eChangedEntityId)
  411.         {
  412.                 currentObservableParams.entityId = newObservableParams.entityId;
  413.         }
  414.  
  415.         if (hint & eChangedUserCondition)
  416.         {
  417.                 observableVisibilityPotentiallyChanged = true;
  418.         }
  419.  
  420.         if (observableVisibilityPotentiallyChanged)
  421.         {
  422.                 FRAME_PROFILER("CVisionMap::ObservableChanged_VisibilityChanged", GetISystem(), PROFILE_AI);
  423.  
  424.                 CTimeValue now = gEnv->pTimer->GetFrameStartTime();
  425.  
  426.                 for (Observers::iterator observersIt = m_observers.begin(), end = m_observers.end(); observersIt != end; ++observersIt)
  427.                 {
  428.                         ObserverInfo& observerInfo = observersIt->second;
  429.  
  430.                         if (observerInfo.observerID == observableID)
  431.                                 continue;
  432.  
  433.                         if (observerInfo.needsPVSUpdate)
  434.                                 continue;
  435.  
  436.                         PVS::iterator pvsIt = observerInfo.pvs.find(observableID);
  437.                         bool inObserverPVS = pvsIt != observerInfo.pvs.end();
  438.  
  439.                         if (ShouldObserve(observerInfo, observableInfo))
  440.                         {
  441.                                 if (inObserverPVS)
  442.                                 {
  443.                                         PVSEntry& pvsEntry = pvsIt->second;
  444.                                         pvsEntry.needsUpdate = true;
  445.                                         observerInfo.needsVisibilityUpdate = true;
  446.                                 }
  447.                                 else
  448.                                 {
  449.                                         AddToObserverPVS(observerInfo, observableInfo);
  450.                                 }
  451.                         }
  452.                         else
  453.                         {
  454.                                 if (inObserverPVS)
  455.                                 {
  456.                                         PVSEntry& pvsEntry = pvsIt->second;
  457.  
  458.                                         if (pvsEntry.visible)
  459.                                         {
  460.                                                 TriggerObserverCallback(observerInfo, observableInfo, false);
  461.                                                 TriggerObservableCallback(observerInfo, observableInfo, false);
  462.                                         }
  463.  
  464.                                         DeletePendingRay(pvsEntry);
  465.  
  466.                                         observerInfo.pvs.erase(pvsIt);
  467.                                 }
  468.                         }
  469.                 }
  470.         }
  471. }
  472.  
  473. bool CVisionMap::IsVisible(const ObserverID& observerID, const ObservableID& observableID) const
  474. {
  475.         Observers::const_iterator observerIt = m_observers.find(observerID);
  476.         if (observerIt == m_observers.end())
  477.                 return false;
  478.  
  479.         const ObserverInfo& observerInfo = observerIt->second;
  480.         PVS::const_iterator pvsIt = observerInfo.pvs.find(observableID);
  481.         if (pvsIt == observerInfo.pvs.end())
  482.                 return false;
  483.  
  484.         return pvsIt->second.visible;
  485. }
  486.  
  487. const ObserverParams* CVisionMap::GetObserverParams(const ObserverID& observerID) const
  488. {
  489.         Observers::const_iterator obsIt = m_observers.find(observerID);
  490.         if (obsIt == m_observers.end())
  491.                 return 0;
  492.  
  493.         const ObserverInfo& observerInfo = obsIt->second;
  494.  
  495.         return &observerInfo.observerParams;
  496. }
  497.  
  498. const ObservableParams* CVisionMap::GetObservableParams(const ObservableID& observableID) const
  499. {
  500.         Observables::const_iterator obsIt = m_observables.find(observableID);
  501.         if (obsIt == m_observables.end())
  502.                 return 0;
  503.  
  504.         const ObservableInfo& observableInfo = obsIt->second;
  505.  
  506.         return &observableInfo.observableParams;
  507. }
  508.  
  509. void CVisionMap::Update(float frameTime)
  510. {
  511.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  512.  
  513. #if VISIONMAP_DEBUG
  514.         m_numberOfPVSUpdatesThisFrame = 0;
  515.         m_numberOfVisibilityUpdatesThisFrame = 0;
  516.         m_numberOfRayCastsSubmittedThisFrame = 0;
  517.         m_debugTimer += frameTime;
  518. #endif
  519.  
  520.         UpdateObservers();
  521. }
  522.  
  523. bool CVisionMap::IsInSightRange(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const
  524. {
  525.         if (observerInfo.observerParams.sightRange <= 0.0f)
  526.                 return true;
  527.  
  528.         const float distance = (observableInfo.observableParams.observablePositions[0] - observerInfo.observerParams.eyePosition).len();
  529.         return distance <= observerInfo.observerParams.sightRange;
  530. }
  531.  
  532. bool CVisionMap::IsInFoV(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const
  533. {
  534.         if (observerInfo.observerParams.fovCos <= -1.0f)
  535.                 return true;
  536.  
  537.         for (int i = 0; i < observableInfo.observableParams.observablePositionsCount; i++)
  538.         {
  539.                 Vec3 directionToObservablePosition = (observableInfo.observableParams.observablePositions[i] - observerInfo.observerParams.eyePosition);
  540.                 directionToObservablePosition.NormalizeSafe();
  541.                 const float dot = directionToObservablePosition.Dot(observerInfo.observerParams.eyeDirection);
  542.                 if (observerInfo.observerParams.fovCos <= dot)
  543.                         return true;
  544.         }
  545.  
  546.         return false;
  547. }
  548.  
  549. bool CVisionMap::IsUserConditionSatisfied(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const
  550. {
  551.         if (!observerInfo.observerParams.userConditionCallback)
  552.                 return true;
  553.  
  554.         return observerInfo.observerParams.userConditionCallback(observerInfo.observerID, observerInfo.observerParams, observableInfo.observableID, observableInfo.observableParams);
  555. }
  556.  
  557. bool CVisionMap::ShouldObserve(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const
  558. {
  559.         const bool matchesType = ((observerInfo.observerParams.typesToObserveMask & observableInfo.observableParams.typeMask) != 0);
  560.         if (!matchesType)
  561.                 return false;
  562.  
  563.         const bool matchesFaction = ((observerInfo.observerParams.factionsToObserveMask & (1 << observableInfo.observableParams.faction)) != 0);
  564.         if (!matchesFaction)
  565.                 return false;
  566.  
  567.         const bool observingMyself = (observerInfo.observerParams.entityId == observableInfo.observableParams.entityId);
  568.         if (observingMyself)
  569.                 return false;
  570.  
  571.         if (!IsInSightRange(observerInfo, observableInfo))
  572.                 return false;
  573.  
  574.         if (!IsInFoV(observerInfo, observableInfo))
  575.                 return false;
  576.  
  577.         if (!IsUserConditionSatisfied(observerInfo, observableInfo))
  578.                 return false;
  579.  
  580.         return true;
  581. }
  582.  
  583. RayCastRequest::Priority CVisionMap::GetRayCastRequestPriority(const ObserverParams& observerParams, const ObservableParams& observableParams)
  584. {
  585.         RayCastRequest::Priority priority = RayCastRequest::MediumPriority;
  586.  
  587.         uint32 fromTypeMask = observerParams.typeMask;
  588.         uint32 toTypeMask = observableParams.typeMask;
  589.         uint8 fromFaction = observerParams.faction;
  590.         uint8 toFaction = observableParams.faction;
  591.  
  592.         for (std::vector<PriorityMapEntry>::iterator it = m_priorityMap.begin(), itEnd = m_priorityMap.end(); it != itEnd; ++it)
  593.         {
  594.                 const PriorityMapEntry& priorityMapEntry = *it;
  595.  
  596.                 if ((priorityMapEntry.fromTypeMask & fromTypeMask) &&
  597.                     (priorityMapEntry.fromFactionMask & (1 << fromFaction)) &&
  598.                     (priorityMapEntry.toTypeMask & toTypeMask) &&
  599.                     (priorityMapEntry.toFactionMask & (1 << toFaction)))
  600.                 {
  601.                         switch (priorityMapEntry.priority)
  602.                         {
  603.                         case eLowPriority:
  604.                                 priority = RayCastRequest::LowPriority;
  605.                                 break;
  606.  
  607.                         case eMediumPriority:
  608.                                 priority = RayCastRequest::MediumPriority;
  609.                                 break;
  610.  
  611.                         case eHighPriority:
  612.                                 priority = RayCastRequest::HighPriority;
  613.                                 break;
  614.  
  615.                         case eVeryHighPriority:
  616.                                 priority = RayCastRequest::HighestPriority;
  617.                                 break;
  618.  
  619.                         default:
  620.                                 CRY_ASSERT("bad priority specified in vision map priority table");
  621.                                 break;
  622.                         }
  623.                         break;
  624.                 }
  625.         }
  626.  
  627.         return priority;
  628. }
  629.  
  630. void CVisionMap::AddToObserverPVS(ObserverInfo& observerInfo, const ObservableInfo& observableInfo)
  631. {
  632.         observerInfo.needsVisibilityUpdate = true;
  633.         const RayCastRequest::Priority priority = GetRayCastRequestPriority(observerInfo.observerParams, observableInfo.observableParams);
  634.         std::pair<PVS::iterator, bool> result = observerInfo.pvs.insert(PVS::value_type(observableInfo.observableID, PVSEntry(observableInfo, priority)));
  635.         assert(result.second);
  636. }
  637.  
  638. void CVisionMap::UpdatePVS(ObserverInfo& observerInfo)
  639. {
  640.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  641.  
  642. #if VISIONMAP_DEBUG
  643.         ++m_numberOfPVSUpdatesThisFrame;
  644. #endif
  645.  
  646.         PVS& pvs = observerInfo.pvs;
  647.  
  648.         // Step1:
  649.         // - Make sure everything in the PVS is in supposed to be there
  650.         // - Delete what it's not
  651.         {
  652.                 FRAME_PROFILER("UpdatePVS_Step1", GetISystem(), PROFILE_AI);
  653.  
  654.                 for (PVS::iterator pvsIt = pvs.begin(), end = pvs.end(); pvsIt != end; )
  655.                 {
  656.                         const ObservableID& observableID = pvsIt->first;
  657.                         const ObservableInfo& observableInfo = pvsIt->second.observableInfo;
  658.  
  659.                         if (!ShouldObserve(observerInfo, observableInfo))
  660.                         {
  661.                                 PVSEntry& pvsEntry = pvsIt->second;
  662.                                 PVS::iterator nextIt = pvsIt;
  663.                                 ++nextIt;
  664.  
  665.                                 if (pvsEntry.visible)
  666.                                 {
  667.                                         TriggerObserverCallback(observerInfo, observableInfo, false);
  668.                                         TriggerObservableCallback(observerInfo, observableInfo, false);
  669.                                 }
  670.  
  671.                                 DeletePendingRay(pvsEntry);
  672.  
  673.                                 pvs.erase(pvsIt);
  674.                                 pvsIt = nextIt;
  675.  
  676.                                 continue;
  677.                         }
  678.  
  679.                         ++pvsIt;
  680.                 }
  681.         }
  682.  
  683.         // Step2:
  684.         // - Go through all objects in range
  685.         // - If object is already in the PVS skip it
  686.         // - Otherwise check if it should be added and add it
  687.         {
  688.                 FRAME_PROFILER("UpdatePVS_Step2", GetISystem(), PROFILE_AI);
  689.  
  690.                 if (observerInfo.observerParams.sightRange > 0.0f)
  691.                 {
  692.                         // the sight range is defined query the obsevableGrid
  693.                         m_queryObservables.clear();
  694.                         uint32 observableCount = m_observablesGrid.query_sphere_distance(observerInfo.observerParams.eyePosition, observerInfo.observerParams.sightRange, m_queryObservables);
  695.  
  696.                         for (QueryObservables::iterator it = m_queryObservables.begin(), end = m_queryObservables.end(); it != end; ++it)
  697.                         {
  698.                                 const ObservableInfo& observableInfo = *it->second;
  699.                                 if (ShouldBeAddedToObserverPVS(observerInfo, observableInfo))
  700.                                         AddToObserverPVS(observerInfo, observableInfo);
  701.                         }
  702.                 }
  703.                 else
  704.                 {
  705.                         // the sight range is unlimited check all observables
  706.                         for (Observables::iterator it = m_observables.begin(), end = m_observables.end(); it != end; ++it)
  707.                         {
  708.                                 ObservableInfo& observableInfo = it->second;
  709.                                 if (ShouldBeAddedToObserverPVS(observerInfo, observableInfo))
  710.                                         AddToObserverPVS(observerInfo, observableInfo);
  711.                         }
  712.                 }
  713.         }
  714. }
  715.  
  716. bool CVisionMap::ShouldBeAddedToObserverPVS(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo) const
  717. {
  718.         if (observableInfo.observableID == observerInfo.observerID)
  719.                 return false;
  720.  
  721.         PVS::const_iterator pvsIt = observerInfo.pvs.find(observableInfo.observableID);
  722.         if (pvsIt != observerInfo.pvs.end())
  723.                 return false;
  724.  
  725.         return ShouldObserve(observerInfo, observableInfo);
  726. }
  727.  
  728. void CVisionMap::QueueRay(const ObserverInfo& observerInfo, PVSEntry& pvsEntry)
  729. {
  730.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  731.  
  732.         assert(!pvsEntry.pendingRayID);
  733.  
  734.         const QueuedRayID queuedRayID = gAIEnv.pRayCaster->Queue(
  735.           pvsEntry.priority,
  736.           functor(*this, &CVisionMap::RayCastComplete),
  737.           functor(*this, &CVisionMap::RayCastSubmit));
  738.         assert(queuedRayID);
  739.  
  740.         std::pair<PendingRays::iterator, bool> result = m_pendingRays.insert(
  741.           PendingRays::value_type(queuedRayID, PendingRayInfo(observerInfo, pvsEntry)));
  742.         assert(result.second);
  743.  
  744. #if VISIONMAP_DEBUG
  745.         if (queuedRayID)
  746.         {
  747.                 m_pendingRayCounts[pvsEntry.priority]++;
  748.                 pvsEntry.rayQueueTimestamp = m_debugTimer;
  749.         }
  750. #endif
  751.  
  752.         pvsEntry.pendingRayID = queuedRayID;
  753. }
  754.  
  755. void CVisionMap::DeletePendingRay(PVSEntry& pvsEntry)
  756. {
  757.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  758.  
  759.         if (!pvsEntry.pendingRayID)
  760.                 return;
  761.  
  762.         gAIEnv.pRayCaster->Cancel(pvsEntry.pendingRayID);
  763.         m_pendingRays.erase(pvsEntry.pendingRayID);
  764.         pvsEntry.pendingRayID = 0;
  765.  
  766. #if VISIONMAP_DEBUG
  767.         m_pendingRayCounts[pvsEntry.priority]--;
  768. #endif
  769. }
  770.  
  771. void CVisionMap::DeletePendingRays(PVS& pvs)
  772. {
  773.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  774.  
  775.         for (PVS::iterator pvsIt = pvs.begin(), end = pvs.end(); pvsIt != end; ++pvsIt)
  776.         {
  777.                 PVSEntry& pvsEntry = pvsIt->second;
  778.                 DeletePendingRay(pvsEntry);
  779.         }
  780. }
  781.  
  782. bool CVisionMap::RayCastSubmit(const QueuedRayID& queuedRayID, RayCastRequest& rayCastRequest)
  783. {
  784.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  785.  
  786.         PendingRays::iterator pendingRayIt = m_pendingRays.find(queuedRayID);
  787.  
  788.         assert(pendingRayIt != m_pendingRays.end());
  789.         if (pendingRayIt == m_pendingRays.end())
  790.                 return false;
  791.  
  792.         PendingRayInfo& pendingRayInfo = pendingRayIt->second;
  793.  
  794.         const ObserverParams& observerParams = pendingRayInfo.observerInfo.observerParams;
  795.         const ObservableParams& observableParams = pendingRayInfo.pvsEntry.observableInfo.observableParams;
  796.  
  797.         const Vec3& observerPosition = observerParams.eyePosition;
  798.         const Vec3& observablePosition = observableParams.observablePositions[pendingRayInfo.pvsEntry.currentTestPositionIndex];
  799.  
  800. #if VISIONMAP_DEBUG
  801.         pendingRayInfo.observerPosition = observerPosition;
  802.         pendingRayInfo.observablePosition = observablePosition;
  803. #endif
  804.  
  805.         rayCastRequest.pos = observerPosition;
  806.         rayCastRequest.dir = observablePosition - observerPosition;
  807.         rayCastRequest.objTypes = COVER_OBJECT_TYPES;
  808.         rayCastRequest.flags = observerParams.raycastFlags;
  809.         rayCastRequest.maxHitCount = 2;
  810.  
  811.         size_t skipListCount = observerParams.skipListSize + observableParams.skipListSize;
  812.         assert(rayCastRequest.skipListCount <= RayCastRequest::MaxSkipListCount);
  813.  
  814.         skipListCount = std::min<size_t>(skipListCount, RayCastRequest::MaxSkipListCount);
  815.         rayCastRequest.skipListCount = static_cast<uint8>(skipListCount);
  816.  
  817.         size_t observerSkipListCount = std::min<size_t>(observerParams.skipListSize, RayCastRequest::MaxSkipListCount);
  818.         memcpy(rayCastRequest.skipList, observerParams.skipList, observerSkipListCount * sizeof(IPhysicalEntity*));
  819.  
  820.         size_t observableSkipListCount =
  821.           std::min<size_t>(observableParams.skipListSize, RayCastRequest::MaxSkipListCount - observerSkipListCount);
  822.         memcpy(rayCastRequest.skipList + observerSkipListCount, observableParams.skipList, observableSkipListCount * sizeof(IPhysicalEntity*));
  823.  
  824. #if VISIONMAP_DEBUG
  825.         m_numberOfRayCastsSubmittedThisFrame++;
  826.  
  827.         float latency = m_debugTimer - pendingRayInfo.pvsEntry.rayQueueTimestamp;
  828.         LatencyInfo* latencyInfo = &m_latencyInfo[pendingRayInfo.pvsEntry.priority];
  829.         latencyInfo->buffer[latencyInfo->bufferIndex].latency = latency;
  830.         latencyInfo->buffer[latencyInfo->bufferIndex].occurred = m_debugTimer;
  831.         latencyInfo->bufferIndex = (latencyInfo->bufferIndex + 1) % CRY_ARRAY_COUNT(latencyInfo->buffer);
  832.         latencyInfo->usedBufferSize = MAX(latencyInfo->usedBufferSize, latencyInfo->bufferIndex);
  833. #endif
  834.  
  835.         return true;
  836. }
  837.  
  838. void CVisionMap::RayCastComplete(const QueuedRayID& queuedRayID, const RayCastResult& rayCastResult)
  839. {
  840.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  841.  
  842.         PendingRays::iterator pendingRayIt = m_pendingRays.find(queuedRayID);
  843.  
  844.         assert(pendingRayIt != m_pendingRays.end());
  845.         if (pendingRayIt == m_pendingRays.end())
  846.                 return;
  847.  
  848.         PendingRayInfo& pendingRayInfo = pendingRayIt->second;
  849.         PVSEntry& pvsEntry = pendingRayInfo.pvsEntry;
  850.  
  851.         pvsEntry.pendingRayID = 0;
  852.  
  853. #if VISIONMAP_DEBUG
  854.         m_pendingRayCounts[pvsEntry.priority]--;
  855. #endif
  856.  
  857.         bool visible = !rayCastResult;
  858.  
  859. #if VISIONMAP_DEBUG
  860.         pvsEntry.lastObserverPositionChecked = pendingRayInfo.observerPosition;
  861.         pvsEntry.lastObservablePositionChecked = pendingRayInfo.observablePosition;
  862. #endif
  863.  
  864.         const ObserverInfo& observerInfo = pendingRayInfo.observerInfo;
  865.         const ObservableInfo& observableInfo = pvsEntry.observableInfo;
  866.  
  867.         if (!visible)
  868.         {
  869. #if VISIONMAP_DEBUG
  870.                 pvsEntry.obstructionPosition = rayCastResult->pt;
  871. #endif
  872.  
  873.                 if (++pvsEntry.currentTestPositionIndex < observableInfo.observableParams.observablePositionsCount)
  874.                 {
  875.                         m_pendingRays.erase(pendingRayIt);
  876.                         QueueRay(observerInfo, pvsEntry);
  877.                         return;
  878.                 }
  879.         }
  880.  
  881.         pvsEntry.currentTestPositionIndex = 0;
  882.         if (pvsEntry.visible != visible)
  883.         {
  884.                 pvsEntry.visible = visible;
  885.  
  886.                 TriggerObserverCallback(observerInfo, observableInfo, visible);
  887.                 TriggerObservableCallback(observerInfo, observableInfo, visible);
  888.  
  889.                 // find the pending ray again in case it was removed by the callback
  890.                 PendingRays::iterator pendingRaysToBeErasedIt = m_pendingRays.find(queuedRayID);
  891.                 if (pendingRaysToBeErasedIt != m_pendingRays.end())
  892.                         m_pendingRays.erase(pendingRaysToBeErasedIt);
  893.         }
  894.         else
  895.         {
  896.                 m_pendingRays.erase(pendingRayIt);
  897.         }
  898. }
  899.  
  900. void CVisionMap::AcquireSkipList(IPhysicalEntity** skipList, uint32 skipListSize)
  901. {
  902.         for (uint32 i = 0; i < skipListSize; ++i)
  903.                 skipList[i]->AddRef();
  904. }
  905.  
  906. void CVisionMap::ReleaseSkipList(IPhysicalEntity** skipList, uint32 skipListSize)
  907. {
  908.         for (uint32 i = 0; i < skipListSize; ++i)
  909.                 skipList[i]->Release();
  910. }
  911.  
  912. void CVisionMap::AddPriorityMapEntry(const PriorityMapEntry& priorityMapEntry)
  913. {
  914.         m_priorityMap.push_back(priorityMapEntry);
  915. }
  916.  
  917. void CVisionMap::ClearPriorityMap()
  918. {
  919.         m_priorityMap.clear();
  920. }
  921.  
  922. void CVisionMap::UpdateVisibilityStatus(ObserverInfo& observerInfo)
  923. {
  924. #if VISIONMAP_DEBUG
  925.         ++m_numberOfVisibilityUpdatesThisFrame;
  926. #endif
  927.  
  928.         for (PVS::iterator pvsIt = observerInfo.pvs.begin(), end = observerInfo.pvs.end(); pvsIt != end; ++pvsIt)
  929.         {
  930.                 PVSEntry& pvsEntry = pvsIt->second;
  931.  
  932.                 if (observerInfo.updateAllVisibilityStatus || pvsEntry.needsUpdate)
  933.                 {
  934.                         pvsEntry.needsUpdate = false;
  935.  
  936.                         if (pvsEntry.pendingRayID != 0)
  937.                                 DeletePendingRay(pvsEntry);
  938.  
  939.                         QueueRay(observerInfo, pvsEntry);
  940.                 }
  941.         }
  942.  
  943.         observerInfo.updateAllVisibilityStatus = false;
  944. }
  945.  
  946. void CVisionMap::UpdateObservers()
  947. {
  948.         CTimeValue now = gEnv->pTimer->GetFrameStartTime();
  949.  
  950.         // Update PVS ////////////////////////////////////////////////////////////
  951.  
  952.         for (Observers::iterator it = m_observers.begin(), end = m_observers.end(); it != end; ++it)
  953.         {
  954.                 ObserverInfo& observerInfo = it->second;
  955.  
  956.                 assert(observerInfo.observerParams.eyePosition.IsValid());
  957.  
  958.                 if (observerInfo.needsPVSUpdate && !observerInfo.queuedForPVSUpdate && now > observerInfo.nextPVSUpdateTime)
  959.                 {
  960.                         m_observerPVSUpdateQueue.push_back(observerInfo.observerID);
  961.                         observerInfo.queuedForPVSUpdate = true;
  962.  
  963. #if VISIONMAP_DEBUG
  964.                         observerInfo.queuedForPVSUpdateTime = now;
  965. #endif
  966.                 }
  967.         }
  968.  
  969.         int numberOfPVSUpdatesLeft = gAIEnv.CVars.VisionMapNumberOfPVSUpdatesPerFrame;
  970.         while (numberOfPVSUpdatesLeft > 0 && m_observerPVSUpdateQueue.size() > 0)
  971.         {
  972.                 Observers::iterator observerIt = m_observers.find(m_observerPVSUpdateQueue.front());
  973.                 ObserverInfo& observerInfo = observerIt->second;
  974.  
  975.                 UpdatePVS(observerInfo);
  976.                 observerInfo.needsPVSUpdate = false;
  977.  
  978.                 m_observerPVSUpdateQueue.pop_front();
  979.                 observerInfo.queuedForPVSUpdate = false;
  980.  
  981.                 numberOfPVSUpdatesLeft--;
  982.  
  983. #if VISIONMAP_DEBUG
  984.                 m_pvsUpdateQueueLatency = now - observerInfo.queuedForPVSUpdateTime;
  985. #endif
  986.         }
  987.  
  988.         // Update Visibility /////////////////////////////////////////////////////
  989.         for (Observers::iterator it = m_observers.begin(), end = m_observers.end(); it != end; ++it)
  990.         {
  991.                 ObserverInfo& observerInfo = it->second;
  992.  
  993.                 if (observerInfo.needsVisibilityUpdate && !observerInfo.queuedForVisibilityUpdate && now > observerInfo.nextVisibilityUpdateTime)
  994.                 {
  995.                         m_observerVisibilityUpdateQueue.push_back(observerInfo.observerID);
  996.                         observerInfo.queuedForVisibilityUpdate = true;
  997.  
  998. #if VISIONMAP_DEBUG
  999.                         observerInfo.queuedForVisibilityUpdateTime = now;
  1000. #endif
  1001.                 }
  1002.         }
  1003.  
  1004.         int numberOfVisibilityUpdatesLeft = gAIEnv.CVars.VisionMapNumberOfVisibilityUpdatesPerFrame;
  1005.         while (numberOfVisibilityUpdatesLeft > 0 && m_observerVisibilityUpdateQueue.size() > 0)
  1006.         {
  1007.                 Observers::iterator observerIt = m_observers.find(m_observerVisibilityUpdateQueue.front());
  1008.                 ObserverInfo& observerInfo = observerIt->second;
  1009.  
  1010.                 UpdateVisibilityStatus(observerInfo);
  1011.                 observerInfo.nextVisibilityUpdateTime = now + observerInfo.observerParams.updatePeriod;
  1012.                 observerInfo.needsVisibilityUpdate = false;
  1013.  
  1014.                 m_observerVisibilityUpdateQueue.pop_front();
  1015.                 observerInfo.queuedForVisibilityUpdate = false;
  1016.  
  1017.                 numberOfVisibilityUpdatesLeft--;
  1018.  
  1019. #if VISIONMAP_DEBUG
  1020.                 m_visibilityUpdateQueueLatency = now - observerInfo.queuedForVisibilityUpdateTime;
  1021. #endif
  1022.         }
  1023. }
  1024.  
  1025. void CVisionMap::TriggerObserverCallback(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo, bool visible)
  1026. {
  1027.         if (observerInfo.observerParams.callback)
  1028.                 observerInfo.observerParams.callback(observerInfo.observerID, observerInfo.observerParams, observableInfo.observableID, observableInfo.observableParams, visible);
  1029. }
  1030.  
  1031. void CVisionMap::TriggerObservableCallback(const ObserverInfo& observerInfo, const ObservableInfo& observableInfo, bool visible)
  1032. {
  1033.         if (observableInfo.observableParams.callback)
  1034.                 observableInfo.observableParams.callback(observerInfo.observerID, observerInfo.observerParams, observableInfo.observableID, observableInfo.observableParams, visible);
  1035. }
  1036.  
  1037. #if VISIONMAP_DEBUG
  1038.  
  1039. void CVisionMap::DebugDraw()
  1040. {
  1041.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  1042.  
  1043.         if (gAIEnv.CVars.DebugDrawVisionMap)
  1044.         {
  1045.                 UpdateDebugVisionMapObjects();
  1046.  
  1047.                 DebugDrawObservers();
  1048.  
  1049.                 if (gAIEnv.CVars.DebugDrawVisionMapObservables)
  1050.                         DebugDrawObservables();
  1051.  
  1052.                 if (gAIEnv.CVars.DebugDrawVisionMapStats)
  1053.                         DebugDrawVisionMapStats();
  1054.         }
  1055. }
  1056.  
  1057. void CVisionMap::DebugDrawVisionMapStats()
  1058. {
  1059.         struct DisplayInfo
  1060.         {
  1061.                 float avg;
  1062.                 float min;
  1063.                 float max;
  1064.                 int   count;
  1065.         };
  1066.  
  1067.         DisplayInfo displayInfoArray[CRY_ARRAY_COUNT(m_latencyInfo)];
  1068.         float cutOffTime = m_debugTimer - 10.0f;
  1069.  
  1070.         for (int i = 0; i < CRY_ARRAY_COUNT(m_latencyInfo); i++)
  1071.         {
  1072.                 DisplayInfo* displayInfo = &displayInfoArray[i];
  1073.                 LatencyInfo* latencyInfo = &m_latencyInfo[i];
  1074.                 int count = 0;
  1075.                 displayInfo->min = FLT_MAX;
  1076.                 displayInfo->max = 0.0f;
  1077.                 displayInfo->avg = 0.0f;
  1078.  
  1079.                 for (int j = 0; j < latencyInfo->usedBufferSize; j++)
  1080.                 {
  1081.                         if (latencyInfo->buffer[j].occurred >= cutOffTime)
  1082.                         {
  1083.                                 displayInfo->min = MIN(latencyInfo->buffer[j].latency, displayInfo->min);
  1084.                                 displayInfo->max = MAX(latencyInfo->buffer[j].latency, displayInfo->max);
  1085.                                 displayInfo->avg += latencyInfo->buffer[j].latency;
  1086.                                 count++;
  1087.                         }
  1088.                 }
  1089.  
  1090.                 if (count)
  1091.                 {
  1092.                         displayInfo->avg /= count;
  1093.                 }
  1094.                 else
  1095.                 {
  1096.                         displayInfo->min = 0.0f;
  1097.                 }
  1098.  
  1099.                 displayInfo->count = count;
  1100.         }
  1101.  
  1102.         int numObservers = m_observers.size();
  1103.         int numObservables = m_observables.size();
  1104.  
  1105.         CDebugDrawContext dc;
  1106.  
  1107.         int totalPending =
  1108.           m_pendingRayCounts[RayCastRequest::LowPriority] +
  1109.           m_pendingRayCounts[RayCastRequest::MediumPriority] +
  1110.           m_pendingRayCounts[RayCastRequest::HighPriority] +
  1111.           m_pendingRayCounts[RayCastRequest::HighestPriority];
  1112.  
  1113.         const float fontSize = 1.5f;
  1114.         const float x = dc->GetWidth() * 0.5f;
  1115.         float y = dc->GetHeight() * 0.25f;
  1116.  
  1117.         stack_string text;
  1118.         text.Format(
  1119.           "# Observers: %d\n"
  1120.           "# Observables: %d\n\n"
  1121.           "# PVS updates: %u\n"
  1122.           "# PVS queue size: %" PRISIZE_T "\n"
  1123.                                           "# PVS queue latency : %.2f\n\n"
  1124.                                           "# Visibility updates: %u\n"
  1125.                                           "# Visibility queue size: %" PRISIZE_T "\n"
  1126.                                                                                  "# Visibility queue latency : %.2f\n\n"
  1127.                                                                                  "# Raycast submits: %u\n"
  1128.                                                                                  "# Pending raycast: %d\n\n"
  1129.                                                                                  "Raycast latency:\n"
  1130.                                                                                  "Priority  | avg  | min  | max  | # pending\n"
  1131.                                                                                  "Low       | %.2f | %.2f | %.2f | %d\n"
  1132.                                                                                  "Medium    | %.2f | %.2f | %.2f | %d\n"
  1133.                                                                                  "High      | %.2f | %.2f | %.2f | %d\n"
  1134.                                                                                  "Very High | %.2f | %.2f | %.2f | %d\n",
  1135.           numObservers,
  1136.           numObservables,
  1137.           m_numberOfPVSUpdatesThisFrame,
  1138.           m_observerPVSUpdateQueue.size(),
  1139.           m_pvsUpdateQueueLatency.GetSeconds(),
  1140.           m_numberOfVisibilityUpdatesThisFrame,
  1141.           m_observerVisibilityUpdateQueue.size(),
  1142.           m_visibilityUpdateQueueLatency.GetSeconds(),
  1143.           m_numberOfRayCastsSubmittedThisFrame,
  1144.           totalPending,
  1145.           displayInfoArray[RayCastRequest::LowPriority].avg,
  1146.           displayInfoArray[RayCastRequest::LowPriority].min,
  1147.           displayInfoArray[RayCastRequest::LowPriority].max,
  1148.           m_pendingRayCounts[RayCastRequest::LowPriority],
  1149.           displayInfoArray[RayCastRequest::MediumPriority].avg,
  1150.           displayInfoArray[RayCastRequest::MediumPriority].min,
  1151.           displayInfoArray[RayCastRequest::MediumPriority].max,
  1152.           m_pendingRayCounts[RayCastRequest::MediumPriority],
  1153.           displayInfoArray[RayCastRequest::HighPriority].avg,
  1154.           displayInfoArray[RayCastRequest::HighPriority].min,
  1155.           displayInfoArray[RayCastRequest::HighPriority].max,
  1156.           m_pendingRayCounts[RayCastRequest::HighPriority],
  1157.           displayInfoArray[RayCastRequest::HighestPriority].avg,
  1158.           displayInfoArray[RayCastRequest::HighestPriority].min,
  1159.           displayInfoArray[RayCastRequest::HighestPriority].max,
  1160.           m_pendingRayCounts[RayCastRequest::HighestPriority]);
  1161.  
  1162.         dc->Draw2dLabel(x, y, fontSize, Col_White, false, "%s", text.c_str());
  1163. }
  1164.  
  1165. void CVisionMap::UpdateDebugVisionMapObjects()
  1166. {
  1167.         {
  1168.                 CAIObject* debugObserverAIObject = gAIEnv.pAIObjectManager->GetAIObjectByName("VisionMapObserver");
  1169.                 if (debugObserverAIObject)
  1170.                 {
  1171.                         ObserverParams observerParams;
  1172.                         observerParams.eyePosition = debugObserverAIObject->GetPos();
  1173.                         observerParams.eyeDirection = debugObserverAIObject->GetEntityDir();
  1174.  
  1175.                         if (!m_debugObserverVisionID)
  1176.                         {
  1177.                                 m_debugObserverVisionID = CreateVisionID("DebugObserver");
  1178.                                 observerParams.factionsToObserveMask = 0xffffffff;
  1179.                                 observerParams.typesToObserveMask = 0xffffffff;
  1180.                                 observerParams.typeMask = 0xffffffff;
  1181.                                 observerParams.faction = 0xff;
  1182.                                 observerParams.fovCos = 0.5f;
  1183.                                 observerParams.sightRange = 25.0f;
  1184.                                 RegisterObserver(m_debugObserverVisionID, observerParams);
  1185.                         }
  1186.  
  1187.                         ObserverChanged(m_debugObserverVisionID, observerParams, eChangedPosition | eChangedOrientation);
  1188.                 }
  1189.                 else if (m_debugObserverVisionID)
  1190.                 {
  1191.                         UnregisterObserver(m_debugObserverVisionID);
  1192.                         m_debugObserverVisionID = VisionID();
  1193.                 }
  1194.         }
  1195.  
  1196.         {
  1197.                 CAIObject* debugObservableAIObject = gAIEnv.pAIObjectManager->GetAIObjectByName("VisionMapObservable");
  1198.                 if (debugObservableAIObject)
  1199.                 {
  1200.                         ObservableParams observableParams;
  1201.                         observableParams.observablePositionsCount = 1;
  1202.                         observableParams.observablePositions[0] = debugObservableAIObject->GetPos();
  1203.  
  1204.                         if (!m_debugObservableVisionID)
  1205.                         {
  1206.                                 m_debugObservableVisionID = CreateVisionID("DebugObservable");
  1207.                                 observableParams.typeMask = 0xffffffff;
  1208.                                 observableParams.faction = 0xff;
  1209.                                 RegisterObservable(m_debugObservableVisionID, observableParams);
  1210.                         }
  1211.  
  1212.                         ObservableChanged(m_debugObservableVisionID, observableParams, eChangedPosition);
  1213.                 }
  1214.                 else if (m_debugObservableVisionID)
  1215.                 {
  1216.                         UnregisterObservable(m_debugObservableVisionID);
  1217.                         m_debugObservableVisionID = VisionID();
  1218.                 }
  1219.         }
  1220. }
  1221.  
  1222. void CVisionMap::DebugDrawObservers()
  1223. {
  1224.         CDebugDrawContext dc;
  1225.         dc->SetAlphaBlended(true);
  1226.         dc->SetBackFaceCulling(false);
  1227.         dc->SetDepthWrite(false);
  1228.  
  1229.         ColorF observersColor = ColorF(0.0f, 0.749f, 1.0f);
  1230.  
  1231.         for (Observers::iterator observerIt = m_observers.begin(), observerEndIt = m_observers.end(); observerIt != observerEndIt; ++observerIt)
  1232.         {
  1233.                 const ObserverInfo& observerInfo = observerIt->second;
  1234.  
  1235.                 const Vec3& currentObserverPosition = observerInfo.observerParams.eyePosition;
  1236.  
  1237.                 // Visibility Checks ///////////////////////////////////////////////////
  1238.  
  1239.                 if (gAIEnv.CVars.DebugDrawVisionMapVisibilityChecks)
  1240.                 {
  1241.                         for (PVS::const_iterator pvsIt = observerInfo.pvs.begin(), end = observerInfo.pvs.end(); pvsIt != end; ++pvsIt)
  1242.                         {
  1243.                                 const PVSEntry& pvsEntry = pvsIt->second;
  1244.  
  1245.                                 Vec3 currentObservablePosition = pvsEntry.observableInfo.observableParams.observablePositions[pvsEntry.currentTestPositionIndex];
  1246.                                 Vec3 lastObserverPositionChecked = pvsEntry.lastObserverPositionChecked;
  1247.                                 Vec3 lastObservablePositionChecked = pvsEntry.lastObservablePositionChecked;
  1248.  
  1249.                                 bool pvsEntryHasBeenChecked = (!lastObserverPositionChecked.IsZero() && !lastObservablePositionChecked.IsZero());
  1250.  
  1251.                                 // move player's observable pos down a bit, so that when in 1st person you can tell the AI is looking at you via the debug lines
  1252.                                 if (pvsEntry.observableInfo.observableParams.typeMask & Player)
  1253.                                 {
  1254.                                         static const float zOffset = -0.05f;
  1255.                                         currentObservablePosition.z += zOffset;
  1256.                                         lastObservablePositionChecked.z += zOffset;
  1257.                                 }
  1258.  
  1259.                                 dc->DrawLine(currentObserverPosition, Col_LightGray, currentObservablePosition, Col_LightGray);
  1260.  
  1261.                                 if (pvsEntryHasBeenChecked)
  1262.                                 {
  1263.                                         if (pvsEntry.visible)
  1264.                                         {
  1265.                                                 dc->DrawLine(lastObserverPositionChecked, Col_DarkGreen, lastObservablePositionChecked, Col_Green, 5.0f);
  1266.                                                 dc->DrawWireSphere(lastObservablePositionChecked, 0.05f, Col_Green);
  1267.                                         }
  1268.                                         else
  1269.                                         {
  1270.                                                 dc->DrawLine(lastObserverPositionChecked, Col_IndianRed, pvsEntry.obstructionPosition, Col_Red, 5.0f);
  1271.                                                 dc->DrawWireSphere(pvsEntry.obstructionPosition, 0.05f, Col_Red);
  1272.                                         }
  1273.                                 }
  1274.                         }
  1275.                 }
  1276.  
  1277.                 if (gAIEnv.CVars.DebugDrawVisionMapObservers)
  1278.                 {
  1279.                         // Stats /////////////////////////////////////////////////////////////////
  1280.                         {
  1281.                                 float x, y, z;
  1282.                                 if (dc->ProjectToScreen(currentObserverPosition.x, currentObserverPosition.y, currentObserverPosition.z + 0.45f, &x, &y, &z))
  1283.                                 {
  1284.                                         if ((z >= 0.0f) && (z <= 1.0f))
  1285.                                         {
  1286.                                                 int visibleCount = 0;
  1287.                                                 for (PVS::const_iterator pvsIt = observerInfo.pvs.begin(), end = observerInfo.pvs.end(); pvsIt != end; ++pvsIt)
  1288.                                                 {
  1289.                                                         const PVSEntry& pvsEntry = pvsIt->second;
  1290.                                                         if (pvsEntry.visible)
  1291.                                                                 ++visibleCount;
  1292.                                                 }
  1293.  
  1294.         #ifdef VISION_MAP_STORE_DEBUG_NAMES_FOR_VISION_ID
  1295.                                                 x *= dc->GetWidth() * 0.01f;
  1296.                                                 y *= dc->GetHeight() * 0.01f;
  1297.                                                 const float fontSize = 1.15f;
  1298.                                                 stack_string text;
  1299.                                                 text.Format("%s\nVisible: %d/%" PRISIZE_T "\n", observerInfo.observerID.m_debugName.c_str(), visibleCount, observerInfo.pvs.size());
  1300.  
  1301.                                                 dc->Draw2dLabel(x, y, fontSize, observersColor, true, "%s", text.c_str());
  1302.         #endif    // VISION_MAP_STORE_DEBUG_NAMES_FOR_VISION_ID
  1303.                                         }
  1304.                                 }
  1305.                         }
  1306.  
  1307.                         // Location //////////////////////////////////////////////////////////////
  1308.                         {
  1309.                                 dc->DrawWireSphere(currentObserverPosition, 0.15f, observersColor);
  1310.                         }
  1311.  
  1312.                         // FOVs //////////////////////////////////////////////////////////////////
  1313.                         if (gAIEnv.CVars.DebugDrawVisionMapObserversFOV)
  1314.                         {
  1315.                                 const ObserverParams& observerParams = observerInfo.observerParams;
  1316.  
  1317.                                 const Vec3& eyePosition = observerParams.eyePosition;
  1318.                                 Vec3 eyeDirection = observerParams.eyeDirection;
  1319.  
  1320.                                 if (eyeDirection.IsZero())
  1321.                                         continue;
  1322.  
  1323.                                 eyeDirection.NormalizeFast();
  1324.  
  1325.                                 dc->DrawLine(eyePosition, observersColor, eyePosition + eyeDirection * 2.5f, observersColor, 5.0f);
  1326.  
  1327.                                 const uint32 pointCount = 32;
  1328.  
  1329.                                 Vec3 points[pointCount];
  1330.                                 Vec3 triangles[(pointCount - 1) * 2 * 3];
  1331.  
  1332.                                 Vec3 y(eyeDirection.x, eyeDirection.y, eyeDirection.z);
  1333.                                 Vec3 x(y.Cross(Vec3Constants<float>::fVec3_OneZ).GetNormalized());
  1334.  
  1335.                                 float anglePrimary = acosf(observerParams.fovCos) * 2.0f;
  1336.  
  1337.                                 for (uint32 i = 0; i < pointCount; ++i)
  1338.                                 {
  1339.                                         float angle = ((float)i / (float)(pointCount - 1) - 0.5f) * anglePrimary;
  1340.                                         points[i] = y * cosf(angle) + x * sinf(angle);
  1341.                                 }
  1342.  
  1343.                                 float radius = observerParams.sightRange;
  1344.                                 float inner = 0.25f;
  1345.  
  1346.                                 uint32 triangleVertexCount = 0;
  1347.                                 for (uint32 i = 0; i < pointCount - 1; ++i)
  1348.                                 {
  1349.                                         triangles[triangleVertexCount++] = eyePosition + points[i] * inner;
  1350.                                         triangles[triangleVertexCount++] = eyePosition + points[i + 1] * radius;
  1351.                                         triangles[triangleVertexCount++] = eyePosition + points[i] * radius;
  1352.  
  1353.                                         triangles[triangleVertexCount++] = eyePosition + points[i] * inner;
  1354.                                         triangles[triangleVertexCount++] = eyePosition + points[i + 1] * inner;
  1355.                                         triangles[triangleVertexCount++] = eyePosition + points[i + 1] * radius;
  1356.                                 }
  1357.  
  1358.                                 dc->DrawTriangles(triangles, triangleVertexCount, ColorF(observersColor, 0.5f));
  1359.                         }
  1360.                 }
  1361.         }
  1362. }
  1363.  
  1364. void CVisionMap::DebugDrawObservables()
  1365. {
  1366.         CDebugDrawContext dc;
  1367.         dc->SetAlphaBlended(true);
  1368.         dc->SetBackFaceCulling(false);
  1369.  
  1370.         for (Observables::iterator it = m_observables.begin(), end = m_observables.end(); it != end; ++it)
  1371.         {
  1372.                 // Stats /////////////////////////////////////////////////////////////////
  1373.  
  1374.                 ObservableInfo& observableInfo = it->second;
  1375.  
  1376.                 const Vec3& firstObservablePosition = observableInfo.observableParams.observablePositions[0];
  1377.  
  1378.         #ifdef VISION_MAP_STORE_DEBUG_NAMES_FOR_VISION_ID
  1379.  
  1380.                 float x, y, z;
  1381.                 if (dc->ProjectToScreen(firstObservablePosition.x, firstObservablePosition.y, firstObservablePosition.z - 0.45f, &x, &y, &z))
  1382.                 {
  1383.                         if ((z >= 0.0f) && (z <= 1.0f))
  1384.                         {
  1385.                                 x *= dc->GetWidth() * 0.01f;
  1386.                                 y *= dc->GetHeight() * 0.01f;
  1387.                                 const float fontSize = 1.0f;
  1388.                                 stack_string text;
  1389.                                 text.Format("%s\n", observableInfo.observableID.m_debugName.c_str());
  1390.  
  1391.                                 dc->Draw2dLabel(x, y, fontSize, ColorF(0.8f, 0.498039f, 0.196078f), true, "%s", text.c_str());
  1392.                         }
  1393.                 }
  1394.  
  1395.         #endif // VISION_MAP_STORE_DEBUG_NAMES_FOR_VISION_ID
  1396.  
  1397.                 // Location //////////////////////////////////////////////////////////////
  1398.  
  1399.                 for (int i = 0; i < observableInfo.observableParams.observablePositionsCount; i++)
  1400.                 {
  1401.                         dc->DrawWireSphere(observableInfo.observableParams.observablePositions[i], 0.10f, ColorF(0.8f, 0.498039f, 0.196078f));
  1402.                 }
  1403.         }
  1404. }
  1405.  
  1406. #endif
  1407.  
downloadVisionMap.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