BVB Source Codes

CRYENGINE Show Free2DNavRegion.cpp Source code

Return Download CRYENGINE: download Free2DNavRegion.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "Free2DNavRegion.h"
  5. #include "CAISystem.h"
  6. #include "AILog.h"
  7.  
  8. //===================================================================
  9. // CFree2DNavRegion
  10. //===================================================================
  11. CFree2DNavRegion::CFree2DNavRegion(CGraph* pGraph)
  12. {
  13.         m_pDummyNode = 0;
  14.         m_dummyNodeIndex = 0;
  15. }
  16. //===================================================================
  17. // ~CFree2DNavRegion
  18. //===================================================================
  19. CFree2DNavRegion::~CFree2DNavRegion()
  20. {
  21. }
  22.  
  23. //===================================================================
  24. // BeautifyPath
  25. //===================================================================
  26. void CFree2DNavRegion::BeautifyPath(const VectorConstNodeIndices& inPath, TPathPoints& outPath,
  27.                                     const Vec3& startPos, const Vec3& startDir,
  28.                                     const Vec3& endPos, const Vec3& endDir,
  29.                                     float radius,
  30.                                     const AgentMovementAbility& movementAbility,
  31.                                     const NavigationBlockers& navigationBlockers)
  32. {
  33.         AIWarning("CFree2DNavRegion::BeautifyPath should never be called");
  34. }
  35.  
  36. //===================================================================
  37. // UglifyPath
  38. //===================================================================
  39. void CFree2DNavRegion::UglifyPath(const VectorConstNodeIndices& inPath, TPathPoints& outPath,
  40.                                   const Vec3& startPos, const Vec3& startDir,
  41.                                   const Vec3& endPos, const Vec3& endDir)
  42. {
  43.         AIWarning("CFree2DNavRegion::UglifyPath should never be called");
  44. }
  45.  
  46. //===================================================================
  47. // GetEnclosing
  48. //===================================================================
  49. unsigned CFree2DNavRegion::GetEnclosing(const Vec3& pos, float passRadius, unsigned startIndex,
  50.                                         float /*range*/, Vec3* closestValid, bool returnSuspect, const char* requesterName, bool omitWalkabilityTest)
  51. {
  52.         /*
  53.            const SpecialArea *sa = GetAISystem()->GetSpecialArea(pos, SpecialArea::TYPE_FREE_2D);
  54.            if (sa)
  55.             return 0;
  56.            int nBuildingID = sa->nBuildingID;
  57.            if (nBuildingID < 0)
  58.             return 0;
  59.          */
  60.         if (!m_pDummyNode)
  61.         {
  62.                 m_dummyNodeIndex = gAIEnv.pGraph->CreateNewNode(IAISystem::NAV_FREE_2D, ZERO);
  63.                 m_pDummyNode = gAIEnv.pGraph->GetNode(m_dummyNodeIndex);
  64.         }
  65.  
  66.         return m_dummyNodeIndex;
  67. }
  68.  
  69. //===================================================================
  70. // Clear
  71. //===================================================================
  72. void CFree2DNavRegion::Clear()
  73. {
  74.         if (m_pDummyNode)
  75.         {
  76.                 gAIEnv.pGraph->Disconnect(m_dummyNodeIndex);
  77.                 m_pDummyNode = 0;
  78.                 m_dummyNodeIndex = 0;
  79.         }
  80. }
  81.  
  82. //===================================================================
  83. // MemStats
  84. //===================================================================
  85. size_t CFree2DNavRegion::MemStats()
  86. {
  87.         size_t size = sizeof(*this);
  88.         return size;
  89. }
  90.  
  91. //===================================================================
  92. // CheckPassability
  93. //===================================================================
  94. bool CFree2DNavRegion::CheckPassability(const Vec3& from, const Vec3& to,
  95.                                         float radius, const NavigationBlockers& navigationBlockers, IAISystem::tNavCapMask) const
  96. {
  97.         const SpecialArea* sa = gAIEnv.pNavigation->GetSpecialArea(from, SpecialArea::TYPE_FREE_2D);
  98.         if (!sa)
  99.                 return false;
  100.         return !Overlap::Lineseg_Polygon2D(Lineseg(from, to), sa->GetPolygon(), &sa->GetAABB());
  101. }
  102.  
  103. //===================================================================
  104. // ExpandShape
  105. //===================================================================
  106. static void ShrinkShape(const ListPositions& shapeIn, ListPositions& shapeOut, float radius)
  107. {
  108.         // push the points in. The shape is guaranteed to be wound anti-clockwise
  109.         shapeOut.clear();
  110.         for (ListPositions::const_iterator it = shapeIn.begin(); it != shapeIn.end(); ++it)
  111.         {
  112.                 ListPositions::const_iterator itNext = it;
  113.                 if (++itNext == shapeIn.end())
  114.                         itNext = shapeIn.begin();
  115.                 ListPositions::const_iterator itNextNext = itNext;
  116.                 if (++itNextNext == shapeIn.end())
  117.                         itNextNext = shapeIn.begin();
  118.  
  119.                 Vec3 pos = *it;
  120.                 Vec3 posNext = *itNext;
  121.                 Vec3 posNextNext = *itNextNext;
  122.                 pos.z = posNext.z = posNextNext.z = 0.0f;
  123.  
  124.                 Vec3 segDirPrev = (posNext - pos).GetNormalizedSafe();
  125.                 Vec3 segDirNext = (posNextNext - posNext).GetNormalizedSafe();
  126.  
  127.                 Vec3 normalInPrev(-segDirPrev.y, segDirPrev.x, 0.0f);
  128.                 Vec3 normalInNext(-segDirNext.y, segDirNext.x, 0.0f);
  129.                 Vec3 normalAv = (normalInPrev + normalInNext).GetNormalizedSafe();
  130.  
  131.                 Vec3 cross = segDirPrev.Cross(segDirNext);
  132.                 // convex means the point is convex from the point of view of inside the shape
  133.                 bool convex = cross.z < 0.0f;
  134.  
  135.                 static float radiusScale = 0.5f;
  136.                 if (convex)
  137.                 {
  138.                         Vec3 newPtPrev = posNext + normalInPrev * (radius * radiusScale);
  139.                         newPtPrev.z = it->z;
  140.                         Vec3 newPtMid = posNext + normalAv * (radius * radiusScale);
  141.                         newPtMid.z = itNext->z;
  142.                         Vec3 newPtNext = posNext + normalInNext * (radius * radiusScale);
  143.                         newPtNext.z = itNextNext->z;
  144.                         shapeOut.push_back(newPtPrev);
  145.                         shapeOut.push_back(newPtMid);
  146.                         shapeOut.push_back(newPtNext);
  147.                 }
  148.                 else
  149.                 {
  150.                         float dot = segDirPrev.Dot(segDirNext);
  151.                         float extraRadiusScale = sqrtf(2.0f / (1.0f + dot));
  152.                         Vec3 newPtMid = posNext + normalAv * (radius * radiusScale * extraRadiusScale);
  153.                         newPtMid.z = itNext->z;
  154.                         shapeOut.push_back(newPtMid);
  155.                 }
  156.  
  157.         }
  158. }
  159.  
  160. //===================================================================
  161. // GetSingleNodePath
  162. // Danny todo This "works" but doesn't generate ideal paths because it hugs
  163. // a single wall - it can't cross over to hug the other wall. Should
  164. // be OK for most sensible areas though. Also there is a danger that
  165. // the path can get close to the area edge, but I don't know what can
  166. // be done to stop that. Also, the shape shrinking could/should
  167. // be precalculated.
  168. //===================================================================
  169. bool CFree2DNavRegion::GetSingleNodePath(const GraphNode* pNode,
  170.                                          const Vec3& startPos, const Vec3& endPos, float radius,
  171.                                          const NavigationBlockers& navigationBlockers,
  172.                                          std::vector<PathPointDescriptor>& points,
  173.                                          IAISystem::tNavCapMask) const
  174. {
  175.         const SpecialArea* sa = gAIEnv.pNavigation->GetSpecialAreaNearestPos(startPos, SpecialArea::TYPE_FREE_2D);
  176.         if (!sa)
  177.                 return false;
  178.  
  179.         const ListPositions& origShape = sa->GetPolygon();
  180.         ListPositions shape;
  181.         ShrinkShape(origShape, shape, radius);
  182.  
  183.         // simplest straight-line case
  184.         if (!Overlap::Lineseg_Polygon2D(Lineseg(startPos, endPos), shape))
  185.         {
  186.                 points.resize(0);
  187.                 points.push_back(PathPointDescriptor(IAISystem::NAV_FREE_2D, startPos));
  188.                 points.push_back(PathPointDescriptor(IAISystem::NAV_FREE_2D, endPos));
  189.                 return true;
  190.         }
  191.  
  192.         if (!Overlap::Point_Polygon2D(endPos, origShape, &sa->GetAABB()))
  193.                 return false;
  194.  
  195.         // So, now start and end are in the same area. make a "safe" path
  196.         // by going from startPos to the nearest vertex, then through all
  197.         // vertices to the vertex nearest to endPos, then to endPos. Subsequently
  198.         // we'll tidy this up by cutting vertices.
  199.  
  200.         ListPositions::const_iterator itStart, itEnd;
  201.         float bestDistStartSq = std::numeric_limits<float>::max();
  202.         float bestDistEndSq = std::numeric_limits<float>::max();
  203.         int countToStart = -1;
  204.         int countToEnd = -1;
  205.         int count = 0;
  206.         for (ListPositions::const_iterator it = shape.begin(); it != shape.end(); ++it, ++count)
  207.         {
  208.                 Vec3 itPos = *it;
  209.                 static float frac = 0.99f;
  210.                 bool reachableStart = !Overlap::Lineseg_Polygon2D(Lineseg(startPos, startPos + frac * (itPos - startPos)), origShape, &sa->GetAABB());
  211.                 bool reachableEnd = !Overlap::Lineseg_Polygon2D(Lineseg(endPos, endPos + frac * (itPos - endPos)), origShape, &sa->GetAABB());
  212.                 if (reachableStart)
  213.                 {
  214.                         float distToStartSq = Distance::Point_Point2DSq(startPos, itPos);
  215.                         if (distToStartSq < bestDistStartSq)
  216.                         {
  217.                                 bestDistStartSq = distToStartSq;
  218.                                 itStart = it;
  219.                                 countToStart = count;
  220.                         }
  221.                 }
  222.                 if (reachableEnd)
  223.                 {
  224.                         float distToEndSq = Distance::Point_Point2DSq(endPos, itPos);
  225.                         if (distToEndSq < bestDistEndSq)
  226.                         {
  227.                                 bestDistEndSq = distToEndSq;
  228.                                 itEnd = it;
  229.                                 countToEnd = count;
  230.                         }
  231.                 }
  232.         }
  233.  
  234.         if (countToStart < 0 || countToEnd < 0)
  235.         {
  236.                 AIWarning("CFree2DNavRegion::GetSingleNodePath failed from (%5.2f, %5.2f, %5.2f) to (%5.2f, %5.2f, %5.2f)",
  237.                           startPos.x, startPos.y, startPos.z, endPos.x, endPos.y, endPos.z);
  238.                 return false;
  239.         }
  240.  
  241.         // add the points
  242.         points.resize(0);
  243.         points.push_back(PathPointDescriptor(IAISystem::NAV_FREE_2D, startPos));
  244.         bool walkingFwd = true;
  245.         if (itStart == itEnd)
  246.         {
  247.                 points.push_back(PathPointDescriptor(IAISystem::NAV_FREE_2D, *itStart));
  248.         }
  249.         else
  250.         {
  251.                 // decide on the direction using the counts...
  252.                 int shapeCount = shape.size();
  253.                 int countFwd = (shapeCount + countToEnd - countToStart) % shapeCount;
  254.                 int countBwd = shapeCount - countFwd;
  255.                 walkingFwd = countFwd < countBwd;
  256.  
  257.                 ListPositions::const_iterator it = itStart;
  258.                 do
  259.                 {
  260.                         points.push_back(PathPointDescriptor(IAISystem::NAV_FREE_2D, *it));
  261.                         if (walkingFwd)
  262.                         {
  263.                                 ++it;
  264.                                 if (it == shape.end()) it = shape.begin();
  265.                         }
  266.                         else
  267.                         {
  268.                                 if (it == shape.begin()) it = shape.end();
  269.                                 --it;
  270.                         }
  271.                 }
  272.                 while (it != itEnd);
  273.                 points.push_back(PathPointDescriptor(IAISystem::NAV_FREE_2D, *itEnd));
  274.         }
  275.         points.push_back(PathPointDescriptor(IAISystem::NAV_FREE_2D, endPos));
  276.  
  277.         // now walk through iteratively cutting points
  278.         static bool doCutting = true;
  279.         bool cutOne = doCutting;
  280.         while (cutOne == true && points.size() > 2)
  281.         {
  282.                 cutOne = false;
  283.                 for (std::vector<PathPointDescriptor>::iterator it = points.begin(); it != points.end(); ++it)
  284.                 {
  285.                         std::vector<PathPointDescriptor>::iterator itNext = it;
  286.                         if (++itNext == points.end())
  287.                                 break;
  288.                         std::vector<PathPointDescriptor>::iterator itNextNext = itNext;
  289.                         if (++itNextNext == points.end())
  290.                                 break;
  291.  
  292.                         Vec3 pos = it->vPos;
  293.                         //      Vec3 posNext = itNext->vPos;
  294.                         Vec3 posNextNext = itNextNext->vPos;
  295.  
  296.                         static float frac = 0.001f;
  297.                         pos += frac * (posNextNext - pos);
  298.                         posNextNext += frac * (pos - posNextNext);
  299.  
  300.                         Lineseg seg(pos, posNextNext);
  301.                         Vec3 posMid = 0.5f * (pos + posNextNext);
  302.                         std::vector<PathPointDescriptor>::iterator itNextNextNext = itNextNext;
  303.                         ++itNextNextNext;
  304.                         bool doingEnd = it == points.begin() || itNextNextNext == points.end();
  305.                         const ListPositions& thisShape = doingEnd ? origShape : shape;
  306.                         if (Overlap::Point_Polygon2D(pos, thisShape) && !Overlap::Lineseg_Polygon2D(seg, thisShape))
  307.                         {
  308.                                 points.erase(itNext);
  309.                                 cutOne = true;
  310.                                 // iterator it is safe because itNext comes after it
  311.                                 it = points.begin();
  312.                         }
  313.                 }
  314.         }
  315.  
  316.         return true;
  317. }
  318.  
downloadFree2DNavRegion.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